apple-tv-converter 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +11 -0
- data/Gemfile.lock +44 -0
- data/README.md +3 -2
- data/bin/SublerCLI +0 -0
- data/gems/streamio-ffmpeg/CHANGELOG +198 -0
- data/gems/streamio-ffmpeg/Gemfile +3 -0
- data/gems/streamio-ffmpeg/LICENSE +20 -0
- data/gems/streamio-ffmpeg/README.md +180 -0
- data/gems/streamio-ffmpeg/Rakefile +22 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/encoding_options.rb +139 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/errors.rb +4 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/io_monkey.rb +42 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/movie.rb +206 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/stream.rb +15 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/transcoder.rb +120 -0
- data/gems/streamio-ffmpeg/lib/ffmpeg/version.rb +3 -0
- data/gems/streamio-ffmpeg/lib/streamio-ffmpeg.rb +49 -0
- data/gems/streamio-ffmpeg/spec/ffmpeg/encoding_options_spec.rb +135 -0
- data/gems/streamio-ffmpeg/spec/ffmpeg/movie_spec.rb +325 -0
- data/gems/streamio-ffmpeg/spec/ffmpeg/transcoder_spec.rb +210 -0
- data/gems/streamio-ffmpeg/spec/fixtures/bin/ffmpeg-audio-only +62 -0
- data/gems/streamio-ffmpeg/spec/fixtures/bin/ffmpeg-hanging +44 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/awesome movie.mov +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/awesome'movie.mov +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/awesome_widescreen.mov +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/broken.mp4 +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/empty.flv +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/sideways movie.mov +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/movies/weird_aspect.small.mpg +0 -0
- data/gems/streamio-ffmpeg/spec/fixtures/outputs/file_with_iso-8859-1.txt +35 -0
- data/gems/streamio-ffmpeg/spec/fixtures/outputs/file_with_no_audio.txt +18 -0
- data/gems/streamio-ffmpeg/spec/fixtures/outputs/file_with_non_supported_audio.txt +29 -0
- data/gems/streamio-ffmpeg/spec/fixtures/outputs/file_with_surround_sound.txt +19 -0
- data/gems/streamio-ffmpeg/spec/fixtures/outputs/file_with_weird_dar.txt +24 -0
- data/gems/streamio-ffmpeg/spec/fixtures/sounds/napoleon.mp3 +0 -0
- data/gems/streamio-ffmpeg/spec/spec_helper.rb +21 -0
- data/gems/streamio-ffmpeg/spec/streamio-ffmpeg_spec.rb +40 -0
- data/gems/streamio-ffmpeg/streamio-ffmpeg.gemspec +19 -0
- data/lib/apple_tv_converter.rb +10 -4
- data/lib/apple_tv_converter/apple_tv_converter.sublime-project +0 -6
- data/lib/apple_tv_converter/apple_tv_converter.sublime-workspace +501 -378
- data/lib/apple_tv_converter/command_line.rb +46 -22
- data/lib/apple_tv_converter/media.rb +49 -16
- data/lib/apple_tv_converter/media_converter.rb +19 -18
- data/lib/apple_tv_converter/media_converter_adapter.rb +58 -14
- data/lib/apple_tv_converter/media_converter_mac_adapter.rb +46 -35
- data/lib/apple_tv_converter/version.rb +1 -1
- metadata +49 -12
@@ -0,0 +1,49 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
require 'ffmpeg/version'
|
7
|
+
require 'ffmpeg/errors'
|
8
|
+
require 'ffmpeg/movie'
|
9
|
+
require 'ffmpeg/stream'
|
10
|
+
require 'ffmpeg/io_monkey'
|
11
|
+
require 'ffmpeg/transcoder'
|
12
|
+
require 'ffmpeg/encoding_options'
|
13
|
+
|
14
|
+
module FFMPEG
|
15
|
+
# FFMPEG logs information about its progress when it's transcoding.
|
16
|
+
# Jack in your own logger through this method if you wish to.
|
17
|
+
#
|
18
|
+
# @param [Logger] log your own logger
|
19
|
+
# @return [Logger] the logger you set
|
20
|
+
def self.logger=(log)
|
21
|
+
@logger = log
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get FFMPEG logger.
|
25
|
+
#
|
26
|
+
# @return [Logger]
|
27
|
+
def self.logger
|
28
|
+
return @logger if @logger
|
29
|
+
logger = Logger.new(STDOUT)
|
30
|
+
logger.level = Logger::INFO
|
31
|
+
@logger = logger
|
32
|
+
end
|
33
|
+
|
34
|
+
# Set the path of the ffmpeg binary.
|
35
|
+
# Can be useful if you need to specify a path such as /usr/local/bin/ffmpeg
|
36
|
+
#
|
37
|
+
# @param [String] path to the ffmpeg binary
|
38
|
+
# @return [String] the path you set
|
39
|
+
def self.ffmpeg_binary=(bin)
|
40
|
+
@ffmpeg_binary = bin
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the path to the ffmpeg binary, defaulting to 'ffmpeg'
|
44
|
+
#
|
45
|
+
# @return [String] the path to the ffmpeg binary
|
46
|
+
def self.ffmpeg_binary
|
47
|
+
@ffmpeg_binary || 'ffmpeg'
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
module FFMPEG
|
4
|
+
describe EncodingOptions do
|
5
|
+
describe "ffmpeg arguments conversion" do
|
6
|
+
it "should convert video codec" do
|
7
|
+
EncodingOptions.new(video_codec: "libx264").to_s.should == "-vcodec libx264"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should know the width from the resolution or be nil" do
|
11
|
+
EncodingOptions.new(resolution: "320x240").width.should == 320
|
12
|
+
EncodingOptions.new.width.should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should know the height from the resolution or be nil" do
|
16
|
+
EncodingOptions.new(resolution: "320x240").height.should == 240
|
17
|
+
EncodingOptions.new.height.should be_nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should convert frame rate" do
|
21
|
+
EncodingOptions.new(frame_rate: 29.9).to_s.should == "-r 29.9"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should convert the resolution" do
|
25
|
+
EncodingOptions.new(resolution: "640x480").to_s.should include("-s 640x480")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should add calculated aspect ratio" do
|
29
|
+
EncodingOptions.new(resolution: "640x480").to_s.should include("-aspect 1.3333333")
|
30
|
+
EncodingOptions.new(resolution: "640x360").to_s.should include("-aspect 1.7777777777777")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should use specified aspect ratio if given" do
|
34
|
+
output = EncodingOptions.new(resolution: "640x480", aspect: 1.77777777777778).to_s
|
35
|
+
output.should include("-s 640x480")
|
36
|
+
output.should include("-aspect 1.77777777777778")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should convert video bitrate" do
|
40
|
+
EncodingOptions.new(video_bitrate: "600k").to_s.should == "-b:v 600k"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should use k unit for video bitrate" do
|
44
|
+
EncodingOptions.new(video_bitrate: 600).to_s.should == "-b:v 600k"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should convert audio codec" do
|
48
|
+
EncodingOptions.new(audio_codec: "aac").to_s.should == "-acodec aac"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should convert audio bitrate" do
|
52
|
+
EncodingOptions.new(audio_bitrate: "128k").to_s.should == "-b:a 128k"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should use k unit for audio bitrate" do
|
56
|
+
EncodingOptions.new(audio_bitrate: 128).to_s.should == "-b:a 128k"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should convert audio sample rate" do
|
60
|
+
EncodingOptions.new(audio_sample_rate: 44100).to_s.should == "-ar 44100"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should convert audio channels" do
|
64
|
+
EncodingOptions.new(audio_channels: 2).to_s.should == "-ac 2"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should convert maximum video bitrate" do
|
68
|
+
EncodingOptions.new(video_max_bitrate: 600).to_s.should == "-maxrate 600k"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should convert mininimum video bitrate" do
|
72
|
+
EncodingOptions.new(video_min_bitrate: 600).to_s.should == "-minrate 600k"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should convert video bitrate tolerance" do
|
76
|
+
EncodingOptions.new(video_bitrate_tolerance: 100).to_s.should == "-bt 100k"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should convert buffer size" do
|
80
|
+
EncodingOptions.new(buffer_size: 2000).to_s.should == "-bufsize 2000k"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should convert threads" do
|
84
|
+
EncodingOptions.new(threads: 2).to_s.should == "-threads 2"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should convert duration" do
|
88
|
+
EncodingOptions.new(duration: 30).to_s.should == "-t 30"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should convert keyframe interval" do
|
92
|
+
EncodingOptions.new(keyframe_interval: 60).to_s.should == "-g 60"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should convert video preset" do
|
96
|
+
EncodingOptions.new(video_preset: "max").to_s.should == "-vpre max"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should convert audio preset" do
|
100
|
+
EncodingOptions.new(audio_preset: "max").to_s.should == "-apre max"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should convert file preset" do
|
104
|
+
EncodingOptions.new(file_preset: "max.ffpreset").to_s.should == "-fpre max.ffpreset"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should specify seek time" do
|
108
|
+
EncodingOptions.new(seek_time: 1).to_s.should == "-ss 1"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should specify screenshot parameters" do
|
112
|
+
EncodingOptions.new(screenshot: true).to_s.should == "-vframes 1 -f image2"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should put the parameters in order of codecs, presets, others" do
|
116
|
+
opts = Hash.new
|
117
|
+
opts[:frame_rate] = 25
|
118
|
+
opts[:video_codec] = "libx264"
|
119
|
+
opts[:video_preset] = "normal"
|
120
|
+
|
121
|
+
converted = EncodingOptions.new(opts).to_s
|
122
|
+
converted.should == "-vcodec libx264 -vpre normal -r 25"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should convert a lot of them simultaneously" do
|
126
|
+
converted = EncodingOptions.new(video_codec: "libx264", audio_codec: "aac", video_bitrate: "1000k").to_s
|
127
|
+
converted.should match(/-acodec aac/)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should ignore options with nil value" do
|
131
|
+
EncodingOptions.new(video_codec: "libx264", frame_rate: nil).to_s.should == "-vcodec libx264 "
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,325 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
module FFMPEG
|
4
|
+
describe Movie do
|
5
|
+
describe "initializing" do
|
6
|
+
context "given a non existing file" do
|
7
|
+
it "should throw ArgumentError" do
|
8
|
+
expect { Movie.new("i_dont_exist") }.to raise_error(Errno::ENOENT, /does not exist/)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "given a file containing a single quotation mark in the filename" do
|
13
|
+
before(:all) do
|
14
|
+
@movie = Movie.new("#{fixture_path}/movies/awesome'movie.mov")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should run ffmpeg successfully" do
|
18
|
+
@movie.duration.should == 7.56
|
19
|
+
@movie.frame_rate.should == 16.75
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "given a non movie file" do
|
24
|
+
before(:all) do
|
25
|
+
@movie = Movie.new(__FILE__)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be valid" do
|
29
|
+
@movie.should_not be_valid
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a duration of 0" do
|
33
|
+
@movie.duration.should == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have nil height" do
|
37
|
+
@movie.height.should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have nil width" do
|
41
|
+
@movie.width.should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have nil frame_rate" do
|
45
|
+
@movie.frame_rate.should be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "given an empty flv file (could not find codec parameters)" do
|
50
|
+
before(:all) do
|
51
|
+
@movie = Movie.new("#{fixture_path}/movies/empty.flv")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not be valid" do
|
55
|
+
@movie.should_not be_valid
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "given a broken mp4 file" do
|
60
|
+
before(:all) do
|
61
|
+
@movie = Movie.new("#{fixture_path}/movies/broken.mp4")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should not be valid" do
|
65
|
+
@movie.should_not be_valid
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should have nil calculated_aspect_ratio" do
|
69
|
+
@movie.calculated_aspect_ratio.should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "given a weird aspect ratio file" do
|
74
|
+
before(:all) do
|
75
|
+
@movie = Movie.new("#{fixture_path}/movies/weird_aspect.small.mpg")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should parse the DAR" do
|
79
|
+
@movie.dar.should == "704:405"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should have correct calculated_aspect_ratio" do
|
83
|
+
@movie.calculated_aspect_ratio.to_s[0..14].should == "1.7382716049382" # substringed to be 1.9 compatible
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "given an impossible DAR" do
|
88
|
+
before(:all) do
|
89
|
+
fake_output = StringIO.new(File.read("#{fixture_path}/outputs/file_with_weird_dar.txt"))
|
90
|
+
Open3.stub!(:popen3).and_yield(nil,nil,fake_output)
|
91
|
+
@movie = Movie.new(__FILE__)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should parse the DAR" do
|
95
|
+
@movie.dar.should == "0:1"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should calulate using width and height instead" do
|
99
|
+
@movie.calculated_aspect_ratio.to_s[0..14].should == "1.7777777777777" # substringed to be 1.9 compatible
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "given a file with ISO-8859-1 characters in output" do
|
104
|
+
it "should not crash" do
|
105
|
+
fake_output = StringIO.new(File.read("#{fixture_path}/outputs/file_with_iso-8859-1.txt"))
|
106
|
+
Open3.stub!(:popen3).and_yield(nil, nil, fake_output)
|
107
|
+
expect { Movie.new(__FILE__) }.to_not raise_error
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "given a file with 5.1 audio" do
|
112
|
+
before(:all) do
|
113
|
+
fake_output = StringIO.new(File.read("#{fixture_path}/outputs/file_with_surround_sound.txt"))
|
114
|
+
Open3.stub!(:popen3).and_yield(nil, nil, fake_output)
|
115
|
+
@movie = Movie.new(__FILE__)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have 6 audio channels" do
|
119
|
+
@movie.audio_channels.should == 6
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "given a file with no audio" do
|
124
|
+
before(:all) do
|
125
|
+
fake_output = StringIO.new(File.read("#{fixture_path}/outputs/file_with_no_audio.txt"))
|
126
|
+
Open3.stub!(:popen3).and_yield(nil, nil, fake_output)
|
127
|
+
@movie = Movie.new(__FILE__)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should have nil audio channels" do
|
131
|
+
@movie.audio_channels.should == nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "given a file with non supported audio" do
|
136
|
+
before(:all) do
|
137
|
+
fake_output = StringIO.new(File.read("#{fixture_path}/outputs/file_with_non_supported_audio.txt"))
|
138
|
+
Open3.stub!(:popen3).and_yield(nil, nil, fake_output)
|
139
|
+
@movie = Movie.new(__FILE__)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should not be valid" do
|
143
|
+
@movie.should_not be_valid
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "given an awesome movie file" do
|
148
|
+
before(:all) do
|
149
|
+
@movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should remember the movie path" do
|
153
|
+
@movie.path.should == "#{fixture_path}/movies/awesome movie.mov"
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should parse duration to number of seconds" do
|
157
|
+
@movie.duration.should == 7.56
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should parse the bitrate" do
|
161
|
+
@movie.bitrate.should == 481
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should return nil rotation when no rotation exists" do
|
165
|
+
@movie.rotation.should == nil
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should parse the creation_time" do
|
169
|
+
@movie.creation_time.should == Time.parse("2010-02-05 16:05:04")
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should parse video stream information" do
|
173
|
+
@movie.video_stream.should == "h264 (Main) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 371 kb/s, 16.75 fps, 600 tbr, 600 tbn, 1200 tbc"
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should know the video codec" do
|
177
|
+
@movie.video_codec.should =~ /h264/
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should know the colorspace" do
|
181
|
+
@movie.colorspace.should == "yuv420p"
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should know the resolution" do
|
185
|
+
@movie.resolution.should == "640x480"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should know the video bitrate" do
|
189
|
+
@movie.video_bitrate.should == 371
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should know the width and height" do
|
193
|
+
@movie.width.should == 640
|
194
|
+
@movie.height.should == 480
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should know the framerate" do
|
198
|
+
@movie.frame_rate.should == 16.75
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should parse audio stream information" do
|
202
|
+
@movie.audio_stream.should == "aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 75 kb/s"
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should know the audio codec" do
|
206
|
+
@movie.audio_codec.should =~ /aac/
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should know the sample rate" do
|
210
|
+
@movie.audio_sample_rate.should == 44100
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should know the number of audio channels" do
|
214
|
+
@movie.audio_channels.should == 2
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should know the audio bitrate" do
|
218
|
+
@movie.audio_bitrate.should == 75
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should should be valid" do
|
222
|
+
@movie.should be_valid
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should calculate the aspect ratio" do
|
226
|
+
@movie.calculated_aspect_ratio.to_s[0..14].should == "1.3333333333333" # substringed to be 1.9 compatible
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should know the file size" do
|
230
|
+
@movie.size.should == 455546
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should know the container" do
|
234
|
+
@movie.container.should == "mov,mp4,m4a,3gp,3g2,mj2"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "given a rotated movie file" do
|
240
|
+
before(:all) do
|
241
|
+
@movie = Movie.new("#{fixture_path}/movies/sideways movie.mov")
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should parse the rotation" do
|
245
|
+
@movie.rotation.should == 90
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe "transcode" do
|
250
|
+
it "should run the transcoder" do
|
251
|
+
movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
|
252
|
+
|
253
|
+
mockery = mock(Transcoder)
|
254
|
+
Transcoder.should_receive(:new).with(movie, "#{tmp_path}/awesome.flv", {custom: "-vcodec libx264"}, preserve_aspect_ratio: :width).and_return(mockery)
|
255
|
+
mockery.should_receive(:run)
|
256
|
+
|
257
|
+
movie.transcode("#{tmp_path}/awesome.flv", {custom: "-vcodec libx264"}, preserve_aspect_ratio: :width)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe "screenshot" do
|
262
|
+
it "should run the transcoder with screenshot option" do
|
263
|
+
movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
|
264
|
+
|
265
|
+
mockery = mock(Transcoder)
|
266
|
+
Transcoder.should_receive(:new).with(movie, "#{tmp_path}/awesome.jpg", {seek_time: 2, dimensions: "640x480", screenshot: true}, preserve_aspect_ratio: :width).and_return(mockery)
|
267
|
+
mockery.should_receive(:run)
|
268
|
+
|
269
|
+
movie.screenshot("#{tmp_path}/awesome.jpg", {seek_time: 2, dimensions: "640x480"}, preserve_aspect_ratio: :width)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "given a movie with audio" do
|
274
|
+
before(:all) do
|
275
|
+
@movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should have two total streams" do
|
279
|
+
@movie.streams.count.should == 2
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should have one audio stream" do
|
283
|
+
@movie.streams.select { |s| s.type == :audio }.count.should == 1
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should have one video stream" do
|
287
|
+
@movie.streams.select { |s| s.type == :video }.count.should == 1
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should have no subtitle streams" do
|
291
|
+
@movie.streams.select { |s| s.type == :subtitle }.count.should == 0
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should identify the audio stream language" do
|
295
|
+
@movie.streams.select { |s| s.type == :audio }.first.language.should == 'und'
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "given an audio file" do
|
300
|
+
before(:all) do
|
301
|
+
@movie = Movie.new("#{fixture_path}/sounds/napoleon.mp3")
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should have one total stream" do
|
305
|
+
@movie.streams.count.should == 1
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should have one audio stream" do
|
309
|
+
@movie.streams.select { |s| s.type == :audio }.count.should == 1
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should have no video streams" do
|
313
|
+
@movie.streams.select { |s| s.type == :video }.count.should == 0
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should have no subtitle streams" do
|
317
|
+
@movie.streams.select { |s| s.type == :subtitle }.count.should == 0
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should know the container format" do
|
321
|
+
@movie.container.should =~ /mp3/
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|