streamio-ffmpeg 0.5.0 → 0.6.0

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/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