enigmamachine 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -9,14 +9,15 @@ begin
9
9
  gem.description = %Q{A RESTful video encoder which you can use as either a front-end to ffmpeg or headless on a server.}
10
10
  gem.email = "dave@caprica"
11
11
  gem.homepage = "http://github.com/futurechimp/enigmamachine"
12
- gem.authors = ["Dave Hrycyszyn"]
12
+ gem.authors = ["Dave Hrycyszyn", "Dmitry Brazhkin"]
13
13
  gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
- gem.add_dependency "data_mapper", "=1.0.0"
15
- gem.add_dependency "eventmachine", "=0.12.10"
16
- gem.add_dependency "dm-sqlite-adapter", "=1.0.0"
14
+ gem.add_dependency "data_mapper", ">=1.0.2"
15
+ gem.add_dependency "dm-sqlite-adapter", ">=1.0.2"
16
+ gem.add_dependency "eventmachine", ">=0.12.10"
17
17
  gem.add_dependency "rack-flash"
18
18
  gem.add_dependency "ruby-debug"
19
- gem.add_dependency "sinatra", "=1.0.0"
19
+ gem.add_dependency "sinatra", ">=1.0.0"
20
+ gem.add_dependency "streamio-ffmpeg", ">=0.7.3"
20
21
  gem.add_dependency "thin"
21
22
 
22
23
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.5.0
data/bin/enigmamachine CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Enigmamachine command line interface script.
4
4
  # Run <tt>enigmamachine -h</tt> to get more usage.
5
- require File.dirname(__FILE__) + '/../lib/enigmamachine'
5
+ require 'rubygems'
6
6
  require 'thin'
7
7
 
8
8
  rackup_file = "#{File.dirname(__FILE__)}/../lib/enigmamachine/config.ru"
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{enigmamachine}
8
- s.version = "0.4.3"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Dave Hrycyszyn"]
12
- s.date = %q{2010-09-15}
11
+ s.authors = ["Dave Hrycyszyn", "Dmitry Brazhkin"]
12
+ s.date = %q{2010-10-04}
13
13
  s.default_executable = %q{enigmamachine}
14
14
  s.description = %q{A RESTful video encoder which you can use as either a front-end to ffmpeg or headless on a server.}
15
15
  s.email = %q{dave@caprica}
