streamio-ffmpeg 0.6.0 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/VERSION +1 -1
- data/lib/ffmpeg/movie.rb +11 -4
- data/lib/ffmpeg/transcoder.rb +6 -3
- data/spec/ffmpeg/movie_spec.rb +28 -0
- data/spec/ffmpeg/transcoder_spec.rb +32 -0
- data/spec/fixtures/movies/broken.mp4 +0 -0
- data/spec/fixtures/sounds/napoleon.mp3 +0 -0
- data/streamio-ffmpeg.gemspec +4 -2
- metadata +5 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.6.2 2010-05-05
|
2
|
+
|
3
|
+
* Added Movie#uncertain_duration? which is true if ffmpeg is guessing duration from bitrate
|
4
|
+
* Skipping the transcoders duration validation if original file has uncertain duration
|
5
|
+
* Made sure aspect ratio preservation always rounds new size to an even number to avoid "not divisible by 2" errors
|
6
|
+
* Changed Movie#valid? logic to accept any movie with either a readable audio or video stream
|
7
|
+
|
1
8
|
== 0.6.0 2010-05-04
|
2
9
|
|
3
10
|
* Cropping options now handled by EncodingOptions (croptop, cropbottom, cropleft and cropright)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.2
|
data/lib/ffmpeg/movie.rb
CHANGED
@@ -12,8 +12,6 @@ module FFMPEG
|
|
12
12
|
stdin, stdout, stderr = Open3.popen3("ffmpeg -i '#{path}'") # Output will land in stderr
|
13
13
|
output = stderr.read
|
14
14
|
|
15
|
-
@valid = output["Unknown format"].nil? && output["Invalid data found when processing input"].nil?
|
16
|
-
|
17
15
|
output[/Duration: (\d{2}):(\d{2}):(\d{2}\.\d{1})/]
|
18
16
|
@duration = ($1.to_i*60*60) + ($2.to_i*60) + $3.to_f
|
19
17
|
|
@@ -26,6 +24,8 @@ module FFMPEG
|
|
26
24
|
output[/Audio: (.*)/]
|
27
25
|
@audio_stream = $1
|
28
26
|
|
27
|
+
@uncertain_duration = output.include?("Estimating duration from bitrate, this may be inaccurate")
|
28
|
+
|
29
29
|
if video_stream
|
30
30
|
@video_codec, @colorspace, resolution = video_stream.split(/\s?,\s?/)
|
31
31
|
@resolution = resolution.split(" ").first # get rid of [PAR 1:1 DAR 16:9]
|
@@ -35,10 +35,16 @@ module FFMPEG
|
|
35
35
|
@audio_codec, audio_sample_rate, @audio_channels = audio_stream.split(/\s?,\s?/)
|
36
36
|
@audio_sample_rate = audio_sample_rate[/\d*/].to_i
|
37
37
|
end
|
38
|
+
|
39
|
+
@invalid = @video_stream.to_s.empty? && @audio_stream.to_s.empty?
|
38
40
|
end
|
39
41
|
|
40
42
|
def valid?
|
41
|
-
@
|
43
|
+
not @invalid
|
44
|
+
end
|
45
|
+
|
46
|
+
def uncertain_duration?
|
47
|
+
@uncertain_duration
|
42
48
|
end
|
43
49
|
|
44
50
|
def width
|
@@ -50,7 +56,8 @@ module FFMPEG
|
|
50
56
|
end
|
51
57
|
|
52
58
|
def calculated_aspect_ratio
|
53
|
-
width.to_f / height.to_f
|
59
|
+
aspect = width.to_f / height.to_f
|
60
|
+
aspect.nan? ? nil : aspect
|
54
61
|
end
|
55
62
|
|
56
63
|
def audio_channels
|
data/lib/ffmpeg/transcoder.rb
CHANGED
@@ -65,7 +65,7 @@ module FFMPEG
|
|
65
65
|
end
|
66
66
|
|
67
67
|
precision = 1.1
|
68
|
-
unless !(encoded.duration >= (@movie.duration * precision) or encoded.duration <= (@movie.duration / precision))
|
68
|
+
unless @movie.uncertain_duration? || !(encoded.duration >= (@movie.duration * precision) or encoded.duration <= (@movie.duration / precision))
|
69
69
|
@errors << "encoded file duration differed from original (original: #{@movie.duration}sec, encoded: #{encoded.duration}sec)"
|
70
70
|
return false
|
71
71
|
end
|
@@ -79,12 +79,15 @@ module FFMPEG
|
|
79
79
|
|
80
80
|
private
|
81
81
|
def apply_transcoder_options
|
82
|
+
return if @movie.calculated_aspect_ratio.nil?
|
82
83
|
case @transcoder_options[:preserve_aspect_ratio].to_s
|
83
84
|
when "width"
|
84
|
-
new_height =
|
85
|
+
new_height = @raw_options.width / @movie.calculated_aspect_ratio
|
86
|
+
new_height = new_height.ceil.even? ? new_height.ceil : new_height.floor
|
85
87
|
@raw_options[:resolution] = "#{@raw_options.width}x#{new_height}"
|
86
88
|
when "height"
|
87
|
-
new_width =
|
89
|
+
new_width = @raw_options.height * @movie.calculated_aspect_ratio
|
90
|
+
new_width = new_width.ceil.even? ? new_width.ceil : new_width.floor
|
88
91
|
@raw_options[:resolution] = "#{new_width}x#{@raw_options.height}"
|
89
92
|
end
|
90
93
|
end
|
data/spec/ffmpeg/movie_spec.rb
CHANGED
@@ -19,12 +19,40 @@ module FFMPEG
|
|
19
19
|
@movie.should_not be_valid
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
describe "given a mp3 file" do
|
24
|
+
before(:all) do
|
25
|
+
@movie = Movie.new("#{fixture_path}/sounds/napoleon.mp3")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have uncertain duration" do
|
29
|
+
@movie.should be_uncertain_duration
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "a broken mp4 file" do
|
34
|
+
before(:all) do
|
35
|
+
@movie = Movie.new("#{fixture_path}/movies/broken.mp4")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not be valid" do
|
39
|
+
@movie.should_not be_valid
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have nil calculated_aspect_ratio" do
|
43
|
+
@movie.calculated_aspect_ratio.should be_nil
|
44
|
+
end
|
45
|
+
end
|
22
46
|
|
23
47
|
describe "given an awesome movie file" do
|
24
48
|
before(:all) do
|
25
49
|
@movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
|
26
50
|
end
|
27
51
|
|
52
|
+
it "should not have uncertain duration" do
|
53
|
+
@movie.should_not be_uncertain_duration
|
54
|
+
end
|
55
|
+
|
28
56
|
it "should remember the movie path" do
|
29
57
|
@movie.path.should == "#{fixture_path}/movies/awesome movie.mov"
|
30
58
|
end
|
@@ -79,6 +79,22 @@ module FFMPEG
|
|
79
79
|
encoded = Transcoder.new(@movie, "#{tmp_path}/preserved_aspect.mp4", @options, special_options).run
|
80
80
|
encoded.resolution.should == "426x240"
|
81
81
|
end
|
82
|
+
|
83
|
+
it "should not be used if original resolution is undeterminable" do
|
84
|
+
@movie.should_receive(:calculated_aspect_ratio).and_return(nil)
|
85
|
+
special_options = {:preserve_aspect_ratio => :height}
|
86
|
+
|
87
|
+
encoded = Transcoder.new(@movie, "#{tmp_path}/preserved_aspect.mp4", @options, special_options).run
|
88
|
+
encoded.resolution.should == "320x240"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should round to resolutions divisible by 2" do
|
92
|
+
@movie.should_receive(:calculated_aspect_ratio).at_least(:once).and_return(1.234)
|
93
|
+
special_options = {:preserve_aspect_ratio => :width}
|
94
|
+
|
95
|
+
encoded = Transcoder.new(@movie, "#{tmp_path}/preserved_aspect.mp4", @options, special_options).run
|
96
|
+
encoded.resolution.should == "320x260" # 320 / 1.234 should at first be rounded to 259
|
97
|
+
end
|
82
98
|
end
|
83
99
|
|
84
100
|
it "should transcode the movie with String options" do
|
@@ -97,6 +113,22 @@ module FFMPEG
|
|
97
113
|
transcoder = Transcoder.new(movie, "#{tmp_path}/fail.flv")
|
98
114
|
lambda { transcoder.run }.should raise_error(RuntimeError, /no output file created/)
|
99
115
|
end
|
116
|
+
|
117
|
+
it "should fail if duration differs from original" do
|
118
|
+
movie = Movie.new("#{fixture_path}/sounds/napoleon.mp3")
|
119
|
+
movie.stub!(:duration).and_return(200)
|
120
|
+
movie.stub!(:uncertain_duration?).and_return(false)
|
121
|
+
transcoder = Transcoder.new(movie, "#{tmp_path}/duration_fail.flv")
|
122
|
+
lambda { transcoder.run }.should raise_error(RuntimeError, /encoded file duration differed from original/)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should skip duration check if originals duration is uncertain" do
|
126
|
+
movie = Movie.new("#{fixture_path}/sounds/napoleon.mp3")
|
127
|
+
movie.stub!(:duration).and_return(200)
|
128
|
+
movie.stub!(:uncertain_duration?).and_return(true)
|
129
|
+
transcoder = Transcoder.new(movie, "#{tmp_path}/duration_fail.flv")
|
130
|
+
lambda { transcoder.run }.should_not raise_error(RuntimeError)
|
131
|
+
end
|
100
132
|
end
|
101
133
|
end
|
102
134
|
end
|
Binary file
|
Binary file
|
data/streamio-ffmpeg.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{streamio-ffmpeg}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["David Backeus"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-05}
|
13
13
|
s.description = %q{Simple wrapper around ffmpeg to get metadata from movies and do transcoding}
|
14
14
|
s.email = %q{duztdruid@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -33,6 +33,8 @@ Gem::Specification.new do |s|
|
|
33
33
|
"spec/ffmpeg/transcoder_spec.rb",
|
34
34
|
"spec/fixtures/movies/awesome movie.mov",
|
35
35
|
"spec/fixtures/movies/awesome_widescreen.mov",
|
36
|
+
"spec/fixtures/movies/broken.mp4",
|
37
|
+
"spec/fixtures/sounds/napoleon.mp3",
|
36
38
|
"spec/spec.opts",
|
37
39
|
"spec/spec_helper.rb",
|
38
40
|
"spec/stremio-ffmpeg_spec.rb",
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
8
|
+
- 2
|
9
|
+
version: 0.6.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Backeus
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-05 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -57,6 +57,8 @@ files:
|
|
57
57
|
- spec/ffmpeg/transcoder_spec.rb
|
58
58
|
- spec/fixtures/movies/awesome movie.mov
|
59
59
|
- spec/fixtures/movies/awesome_widescreen.mov
|
60
|
+
- spec/fixtures/movies/broken.mp4
|
61
|
+
- spec/fixtures/sounds/napoleon.mp3
|
60
62
|
- spec/spec.opts
|
61
63
|
- spec/spec_helper.rb
|
62
64
|
- spec/stremio-ffmpeg_spec.rb
|