streamio-ffmpeg 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.6.0 2010-05-04
2
+
3
+ * Cropping options now handled by EncodingOptions (croptop, cropbottom, cropleft and cropright)
4
+ * Aspect ratio parameter calculated and added by default
5
+ * Added transcoder options to preserve original aspect ratio on width or height
6
+
1
7
  == 0.5.0 2010-04-28
2
8
 
3
9
  * Added logging capabilities
data/README.rdoc CHANGED
@@ -48,7 +48,8 @@ Give custom command line options with a string.
48
48
 
49
49
  Use the EncodingOptions parser for humanly readable transcoding options. Below you'll find all the supported options. Note that the :custom key will be used as is without modification so use it for any tricky business you might need.
50
50
 
51
- options = {:video_codec => "libx264", :frame_rate => 10, :resolution => "320x240", :video_bitrate => 300,
51
+ options = {:video_codec => "libx264", :frame_rate => 10, :resolution => "320x240", :video_bitrate => 300,
52
+ :croptop => 60, :cropbottom => 60, :cropleft => 10, :cropright => 10, :aspect => 1.333333,
52
53
  :audio_codec => "libfaac", :audio_bitrate => 32, :audio_sample_rate => 22050, :audio_channels => 1,
53
54
  :custom => "-flags +loop -cmp +chroma -partitions +parti4x4+partp8x8 -flags2 +mixed_refs -me_method umh -subq 6 -refs 6 -rc_eq 'blurCplx^(1-qComp)' -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 21"}
54
55
  movie.transcode("movie.mp4", options)
@@ -59,6 +60,22 @@ The transcode function returns a Movie object for the encoded file.
59
60
 
60
61
  transcoded_movie.video_codec # "flv"
61
62
  transcoded_movie.audio_codec # "mp3"
63
+
64
+ Aspect ratio is added to encoding options automatically if none is specified.
65
+
66
+ options = {:resolution => 320x180} # Will add -aspect 1.77777777777778 to ffmpeg
67
+
68
+ Preserve aspect ratio on width or height by using the preserve_aspect_ratio transcoder option.
69
+
70
+ widescreen_movie = FFMPEG::Movie.new("path/to/widescreen_movie.mov")
71
+
72
+ options = {:resolution => 320x240}
73
+
74
+ transcoder_options = {:preserve_aspect_ratio => :width}
75
+ widescreen_movie.transcode("movie.mp4", options, transcoder_options) # Output resolution will be 320x180
76
+
77
+ transcoder_options = {:preserve_aspect_ratio => :height}
78
+ widescreen_movie.transcode("movie.mp4", options, transcoder_options) # Output resolution will be 426x240
62
79
 
63
80
  == Copyright
64
81
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -7,9 +7,19 @@ module FFMPEG
7
7
  end
8
8
 
9
9
  def to_s
10
- collect do |key, value|
10
+ parameters = collect do |key, value|
11
11
  send("convert_#{key}", value) if supports_option?(key)
12
12
  end.join(" ")
13
+ parameters << " #{convert_aspect(calculate_aspect)}" if calculate_aspect?
14
+ parameters
15
+ end
16
+
17
+ def width
18
+ self[:resolution].split("x").first.to_i rescue nil
19
+ end
20
+
21
+ def height
22
+ self[:resolution].split("x").last.to_i rescue nil
13
23
  end
14
24
 
15
25
  private
@@ -17,6 +27,35 @@ module FFMPEG
17
27
  private_methods.include?("convert_#{option}")
18
28
  end
19
29
 
30
+ def convert_aspect(value)
31
+ "-aspect #{value}"
32
+ end
33
+
34
+ def calculate_aspect
35
+ width, height = self[:resolution].split("x")
36
+ width.to_f / height.to_f
37
+ end
38
+
39
+ def calculate_aspect?
40
+ self[:aspect].nil? && self[:resolution]
41
+ end
42
+
43
+ def convert_croptop(value)
44
+ "-croptop #{value}"
45
+ end
46
+
47
+ def convert_cropbottom(value)
48
+ "-cropbottom #{value}"
49
+ end
50
+
51
+ def convert_cropleft(value)
52
+ "-cropleft #{value}"
53
+ end
54
+
55
+ def convert_cropright(value)
56
+ "-cropright #{value}"
57
+ end
58
+
20
59
  def convert_video_codec(value)
21
60
  "-vcodec #{value}"
22
61
  end
data/lib/ffmpeg/movie.rb CHANGED
@@ -49,6 +49,10 @@ module FFMPEG
49
49
  resolution.split("x")[1].to_i rescue nil
50
50
  end
51
51
 
52
+ def calculated_aspect_ratio
53
+ width.to_f / height.to_f
54
+ end
55
+
52
56
  def audio_channels
53
57
  return @audio_channels[/\d*/].to_i if @audio_channels["channels"]
54
58
  return 1 if @audio_channels["mono"]
@@ -59,8 +63,8 @@ module FFMPEG
59
63
  video_stream[/(\d*\.?\d*)\s?fps/] ? $1.to_f : nil
60
64
  end
61
65
 
62
- def transcode(output_file, options, &block)
63
- Transcoder.new(self, output_file, options).run &block
66
+ def transcode(output_file, options = EncodingOptions.new, transcoder_options = {}, &block)
67
+ Transcoder.new(self, output_file, options, transcoder_options).run &block
64
68
  end
65
69
 
66
70
  protected
@@ -2,7 +2,7 @@ require 'open3'
2
2
 
3
3
  module FFMPEG
4
4
  class Transcoder
5
- def initialize(movie, output_file, options = EncodingOptions.new)
5
+ def initialize(movie, output_file, options = EncodingOptions.new, transcoder_options = {})
6
6
  @movie = movie
7
7
  @output_file = output_file
8
8
 
@@ -14,7 +14,10 @@ module FFMPEG
14
14
  raise ArgumentError, "Unknown options format '#{options.class}', should be either EncodingOptions, Hash or String."
15
15
  end
16
16
 
17
+ @transcoder_options = transcoder_options
17
18
  @errors = []
19
+
20
+ apply_transcoder_options
18
21
  end
19
22
 
20
23
  def run
@@ -73,5 +76,17 @@ module FFMPEG
73
76
  def encoded
74
77
  @encoded ||= Movie.new(@output_file)
75
78
  end
79
+
80
+ private
81
+ def apply_transcoder_options
82
+ case @transcoder_options[:preserve_aspect_ratio].to_s
83
+ when "width"
84
+ new_height = (@raw_options.width / @movie.calculated_aspect_ratio).to_i
85
+ @raw_options[:resolution] = "#{@raw_options.width}x#{new_height}"
86
+ when "height"
87
+ new_width = (@raw_options.height * @movie.calculated_aspect_ratio).to_i
88
+ @raw_options[:resolution] = "#{new_width}x#{@raw_options.height}"
89
+ end
90
+ end
76
91
  end
77
92
  end
@@ -7,12 +7,39 @@ module FFMPEG
7
7
  EncodingOptions.new(:video_codec => "libx264").to_s.should == "-vcodec libx264"
8
8
  end
9
9
 
10
+ it "should convert cropping options" do
11
+ EncodingOptions.new(:croptop => 20).to_s.should == "-croptop 20"
12
+ EncodingOptions.new(:cropbottom => 20).to_s.should == "-cropbottom 20"
13
+ EncodingOptions.new(:cropleft => 20).to_s.should == "-cropleft 20"
14
+ EncodingOptions.new(:cropright => 20).to_s.should == "-cropright 20"
15
+ end
16
+
17
+ it "should know the width from the resolution or be nil" do
18
+ EncodingOptions.new(:resolution => "320x240").width.should == 320
19
+ EncodingOptions.new.width.should be_nil
20
+ end
21
+
22
+ it "should know the height from the resolution or be nil" do
23
+ EncodingOptions.new(:resolution => "320x240").height.should == 240
24
+ EncodingOptions.new.height.should be_nil
25
+ end
26
+
10
27
  it "should convert frame rate" do
11
28
  EncodingOptions.new(:frame_rate => 29.9).to_s.should == "-r 29.9"
12
29
  end
13
30
 
14
31
  it "should convert the resolution" do
15
- EncodingOptions.new(:resolution => "640x480").to_s.should == "-s 640x480"
32
+ EncodingOptions.new(:resolution => "640x480").to_s.should include("-s 640x480")
33
+ end
34
+
35
+ it "should add calculated aspect ratio" do
36
+ EncodingOptions.new(:resolution => "640x480").to_s.should include("-aspect 1.3333333")
37
+ EncodingOptions.new(:resolution => "640x360").to_s.should include("-aspect 1.77777777777778")
38
+ end
39
+
40
+ it "should use specified aspect ratio if given" do
41
+ EncodingOptions.new(:resolution => "640x480",
42
+ :aspect => 1.77777777777778).to_s.should == "-s 640x480 -aspect 1.77777777777778"
16
43
  end
17
44
 
18
45
  it "should convert video bitrate" do
@@ -81,6 +81,10 @@ module FFMPEG
81
81
  it "should should be valid" do
82
82
  @movie.should be_valid
83
83
  end
84
+
85
+ it "should calculate the aspect ratio" do
86
+ @movie.calculated_aspect_ratio.to_s.should == "1.33333333333333"
87
+ end
84
88
  end
85
89
  end
86
90
 
@@ -89,10 +93,10 @@ module FFMPEG
89
93
  movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
90
94
 
91
95
  mockery = mock(Transcoder)
92
- Transcoder.should_receive(:new).with(movie, "#{tmp_path}/awesome.flv", :custom => "-vcodec libx264").and_return(mockery)
96
+ Transcoder.should_receive(:new).with(movie, "#{tmp_path}/awesome.flv", {:custom => "-vcodec libx264"}, :preserve_aspect_ratio => :width).and_return(mockery)
93
97
  mockery.should_receive(:run)
94
98
 
95
- movie.transcode("#{tmp_path}/awesome.flv", :custom => "-vcodec libx264")
99
+ movie.transcode("#{tmp_path}/awesome.flv", {:custom => "-vcodec libx264"}, :preserve_aspect_ratio => :width)
96
100
  end
97
101
  end
98
102
  end
@@ -47,7 +47,7 @@ module FFMPEG
47
47
  FileUtils.rm_f "#{tmp_path}/optionalized.mp4"
48
48
 
49
49
  movie = Movie.new("#{fixture_path}/movies/awesome movie.mov")
50
- options = {:video_codec => "libx264", :frame_rate => 10, :resolution => "320x240", :video_bitrate => 300,
50
+ options = {:video_codec => "libx264", :frame_rate => 10, :resolution => "320x240", :video_bitrate => 300,
51
51
  :audio_codec => "libfaac", :audio_bitrate => 32, :audio_sample_rate => 22050, :audio_channels => 1,
52
52
  :custom => "-flags +loop -cmp +chroma -partitions +parti4x4+partp8x8 -flags2 +mixed_refs -me_method umh -subq 6 -refs 6 -rc_eq 'blurCplx^(1-qComp)' -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 21"}
53
53
 
@@ -60,6 +60,27 @@ module FFMPEG
60
60
  encoded.audio_channels.should == 1
61
61
  end
62
62
 
63
+ describe "aspect ratio preservation" do
64
+ before(:each) do
65
+ @movie = Movie.new("#{fixture_path}/movies/awesome_widescreen.mov")
66
+ @options = {:resolution => "320x240"}
67
+ end
68
+
69
+ it "should work on width" do
70
+ special_options = {:preserve_aspect_ratio => :width}
71
+
72
+ encoded = Transcoder.new(@movie, "#{tmp_path}/preserved_aspect.mp4", @options, special_options).run
73
+ encoded.resolution.should == "320x180"
74
+ end
75
+
76
+ it "should work on height" do
77
+ special_options = {:preserve_aspect_ratio => :height}
78
+
79
+ encoded = Transcoder.new(@movie, "#{tmp_path}/preserved_aspect.mp4", @options, special_options).run
80
+ encoded.resolution.should == "426x240"
81
+ end
82
+ end
83
+
63
84
  it "should transcode the movie with String options" do
64
85
  FileUtils.rm_f "#{tmp_path}/string_optionalized.flv"
65
86
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{streamio-ffmpeg}
8
- s.version = "0.5.0"
8
+ s.version = "0.6.0"
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-04-28}
12
+ s.date = %q{2010-05-04}
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 = [
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  "spec/ffmpeg/movie_spec.rb",
33
33
  "spec/ffmpeg/transcoder_spec.rb",
34
34
  "spec/fixtures/movies/awesome movie.mov",
35
+ "spec/fixtures/movies/awesome_widescreen.mov",
35
36
  "spec/spec.opts",
36
37
  "spec/spec_helper.rb",
37
38
  "spec/stremio-ffmpeg_spec.rb",
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
7
+ - 6
8
8
  - 0
9
- version: 0.5.0
9
+ version: 0.6.0
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-04-28 00:00:00 +02:00
17
+ date: 2010-05-04 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -56,6 +56,7 @@ files:
56
56
  - spec/ffmpeg/movie_spec.rb
57
57
  - spec/ffmpeg/transcoder_spec.rb
58
58
  - spec/fixtures/movies/awesome movie.mov
59
+ - spec/fixtures/movies/awesome_widescreen.mov
59
60
  - spec/spec.opts
60
61
  - spec/spec_helper.rb
61
62
  - spec/stremio-ffmpeg_spec.rb