@@ -76,48 +76,51 @@ Gem::Specification.new do |s|
76
76
  s.homepage = %q{http://github.com/futurechimp/enigmamachine}
77
77
  s.rdoc_options = ["--charset=UTF-8"]
78
78
  s.require_paths = ["lib"]
79
- s.rubygems_version = %q{1.3.7}
79
+ s.rubygems_version = %q{1.3.6}
80
80
  s.summary = %q{A RESTful video encoder.}
81
81
  s.test_files = [
82
- "test/helper.rb",
83
- "test/test_enigmamachine.rb",
84
- "test/support/blueprints.rb",
82
+ "test/support/blueprints.rb",
83
+ "test/helper.rb",
85
84
  "test/test_encoding_queue.rb",
85
+ "test/test_video.rb",
86
86
  "test/test_encoder.rb",
87
- "test/test_video.rb"
87
+ "test/test_enigmamachine.rb"
88
88
  ]
89
89
 
90
90
  if s.respond_to? :specification_version then
91
91
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
92
92
  s.specification_version = 3
93
93
 
94
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
94
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
95
95
  s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
96
- s.add_runtime_dependency(%q<data_mapper>, ["= 1.0.0"])
97
- s.add_runtime_dependency(%q<eventmachine>, ["= 0.12.10"])
98
- s.add_runtime_dependency(%q<dm-sqlite-adapter>, ["= 1.0.0"])
96
+ s.add_runtime_dependency(%q<data_mapper>, [">= 1.0.2"])
97
+ s.add_runtime_dependency(%q<dm-sqlite-adapter>, [">= 1.0.2"])
98
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
99
99
  s.add_runtime_dependency(%q<rack-flash>, [">= 0"])
100
100
  s.add_runtime_dependency(%q<ruby-debug>, [">= 0"])
101
- s.add_runtime_dependency(%q<sinatra>, ["= 1.0.0"])
101
+ s.add_runtime_dependency(%q<sinatra>, [">= 1.0.0"])
102
+ s.add_runtime_dependency(%q<streamio-ffmpeg>, [">= 0.7.3"])
102
103
  s.add_runtime_dependency(%q<thin>, [">= 0"])
103
104
  else
104
105
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
105
- s.add_dependency(%q<data_mapper>, ["= 1.0.0"])
106
- s.add_dependency(%q<eventmachine>, ["= 0.12.10"])
107
- s.add_dependency(%q<dm-sqlite-adapter>, ["= 1.0.0"])
106
+ s.add_dependency(%q<data_mapper>, [">= 1.0.2"])
107
+ s.add_dependency(%q<dm-sqlite-adapter>, [">= 1.0.2"])
108
+ s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
108
109
  s.add_dependency(%q<rack-flash>, [">= 0"])
109
110
  s.add_dependency(%q<ruby-debug>, [">= 0"])
110
- s.add_dependency(%q<sinatra>, ["= 1.0.0"])
111
+ s.add_dependency(%q<sinatra>, [">= 1.0.0"])
112
+ s.add_dependency(%q<streamio-ffmpeg>, [">= 0.7.3"])
111
113
  s.add_dependency(%q<thin>, [">= 0"])
112
114
  end
113
115
  else
114
116
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
115
- s.add_dependency(%q<data_mapper>, ["= 1.0.0"])
116
- s.add_dependency(%q<eventmachine>, ["= 0.12.10"])
117
- s.add_dependency(%q<dm-sqlite-adapter>, ["= 1.0.0"])
117
+ s.add_dependency(%q<data_mapper>, [">= 1.0.2"])
118
+ s.add_dependency(%q<dm-sqlite-adapter>, [">= 1.0.2"])
119
+ s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
118
120
  s.add_dependency(%q<rack-flash>, [">= 0"])
119
121
  s.add_dependency(%q<ruby-debug>, [">= 0"])
120
- s.add_dependency(%q<sinatra>, ["= 1.0.0"])
122
+ s.add_dependency(%q<sinatra>, [">= 1.0.0"])
123
+ s.add_dependency(%q<streamio-ffmpeg>, [">= 0.7.3"])
121
124
  s.add_dependency(%q<thin>, [">= 0"])
122
125
  end
123
126
  end
data/lib/enigmamachine.rb CHANGED
@@ -10,6 +10,7 @@ require 'dm-validations'
10
10
  require 'dm-migrations'
11
11
  require 'open3'
12
12
  require 'logger'
13
+ require 'streamio-ffmpeg'
13
14
 
14
15
  # Extensions to Sinatra
15
16
  #
@@ -270,5 +271,13 @@ class EnigmaMachine < Sinatra::Base
270
271
  end
271
272
  end
272
273
 
274
+ # Deletes a video.
275
+ #
276
+ delete '/videos/:id' do |id|
277
+ @video = Video.get(id)
278
+ @video.destroy
279
+ redirect "/videos"
280
+ end
281
+
273
282
  end
274
283
 
@@ -6,6 +6,7 @@ class EncodingQueue
6
6
  # starts looking for unencoded videos.
7
7
  #
8
8
  def initialize
9
+ @threads = YAML.load_file(Dir.getwd + '/config.yml')['threads'] if @threads.nil?
9
10
  EM.add_periodic_timer(5) {
10
11
  encode_next_video
11
12
  }
@@ -15,7 +16,7 @@ class EncodingQueue
15
16
  # Gets the next unencoded Video from the database and starts encoding it.
16
17
  #
17
18
  def encode_next_video
18
- if Video.unencoded.count > 0 && ::Video.encoding.count == 0
19
+ if Video.unencoded.count > 0 && ::Video.encoding.count < @threads
19
20
  video = Video.unencoded.first
20
21
  begin
21
22
  video.encoder.encode(video)
@@ -33,20 +33,16 @@ class Encoder
33
33
  #
34
34
  def ffmpeg(task, video)
35
35
  current_task_index = encoding_tasks.index(task)
36
- command_string = "ffmpeg -y -i #{video.file} #{task.command} #{video.file + task.output_file_suffix}"
36
+ movie = FFMPEG::Movie.new(video.file)
37
37
  encoding_operation = proc {
38
- video.state = "encoding"
39
- video.save
40
- Open3.popen3 "nice -n 19 #{command_string}" do |stdin, stdout, stderr|
41
- while stderr.gets()
42
- puts stderr.gets
43
- end
38
+ video.update(:state => 'encoding')
39
+ movie.transcode(video.file + task.output_file_suffix, task.command) do |p|
40
+ puts p*100
44
41
  end
45
42
  }
46
43
  completion_callback = proc {|result|
47
44
  if task == encoding_tasks.last
48
- video.state = "complete"
49
- video.save
45
+ video.update(:state => 'complete')
50
46
  video.notify_complete
51
47
  else
52
48
  next_task_index = current_task_index + 1
@@ -16,8 +16,15 @@ class Video
16
16
  property :encoder_id, Integer, :required => true
17
17
  property :callback_url, String
18
18
 
19
+ validates_with_method :file, :method => :check_file
20
+ validates_uniqueness_of :file, :scope => :encoder_id,
21
+ :message => "Same file with same encoder already exists"
19
22
  belongs_to :encoder
20
23
 
24
+ before :destroy, :check_destroy
25
+
26
+ default_scope(:default).update(:order => [:created_at.asc])
27
+
21
28
  # Notifies a calling application that processing has completed by sending
22
29
  # a GET request to the video's callback_url.
23
30
  #
@@ -68,5 +75,29 @@ class Video
68
75
  end
69
76
  end
70
77
 
78
+ private
79
+
80
+ def check_file
81
+ return [false, "Give a file name, not nil"] if self.file.nil?
82
+ return [false, "Give a file name, not a blank string"] if self.file.to_s.empty?
83
+ return [false, "#{self.file} does not exist"] unless File.exist? self.file
84
+ return [false, "#{self.file} is a directory"] if File.directory? self.file
85
+ movie = FFMPEG::Movie.new(self.file)
86
+ return [false, "#{self.file} is not a media file"] unless movie.valid?
87
+ return true
88
+ end
89
+
90
+ def check_destroy
91
+ return true if (self.state != 'encoding')
92
+ encoder = Encoder.get(self.encoder_id)
93
+ return true if stop_encode
94
+ throw :halt
95
+ end
96
+
97
+ def stop_encode
98
+ return false
99
+ #TODO Kill the encoder process
100
+ end
101
+
71
102
  end
72
103
 
@@ -1,6 +1,11 @@
1
1
  <% video = videos_video %>
2
2
  <li>
3
3
  <strong><%= video.state %></strong> - <%=h video.file %> -
4
- created at <%=h video.created_at.strftime("%m/%d/%Y at %H:%M:%S")%><br/>
4
+ created at <%=h video.created_at.strftime("%m/%d/%Y at %H:%M:%S")%>
5
+ <form action="/videos/<%= video.id %>" method="POST">
6
+ <input name="_method" value="DELETE" type="hidden"/>
7
+ <input type="submit" value="Delete"/>
8
+ </form>
9
+ <br/>
5
10
  </li>
6
11
 
@@ -1,3 +1,3 @@
1
1
  username: admin
2
2
  password: admin
3
-
3
+ threads: 1
@@ -3,7 +3,7 @@ require 'faker'
3
3
  require 'sham'
4
4
 
5
5
  Encoder.blueprint do
6
- name {"Blah encoder"}
6
+ name { Faker::Name.name }
7
7
  end
8
8
 
9
9
  Video.blueprint do
@@ -21,13 +21,13 @@ end
21
21
  EncodingTask.blueprint do
22
22
  name { "320x240 flv"}
23
23
  output_file_suffix { ".foo.flv" }
24
- command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136 -y"}
24
+ command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136"}
25
25
  end
26
26
 
27
27
  EncodingTask.blueprint(:with_encoder) do
28
28
  name { "320x240 flv"}
29
29
  output_file_suffix { ".foo.flv" }
30
- command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136 -y"}
30
+ command { "-ss 00:00:02 -t 00:00:01 -vcodec mjpeg -vframes 1 -an -f rawvideo -s 180x136"}
31
31
  encoder
32
32
  end
33
33
 
data/test/test_video.rb CHANGED
@@ -5,12 +5,18 @@ class TestVideo < Test::Unit::TestCase
5
5
 
6
6
  context "A Video instance" do
7
7
 
8
- should "be invalid without a file path" do
8
+ should "be invalid with a bad file path" do
9
9
  resource = ::Video.make
10
10
  resource.file = ""
11
- assert !resource.valid?
11
+ assert(!resource.valid?, "must not be empty")
12
12
  resource.file = nil
13
- assert !resource.valid?
13
+ assert(!resource.valid?, "must not be nil")
14
+ resource.file = "/fdfdf/sfdsdfsd/fse.gfr"
15
+ assert(!resource.valid?, "must be exist")
16
+ resource.file = File.dirname(__FILE__)
17
+ assert(!resource.valid?, "must not be a directory")
18
+ resource.file = __FILE__
19
+ assert(!resource.valid?, "must be media file")
14
20
  end
15
21
 
16
22
  should "be valid without a callback_url" do
@@ -27,9 +33,8 @@ class TestVideo < Test::Unit::TestCase
27
33
  assert resource.valid?
28
34
  end
29
35
 
30
- should "be valid with a file path" do
36
+ should "be valid with a correct file path" do
31
37
  resource = ::Video.make
32
- resource.file = "foo.mpg"
33
38
  assert resource.valid?
34
39
  end
35
40
 
@@ -76,6 +81,48 @@ class TestVideo < Test::Unit::TestCase
76
81
  end
77
82
  end
78
83
 
84
+ context "when try to delete any kind of videos from base" do
85
+ setup do
86
+ clear_videos
87
+ 5.times { Video.make }
88
+ end
89
+
90
+ should "be delete an unencoded videos" do
91
+ count = Video.unencoded.count
92
+ 2.times { Video.unencoded.first.destroy }
93
+ assert_equal count - 2, Video.unencoded.count
94
+ end
95
+
96
+ should "be delete a completed videos" do
97
+ 3.times { Video.unencoded.first.update(:state => "complete") }
98
+ count = Video.complete.count
99
+ 2.times { Video.complete.first.destroy }
100
+ assert_equal count - 2, Video.complete.count
101
+ end
102
+
103
+ should "be delete a videos with errors" do
104
+ 3.times { Video.unencoded.first.update(:state => "error") }
105
+ count = Video.with_errors.count
106
+ 2.times { Video.with_errors.first.destroy }
107
+ assert_equal count - 2, Video.with_errors.count
108
+ end
109
+
110
+ should "not be delete an encoding videos" do
111
+ 3.times { Video.unencoded.first.update(:state => "encoding") }
112
+ count = Video.encoding.count
113
+ 2.times { Video.encoding.first.destroy }
114
+ assert_equal count, Video.encoding.count
115
+ end
116
+
117
+ should "be hard delete an encoding videos" do
118
+ 3.times { Video.unencoded.first.update(:state => "encoding") }
119
+ count = Video.encoding.count
120
+ 2.times { Video.encoding.first.destroy! }
121
+ assert_equal count - 2, Video.encoding.count
122
+ end
123
+
124
+ end
125
+
79
126
  should "be able to grab all completed videos" do
80
127
  assert Video.respond_to? "complete"
81
128
  end
@@ -91,7 +138,7 @@ class TestVideo < Test::Unit::TestCase
91
138
  end
92
139
 
93
140
  def clear_videos
94
- Video.all.each {|v| v.destroy }
141
+ Video.all.each {|v| v.destroy! }
95
142
  end
96
143
 
97
144
  end
metadata CHANGED
@@ -1,32 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enigmamachine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 4
9
- - 3
10
- version: 0.4.3
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Dave Hrycyszyn
13
+ - Dmitry Brazhkin
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-15 00:00:00 +01:00
18
+ date: 2010-10-04 00:00:00 +01:00
19
19
  default_executable: enigmamachine
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: thoughtbot-shoulda
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
31
29
  - 0
32
30
  version: "0"
@@ -36,59 +34,51 @@ dependencies:
36
34
  name: data_mapper
37
35
  prerelease: false
38
36
  requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
37
  requirements:
41
- - - "="
38
+ - - ">="
42
39
  - !ruby/object:Gem::Version
43
- hash: 23
44
40
  segments:
45
41
  - 1
46
42
  - 0
47
- - 0
48
- version: 1.0.0
43
+ - 2
44
+ version: 1.0.2
49
45
  type: :runtime
50
46
  version_requirements: *id002
51
47
  - !ruby/object:Gem::Dependency
52
- name: eventmachine
48
+ name: dm-sqlite-adapter
53
49
  prerelease: false
54
50
  requirement: &id003 !ruby/object:Gem::Requirement
55
- none: false
56
51
  requirements:
57
- - - "="
52
+ - - ">="
58
53
  - !ruby/object:Gem::Version
59
- hash: 59
60
54
  segments:
55
+ - 1
61
56
  - 0
62
- - 12
63
- - 10
64
- version: 0.12.10
57
+ - 2
58
+ version: 1.0.2
65
59
  type: :runtime
66
60
  version_requirements: *id003
67
61
  - !ruby/object:Gem::Dependency
68
- name: dm-sqlite-adapter
62
+ name: eventmachine
69
63
  prerelease: false
70
64
  requirement: &id004 !ruby/object:Gem::Requirement
71
- none: false
72
65
  requirements:
73
- - - "="
66
+ - - ">="
74
67
  - !ruby/object:Gem::Version
75
- hash: 23
76
68
  segments:
77
- - 1
78
69
  - 0
79
- - 0
80
- version: 1.0.0
70
+ - 12
71
+ - 10
72
+ version: 0.12.10
81
73
  type: :runtime
82
74
  version_requirements: *id004
83
75
  - !ruby/object:Gem::Dependency
84
76
  name: rack-flash
85
77
  prerelease: false
86
78
  requirement: &id005 !ruby/object:Gem::Requirement
87
- none: false
88
79
  requirements:
89
80
  - - ">="
90
81
  - !ruby/object:Gem::Version
91
- hash: 3
92
82
  segments:
93
83
  - 0
94
84
  version: "0"
@@ -98,11 +88,9 @@ dependencies:
98
88
  name: ruby-debug
99
89
  prerelease: false
100
90
  requirement: &id006 !ruby/object:Gem::Requirement
101
- none: false
102
91
  requirements:
103
92
  - - ">="
104
93
  - !ruby/object:Gem::Version
105
- hash: 3
106
94
  segments:
107
95
  - 0
108
96
  version: "0"
@@ -112,11 +100,9 @@ dependencies:
112
100
  name: sinatra
113
101
  prerelease: false
114
102
  requirement: &id007 !ruby/object:Gem::Requirement
115
- none: false
116
103
  requirements:
117
- - - "="
104
+ - - ">="
118
105
  - !ruby/object:Gem::Version
119
- hash: 23
120
106
  segments:
121
107
  - 1
122
108
  - 0
@@ -125,19 +111,31 @@ dependencies:
125
111
  type: :runtime
126
112
  version_requirements: *id007
127
113
  - !ruby/object:Gem::Dependency
128
- name: thin
114
+ name: streamio-ffmpeg
129
115
  prerelease: false
130
116
  requirement: &id008 !ruby/object:Gem::Requirement
131
- none: false
132
117
  requirements:
133
118
  - - ">="
134
119
  - !ruby/object:Gem::Version
135
- hash: 3
136
120
  segments:
137
121
  - 0
138
- version: "0"
122
+ - 7
123
+ - 3
124
+ version: 0.7.3
139
125
  type: :runtime
140
126
  version_requirements: *id008
127
+ - !ruby/object:Gem::Dependency
128
+ name: thin
129
+ prerelease: false
130
+ requirement: &id009 !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ segments:
135
+ - 0
136
+ version: "0"
137
+ type: :runtime
138
+ version_requirements: *id009
141
139
  description: A RESTful video encoder which you can use as either a front-end to ffmpeg or headless on a server.
142
140
  email: dave@caprica
143
141
  executables:
@@ -211,34 +209,30 @@ rdoc_options:
211
209
  require_paths:
212
210
  - lib
213
211
  required_ruby_version: !ruby/object:Gem::Requirement
214
- none: false
215
212
  requirements:
216
213
  - - ">="
217
214
  - !ruby/object:Gem::Version
218
- hash: 3
219
215
  segments:
220
216
  - 0
221
217
  version: "0"
222
218
  required_rubygems_version: !ruby/object:Gem::Requirement
223
- none: false
224
219
  requirements:
225
220
  - - ">="
226
221
  - !ruby/object:Gem::Version
227
- hash: 3
228
222
  segments:
229
223
  - 0
230
224
  version: "0"
231
225
  requirements: []
232
226
 
233
227
  rubyforge_project:
234
- rubygems_version: 1.3.7
228
+ rubygems_version: 1.3.6
235
229
  signing_key:
236
230
  specification_version: 3
237
231
  summary: A RESTful video encoder.
238
232
  test_files:
239
- - test/helper.rb
240
- - test/test_enigmamachine.rb
241
233
  - test/support/blueprints.rb
234
+ - test/helper.rb
242
235
  - test/test_encoding_queue.rb
243
- - test/test_encoder.rb
244
236
  - test/test_video.rb
237
+ - test/test_encoder.rb
238
+ - test/test_enigmamachine.rb