vtools 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL +0 -0
- data/LICENSE +20 -0
- data/README.md +131 -0
- data/Rakefile +29 -0
- data/bin/vtools +22 -0
- data/doc/CONFIG.md +36 -0
- data/doc/HOOKS.md +37 -0
- data/doc/LIB_EXAMPLE.md +109 -0
- data/extconf.rb +7 -0
- data/lib/vtools.rb +79 -0
- data/lib/vtools/config.rb +91 -0
- data/lib/vtools/convert_options.rb +155 -0
- data/lib/vtools/converter.rb +98 -0
- data/lib/vtools/errors.rb +21 -0
- data/lib/vtools/handler.rb +43 -0
- data/lib/vtools/harvester.rb +71 -0
- data/lib/vtools/job.rb +48 -0
- data/lib/vtools/options.rb +101 -0
- data/lib/vtools/shared_methods.rb +131 -0
- data/lib/vtools/storage.rb +67 -0
- data/lib/vtools/thumbnailer.rb +93 -0
- data/lib/vtools/thumbs_options.rb +80 -0
- data/lib/vtools/version.rb +6 -0
- data/lib/vtools/version.rb~ +4 -0
- data/lib/vtools/video.rb +158 -0
- data/setup.rb +1585 -0
- data/spec/config_spec.rb +142 -0
- data/spec/convert_options_spec.rb +284 -0
- data/spec/converter_spec.rb +167 -0
- data/spec/errors_spec.rb +39 -0
- data/spec/fixtures/outputs/file_with_iso-8859-1.txt +35 -0
- data/spec/fixtures/outputs/file_with_no_audio.txt +18 -0
- data/spec/fixtures/outputs/file_with_non_supported_audio.txt +29 -0
- data/spec/fixtures/outputs/file_with_start_value.txt +19 -0
- data/spec/fixtures/outputs/file_with_surround_sound.txt +19 -0
- data/spec/handler_spec.rb +81 -0
- data/spec/harvester_spec.rb +189 -0
- data/spec/job_spec.rb +130 -0
- data/spec/options_spec.rb +52 -0
- data/spec/shared_methods_spec.rb +351 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/storage_spec.rb +106 -0
- data/spec/thumbnailer_spec.rb +178 -0
- data/spec/thumbs_options_spec.rb +159 -0
- data/spec/video_spec.rb +274 -0
- data/vtools.gemspec +29 -0
- metadata +177 -0
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "config"
|
3
|
+
|
4
|
+
describe VTools::CONFIG do
|
5
|
+
context "VTools::CONFIG" do
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@config = VTools::CONFIG.dup
|
9
|
+
@config[:video_set] = VTools::CONFIG[:video_set].dup
|
10
|
+
@config[:thumb_set] = VTools::CONFIG[:thumb_set].dup
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
VTools::CONFIG.replace @config.dup
|
15
|
+
VTools::CONFIG[:video_set] = @config[:video_set].dup
|
16
|
+
VTools::CONFIG[:thumb_set] = @config[:thumb_set].dup
|
17
|
+
end
|
18
|
+
|
19
|
+
# specs
|
20
|
+
context "#load!" do
|
21
|
+
|
22
|
+
it "executes configs without merge" do
|
23
|
+
VTools::CONFIG[:config_file] = false
|
24
|
+
|
25
|
+
VTools.should_not_receive(:keys_to_sym)
|
26
|
+
VTools::CONFIG.should_not_receive(:append!)
|
27
|
+
|
28
|
+
expect { VTools::CONFIG.load! }.to_not raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "merges configs sucessfully" do
|
32
|
+
VTools::CONFIG[:config_file] = 'exsitent/file'
|
33
|
+
YAML.stub!(:load_file).and_return { {} } # stub file access method
|
34
|
+
|
35
|
+
VTools.should_receive(:keys_to_sym)
|
36
|
+
VTools::CONFIG.should_receive(:append!)
|
37
|
+
|
38
|
+
expect { VTools::CONFIG.load! }.to_not raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it "breaks executing due to invalid yaml" do
|
42
|
+
VTools::CONFIG[:config_file] = 'nonexsitent/file'
|
43
|
+
expect { VTools::CONFIG.load! }.to raise_error VTools::ConfigError, /Invalid config data /
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "#append!" do
|
48
|
+
|
49
|
+
# common validator behavior
|
50
|
+
def validate_data config_hash
|
51
|
+
|
52
|
+
VTools::CONFIG.append! config_hash
|
53
|
+
|
54
|
+
# validate data
|
55
|
+
VTools::CONFIG.each do |name, content|
|
56
|
+
if config_hash.include? name
|
57
|
+
content.should == config_hash[name]
|
58
|
+
else # the rest data should remain untouched
|
59
|
+
content.should == @config[name]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "merges permitted data directly" do
|
65
|
+
data = {
|
66
|
+
:ffmpeg_binary => 'binary-ffmpeg',
|
67
|
+
:thumb_binary => 'binary-ffmpeg',
|
68
|
+
|
69
|
+
:max_jobs => 'jobs',
|
70
|
+
:harvester_timer=> 'timer',
|
71
|
+
:temp_dir => 'temp',
|
72
|
+
|
73
|
+
:video_storage => 'videos',
|
74
|
+
:thumb_storage => 'thumbs',
|
75
|
+
}
|
76
|
+
|
77
|
+
validate_data data
|
78
|
+
end
|
79
|
+
|
80
|
+
it "merges permitted data as array" do
|
81
|
+
data = { :library => ['data-lib'], }
|
82
|
+
|
83
|
+
validate_data data
|
84
|
+
end
|
85
|
+
|
86
|
+
it "merges permitted data as hash" do
|
87
|
+
data = {
|
88
|
+
:video_set => {:test => [1, 2, 3]},
|
89
|
+
:thumb_set => {:test => [1, 2, 3]},
|
90
|
+
}
|
91
|
+
|
92
|
+
VTools::CONFIG.append! data
|
93
|
+
|
94
|
+
# validate data
|
95
|
+
VTools::CONFIG.each do |name, content|
|
96
|
+
if data.include?(name)
|
97
|
+
content.should include(data[name])
|
98
|
+
content[:test].should == data[name][:test]
|
99
|
+
else # the rest data should remain
|
100
|
+
content.should == @config[name]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "skips denied data" do
|
106
|
+
invalid_data = {
|
107
|
+
:video_set => {:test => 3},
|
108
|
+
:thumb_set => :test,
|
109
|
+
:library => 'data-lib',
|
110
|
+
}
|
111
|
+
|
112
|
+
# save original values
|
113
|
+
VTools::CONFIG.append! invalid_data
|
114
|
+
|
115
|
+
# invalid data should not be placed & the rest data should remain the same
|
116
|
+
VTools::CONFIG.each { |key| VTools::CONFIG[key].should == @config[key] }
|
117
|
+
end
|
118
|
+
|
119
|
+
it "merges permitted & skips denied data (complex)" do
|
120
|
+
|
121
|
+
mixed_data = {
|
122
|
+
:video_set => {
|
123
|
+
:invalid => 3,
|
124
|
+
:valid => [1,2,3],
|
125
|
+
},
|
126
|
+
:thumb_set => {
|
127
|
+
:valid => [1,2,3],
|
128
|
+
},
|
129
|
+
:library => 'invalid',
|
130
|
+
}
|
131
|
+
VTools::CONFIG.append! mixed_data
|
132
|
+
|
133
|
+
VTools::CONFIG[:thumb_set].should include :valid
|
134
|
+
VTools::CONFIG[:thumb_set][:valid].should == mixed_data[:thumb_set][:valid]
|
135
|
+
|
136
|
+
VTools::CONFIG[:video_set].should_not include :valid
|
137
|
+
VTools::CONFIG[:video_set].should_not include :invalid
|
138
|
+
VTools::CONFIG[:library].should_not include 'invalid'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "convert_options"
|
3
|
+
|
4
|
+
describe VTools::ConvertOptions do
|
5
|
+
|
6
|
+
# hooks
|
7
|
+
before :all do
|
8
|
+
@options_base = VTools::ConvertOptions.new({})
|
9
|
+
end
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
@options = @options_base.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
# specs
|
16
|
+
context "#[]=" do
|
17
|
+
|
18
|
+
it "places width & height" do
|
19
|
+
# place initial value
|
20
|
+
@options.merge!({:s => "720x360"})
|
21
|
+
|
22
|
+
# set new values
|
23
|
+
@options[:width] = 1024
|
24
|
+
@options[:height] = 768
|
25
|
+
|
26
|
+
@options[:width].should == 1024
|
27
|
+
@options[:height].should == 768
|
28
|
+
@options[:s].should be nil
|
29
|
+
@options[:resolution].should be nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "places s" do
|
33
|
+
@options[:s] = "720x360"
|
34
|
+
|
35
|
+
@options[:s].should == "720x360"
|
36
|
+
@options[:resolution].should == "720x360"
|
37
|
+
@options[:width].should be 720
|
38
|
+
@options[:height].should be 360
|
39
|
+
end
|
40
|
+
|
41
|
+
it "places resolution" do
|
42
|
+
# place initial value
|
43
|
+
@options.merge!({:s => "720x360"})
|
44
|
+
|
45
|
+
# set new values
|
46
|
+
@options[:resolution] = "1024x768"
|
47
|
+
|
48
|
+
@options[:s].should == "1024x768"
|
49
|
+
@options[:resolution].should == "1024x768"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "places duration" do
|
53
|
+
# forward
|
54
|
+
@options[:t] = 25
|
55
|
+
@options[:t].should == 25
|
56
|
+
@options[:duration].should == 25
|
57
|
+
|
58
|
+
# reverse
|
59
|
+
@options[:duration] = 45
|
60
|
+
@options[:t].should == 45
|
61
|
+
@options[:duration].should == 45
|
62
|
+
end
|
63
|
+
|
64
|
+
it "places other" do
|
65
|
+
@options[:a] = 123
|
66
|
+
@options[:a].should == 123
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
context "#to_s" do
|
72
|
+
|
73
|
+
# skps ignored values
|
74
|
+
it "reates valid string representation" do
|
75
|
+
|
76
|
+
# still empty
|
77
|
+
@options.to_s.should == ""
|
78
|
+
|
79
|
+
# skips disallowed keywords
|
80
|
+
@options.merge!({
|
81
|
+
:width => 1024,
|
82
|
+
:height => 768,
|
83
|
+
:resolution => "600x400",
|
84
|
+
:extension => '.flv',
|
85
|
+
:preserve_aspect => false,
|
86
|
+
:duration => 123,
|
87
|
+
:postfix => "video",
|
88
|
+
:s => "640x480",
|
89
|
+
})
|
90
|
+
@options.to_s.should == "-s 640x480"
|
91
|
+
|
92
|
+
# validate with aspect
|
93
|
+
@options[:aspect] = 1.2
|
94
|
+
@options.to_s.should == "-s 640x480 -aspect 1.2"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "#perform" do
|
99
|
+
|
100
|
+
it "receives recalculate" do
|
101
|
+
@options.should_receive(:recalculate).once.and_return{ |str| str.split("x").map(&:to_i) }
|
102
|
+
|
103
|
+
values = {
|
104
|
+
:duration => 123,
|
105
|
+
:resolution => "600x360",
|
106
|
+
:preserve_aspect => true,
|
107
|
+
}
|
108
|
+
|
109
|
+
@options.method(:perform).call values
|
110
|
+
|
111
|
+
values.delete(:preserve_aspect)
|
112
|
+
@options.method(:perform).call values
|
113
|
+
end
|
114
|
+
|
115
|
+
it "converts data valid" do
|
116
|
+
@options.should_not_receive(:recalculate)
|
117
|
+
|
118
|
+
values = {
|
119
|
+
:duration => 123,
|
120
|
+
:resolution => "640x480",
|
121
|
+
:width => 600,
|
122
|
+
:height => 400,
|
123
|
+
:aspect => 1.3,
|
124
|
+
}
|
125
|
+
|
126
|
+
# major priority
|
127
|
+
@options.method(:perform).call values
|
128
|
+
values[:t].should == 123
|
129
|
+
values[:s].should == "640x480"
|
130
|
+
|
131
|
+
# middle priority
|
132
|
+
values.delete(:resolution)
|
133
|
+
@options.method(:perform).call values
|
134
|
+
values[:s].should == "600x400"
|
135
|
+
|
136
|
+
# minor priority
|
137
|
+
values[:s] = "1024x768"
|
138
|
+
values.delete(:preserve_aspect)
|
139
|
+
values.delete(:width)
|
140
|
+
values.delete(:height)
|
141
|
+
@options.method(:perform).call values
|
142
|
+
values[:s].should == "1024x768"
|
143
|
+
end
|
144
|
+
|
145
|
+
it "deletes invalid dimmensions definition" do
|
146
|
+
@options.should_not_receive(:recalculate)
|
147
|
+
|
148
|
+
values = { :width => 600 }
|
149
|
+
@options[:s] = "600x400"
|
150
|
+
@options.method(:perform).call values
|
151
|
+
values[:s].should be nil
|
152
|
+
|
153
|
+
values = { :height => 600 }
|
154
|
+
@options[:s] = "600x400"
|
155
|
+
@options.method(:perform).call values
|
156
|
+
values[:s].should be nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "#parse!" do
|
161
|
+
|
162
|
+
# set predefined data
|
163
|
+
VTools::CONFIG[:video_set][:x264_180p] = [
|
164
|
+
'libx264', 'libfaac', '240x180', '96k', '64k',
|
165
|
+
22050, 2, 'mp4', '_180', 'normal'
|
166
|
+
]
|
167
|
+
|
168
|
+
let :conf_hash do
|
169
|
+
{ :s => "240x180", :vcodec => "libx264", :acodec => "libfaac",
|
170
|
+
:vb => "96k", :ab => "64k", :ar => 22050, :ac => 2,
|
171
|
+
:extension => "mp4", :postfix => "_180", :vpre => "normal" }
|
172
|
+
end
|
173
|
+
|
174
|
+
def make_stubs
|
175
|
+
@options.stub(:keys_to_sym).and_return{ |hsh| hsh }
|
176
|
+
@options.stub(:perform).and_return{ |hsh| hsh }
|
177
|
+
end
|
178
|
+
|
179
|
+
it "parses custom hash" do
|
180
|
+
make_stubs
|
181
|
+
|
182
|
+
@options.method(:parse!).call({:s => "640x480"}).should == {:s => "640x480"}
|
183
|
+
@options.delete(:s)
|
184
|
+
@options.method(:parse!).call({:width => 640, :height => 480}).should == {:width => 640, :height => 480}
|
185
|
+
end
|
186
|
+
|
187
|
+
it "parses predefined set" do
|
188
|
+
make_stubs
|
189
|
+
|
190
|
+
@options.method(:parse!).call("x264_180p").should include conf_hash
|
191
|
+
end
|
192
|
+
|
193
|
+
it "parses complex set" do
|
194
|
+
make_stubs
|
195
|
+
|
196
|
+
complex = conf_hash.dup
|
197
|
+
complex[:s] = "1024x768"
|
198
|
+
|
199
|
+
@options.method(:parse!).call({:set => "x264_180p", :s => "1024x768"}).should include complex
|
200
|
+
end
|
201
|
+
|
202
|
+
it "raises error" do
|
203
|
+
make_stubs
|
204
|
+
|
205
|
+
expect {@options.method(:parse!).call(123) }.to raise_error VTools::ConfigError
|
206
|
+
expect {@options.method(:parse!).call("nonexistent") }.to raise_error VTools::ConfigError
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "#recalculate" do
|
211
|
+
|
212
|
+
it "no rescale" do
|
213
|
+
@options[:aspect] = nil
|
214
|
+
width, height = @options.method(:recalculate).call "1024x768"
|
215
|
+
width.should == 1024
|
216
|
+
height.should == 768
|
217
|
+
end
|
218
|
+
|
219
|
+
it "rescale by aspect > 1 (wide video)" do
|
220
|
+
@options[:aspect] = 6.to_f / 5.to_f # original video aspect is 6:5
|
221
|
+
{ # set max expected video dimm => rescale
|
222
|
+
"1024x768" => [922, 768], # we create 4:3
|
223
|
+
"1024x576" => [692, 576], # we create 16:9
|
224
|
+
}.each do |accept, result|
|
225
|
+
width, height = @options.method(:recalculate).call accept
|
226
|
+
width.should == result[0]
|
227
|
+
height.should == result[1]
|
228
|
+
end
|
229
|
+
|
230
|
+
@options[:aspect] = 17.to_f / 8.to_f # original video aspect is 17:8
|
231
|
+
{ # set max expected video dimm => rescale_result
|
232
|
+
"1024x768" => [1024, 482], # we create 4:3
|
233
|
+
"600x436" => [600, 282], # we create 11:8
|
234
|
+
}.each do |accept, result|
|
235
|
+
width, height = @options.method(:recalculate).call accept
|
236
|
+
width.should == result[0]
|
237
|
+
height.should == result[1]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
it "rescale by aspect < 1 (tall video)" do
|
242
|
+
@options[:aspect] = 5.to_f / 6.to_f # original video aspect is 5:6
|
243
|
+
{ # set max expected video dimm => rescale
|
244
|
+
"1024x768" => [640, 768], # we create 4:3
|
245
|
+
"1024x576" => [480, 576], # we create 16:9
|
246
|
+
}.each do |accept, result|
|
247
|
+
width, height = @options.method(:recalculate).call accept
|
248
|
+
width.should == result[0]
|
249
|
+
height.should == result[1]
|
250
|
+
end
|
251
|
+
|
252
|
+
@options[:aspect] = 8.to_f / 17.to_f # original video aspect is 8:17
|
253
|
+
{ # set max expected video dimm => rescale_result
|
254
|
+
"1024x768" => [362, 768], # we create 4:3
|
255
|
+
"600x436" => [206, 436], # we create 11:8
|
256
|
+
}.each do |accept, result|
|
257
|
+
width, height = @options.method(:recalculate).call accept
|
258
|
+
width.should == result[0]
|
259
|
+
height.should == result[1]
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
it "rescale by aspect = 1 (square video)" do
|
264
|
+
@options[:aspect] = 1.to_f / 1.to_f # original video aspect is 1:1
|
265
|
+
{ # set max expected video dimm => rescale
|
266
|
+
"1024x768" => [768, 768], # we create 4:3
|
267
|
+
"1024x576" => [576, 576], # we create 16:9
|
268
|
+
}.each do |accept, result|
|
269
|
+
width, height = @options.method(:recalculate).call accept
|
270
|
+
width.should == result[0]
|
271
|
+
height.should == result[1]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "#initialize" do
|
277
|
+
it "valid calls methods" do
|
278
|
+
config = { :width => 1024, :height => 768 }
|
279
|
+
|
280
|
+
VTools::ConvertOptions.any_instance.should_receive(:parse!).with(config)
|
281
|
+
options = VTools::ConvertOptions.new config
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "converter"
|
3
|
+
|
4
|
+
describe VTools::Converter do
|
5
|
+
|
6
|
+
# hooks
|
7
|
+
before do
|
8
|
+
@converter = VTools::Converter.new nil
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:video) { double nil }
|
12
|
+
|
13
|
+
# specs
|
14
|
+
context "#run" do
|
15
|
+
|
16
|
+
let(:output_array) { [] }
|
17
|
+
let(:ffmpeg_7) { {10.02 => "time=10.02", 15.34 => "time=15.34", 20.45 => "time=20.45"} }
|
18
|
+
let(:ffmpeg_8) { {10.02 => "time=00:00:10.02", 15.34 => "time=00:00:15.34", 20.45 => "time=00:00:20.45", 61.05 => "time=00:01:01.05"} }
|
19
|
+
let(:ffmpeg_no_time) { {0.0 => "broken pipe"} }
|
20
|
+
|
21
|
+
# hooks
|
22
|
+
before do
|
23
|
+
@output_file = nil
|
24
|
+
@options = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def prepare_converter values_set
|
29
|
+
# prepare output lines
|
30
|
+
output_array.push *values_set.values
|
31
|
+
# output iterator
|
32
|
+
(io = double(nil)).stub!(:each) { |*args, blk| output_array.each { |line| blk.yield(line) } }
|
33
|
+
Open3.stub!(:popen3).and_return{ |*args, block| block.yield(nil, nil, io) }
|
34
|
+
|
35
|
+
@options.should_receive(:to_s).and_return { "test.options" }
|
36
|
+
|
37
|
+
video.stub(:convert_options){ @options }
|
38
|
+
video.stub(:name) {"video/name"}
|
39
|
+
video.stub(:path) {"video/path"}
|
40
|
+
video.stub(:duration) { values_set.keys.last }
|
41
|
+
|
42
|
+
@converter.instance_variable_set(:@video, video)
|
43
|
+
|
44
|
+
VTools::CONFIG[:ffmpeg_binary] = "tested.ffmpeg"
|
45
|
+
@output_file = "/#{video.name}#{@options[:postfix]}.#{@options[:extension]}"
|
46
|
+
# "#{CONFIG[:ffmpeg_binary]} -y -i '#{@video.path}' #{@options} '#{@output_file}'"
|
47
|
+
exec_com = "tested.ffmpeg -y -i 'video/path' test.options '#{@output_file}'"
|
48
|
+
|
49
|
+
VTools::Handler.should_receive(:exec).with(:before_convert, video, exec_com)
|
50
|
+
VTools.should_receive(:fix_encoding).exactly(values_set.size).times
|
51
|
+
@converter.should_receive(:generate_path)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "converts video for ffmpeg 0.7" do
|
55
|
+
prepare_converter ffmpeg_7
|
56
|
+
|
57
|
+
ffmpeg_7.each do |sec, time_str|
|
58
|
+
VTools::Handler.should_receive(:exec).with(:in_convert, video, sec/ffmpeg_7.keys.last)
|
59
|
+
end
|
60
|
+
|
61
|
+
VTools::Handler.should_receive(:exec).with(:convert_success, video, @output_file)
|
62
|
+
@converter.should_receive(:encoding_invalid?) { false }
|
63
|
+
@converter.should_receive(:encoded)
|
64
|
+
|
65
|
+
@converter.run
|
66
|
+
end
|
67
|
+
|
68
|
+
it "converts video for ffmpeg 0.8" do
|
69
|
+
prepare_converter ffmpeg_8
|
70
|
+
|
71
|
+
ffmpeg_8.each do |sec, time_str|
|
72
|
+
VTools::Handler.should_receive(:exec).with(:in_convert, video, sec/ffmpeg_8.keys.last)
|
73
|
+
end
|
74
|
+
|
75
|
+
VTools::Handler.should_receive(:exec).with(:convert_success, video, @output_file)
|
76
|
+
@converter.should_receive(:encoding_invalid?) { false }
|
77
|
+
@converter.should_receive(:encoded)
|
78
|
+
|
79
|
+
@converter.run
|
80
|
+
end
|
81
|
+
|
82
|
+
context "fails encoding" do
|
83
|
+
|
84
|
+
it "--no time received" do
|
85
|
+
prepare_converter ffmpeg_no_time
|
86
|
+
expect { @converter.run }.to raise_error VTools::ProcessError, "broken pipe"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "--result file is invalid" do
|
90
|
+
VTools::Handler.stub(:exec).and_return nil
|
91
|
+
prepare_converter ffmpeg_7
|
92
|
+
@converter.should_receive(:encoding_invalid?) { "test.fail" }
|
93
|
+
expect { @converter.run }.to raise_error VTools::ProcessError, "test.fail"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "#encoding_invalid?" do
|
99
|
+
|
100
|
+
before do
|
101
|
+
VTools::CONFIG[:validate_duration] = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def prepare_converter
|
105
|
+
File.stub!(:exists?).and_return { true }
|
106
|
+
video.stub(:duration) { 200.2 } # set duration in sec
|
107
|
+
@converter.stub_chain(:encoded, :valid?).and_return { true }
|
108
|
+
@converter.instance_variable_set(:@video, video)
|
109
|
+
end
|
110
|
+
|
111
|
+
context "encoding is valid" do
|
112
|
+
|
113
|
+
it "no manual duration set" do
|
114
|
+
prepare_converter
|
115
|
+
@converter.instance_variable_set(:@options, {}) # no manual duration set
|
116
|
+
@converter.stub_chain(:encoded, :duration).and_return { 200.2 }
|
117
|
+
VTools::CONFIG[:validate_duration] = true
|
118
|
+
|
119
|
+
@converter.encoding_invalid?.should == false
|
120
|
+
end
|
121
|
+
|
122
|
+
it "duration set manually" do
|
123
|
+
prepare_converter
|
124
|
+
@converter.instance_variable_set(:@options, { :duration => 115.3 }) # manual duration set
|
125
|
+
@converter.stub_chain(:encoded, :duration).and_return { 115.3 }
|
126
|
+
VTools::CONFIG[:validate_duration] = true
|
127
|
+
|
128
|
+
@converter.encoding_invalid?.should == false
|
129
|
+
end
|
130
|
+
|
131
|
+
it "without duration test" do
|
132
|
+
prepare_converter
|
133
|
+
@converter.encoding_invalid?.should == false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "encoding is invalid" do
|
138
|
+
|
139
|
+
it "no encoded file" do
|
140
|
+
File.stub!(:exists?).and_return { false }
|
141
|
+
@converter.encoding_invalid?.should == "No output file created"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "encoded media is invalid video instance" do
|
145
|
+
File.stub!(:exists?).and_return { true }
|
146
|
+
@converter.stub_chain(:encoded, :valid?).and_return { false }
|
147
|
+
@converter.encoding_invalid?.should == "Encoded file is invalid"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "invalid duration auto" do
|
151
|
+
prepare_converter
|
152
|
+
VTools::CONFIG[:validate_duration] = true
|
153
|
+
@converter.instance_variable_set(:@options, { :duration => 115.3 }) # no manual duration set
|
154
|
+
@converter.stub_chain(:encoded, :duration).and_return { 220.2 } # original 220
|
155
|
+
@converter.encoding_invalid?.should =~ /Encoded file duration is invalid \(original\/specified:/
|
156
|
+
end
|
157
|
+
|
158
|
+
it "invalid duration manual" do
|
159
|
+
prepare_converter
|
160
|
+
VTools::CONFIG[:validate_duration] = true
|
161
|
+
@converter.instance_variable_set(:@options, {}) # no manual duration set
|
162
|
+
@converter.stub_chain(:encoded, :duration).and_return { 320.2 } # original 220
|
163
|
+
@converter.encoding_invalid?.should =~ /Encoded file duration is invalid \(original\/specified:/
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|