vidibus-mp4_encoder 0.1.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 André Pankratz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Vidibus::Mp4Encoder
2
+
3
+ This is an encoder class for generating H.264 videos in a mp4 container.
4
+
5
+ This gem is part of [Vidibus](http://vidibus.org), an open source toolset for building distributed (video) applications.
6
+
7
+ **Beware:** Work in progress!
8
+
9
+
10
+ ## Notes
11
+
12
+ x264 FFmpeg Options Guide:
13
+ https://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping
14
+
15
+
16
+ ## Copyright
17
+
18
+ © 2012 André Pankratz See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ $:.unshift File.expand_path('../lib/', __FILE__)
2
+
3
+ require 'bundler'
4
+ require 'rdoc/task'
5
+ require 'rspec'
6
+ require 'rspec/core/rake_task'
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ RSpec::Core::RakeTask.new(:rcov) do |t|
11
+ t.pattern = 'spec/**/*_spec.rb'
12
+ t.rcov = true
13
+ t.rcov_opts = ['--exclude', '^spec,/gems/']
14
+ end
15
+
16
+ Rake::RDocTask.new do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Vidibus::Mp4Encoder'
19
+ rdoc.rdoc_files.include('README*')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ rdoc.options << '--charset=utf-8'
22
+ end
23
+
24
+ task :default => :rcov
@@ -0,0 +1,189 @@
1
+ module Vidibus
2
+ class Mp4Encoder < Vidibus::Encoder::Base
3
+ class ProfileError < Vidibus::Encoder::ProfileError; end
4
+
5
+ VERSION = '0.1.0'
6
+
7
+ DEFAULT_AUDIO_CODEC = 'aac'
8
+ DEFAULT_VIDEO_CODEC = 'h264'
9
+ DEFAULT_VIDEO_PROFILE = 'main'
10
+ DEFAULT_VIDEO_CODEC_LEVEL = '3.1'
11
+ DEFAULT_PRESETS = {
12
+ :baseline => 'coder=0 bf=0 flags2=-wpred-dct8x8',
13
+ :main => 'coder=1 flags=+loop cmp=+chroma partitions=+parti8x8+parti4x4+partp8x8+partb8x8 me_method=hex subq=7 i_qfactor=0.71 directpred=1 flags2=+wpred+fastpskip-dct8x8'
14
+ }
15
+
16
+ # Common profile settings.
17
+ def self.profile_presets
18
+ @profile_presets ||= begin
19
+ {
20
+ :p192 => {
21
+ :video_profile => 'baseline',
22
+ :constant_bit_rate => true,
23
+ :video_bit_rate => 90000,
24
+ :audio_bit_rate => 32000,
25
+ :audio_sample_rate => 32000,
26
+ :audio_channels => 1,
27
+ :width => 192,
28
+ :dimensions_modulus => 4,
29
+ :frame_rate => 10
30
+ },
31
+ :p480 => {
32
+ :video_profile => 'baseline',
33
+ :constant_bit_rate => true,
34
+ :video_bit_rate => 400000,
35
+ :audio_bit_rate => 32000,
36
+ :audio_sample_rate => 32000,
37
+ :audio_channels => 1,
38
+ :width => 480,
39
+ :dimensions_modulus => 4,
40
+ :frame_rate => [29.97, 25]
41
+ },
42
+ :t960 => {
43
+ :video_profile => 'baseline',
44
+ :constant_bit_rate => true,
45
+ :video_bit_rate => 1800000,
46
+ :audio_bit_rate => 96000,
47
+ :audio_sample_rate => 32000,
48
+ :width => 960,
49
+ :frame_rate => [29.97, 25]
50
+ },
51
+ :t1280 => {
52
+ :video_profile => 'baseline',
53
+ :video_bit_rate => 2800000,
54
+ :audio_bit_rate => 128000,
55
+ :audio_sample_rate => 32000,
56
+ :width => 1280,
57
+ :frame_rate => [29.97, 25]
58
+ },
59
+ :w620 => {
60
+ :video_bit_rate => 1000000,
61
+ :audio_bit_rate => 96000,
62
+ :audio_sample_rate => 48000,
63
+ :width => 620,
64
+ :dimensions_modulus => 4,
65
+ :frame_rate => [29.97, 25]
66
+ },
67
+ :w768 => {
68
+ :video_bit_rate => 1400000,
69
+ :audio_bit_rate => 128000,
70
+ :audio_sample_rate => 48000,
71
+ :width => 768,
72
+ :frame_rate => [29.97, 25]
73
+ },
74
+ :w1280 => {
75
+ :video_bit_rate => 2800000,
76
+ :audio_bit_rate => 192000,
77
+ :audio_sample_rate => 48000,
78
+ :width => 1280,
79
+ :frame_rate => [29.97, 25]
80
+ },
81
+ :w1920 => {
82
+ :video_bit_rate => 4500000,
83
+ :audio_bit_rate => 192000,
84
+ :audio_sample_rate => 48000,
85
+ :width => 1920,
86
+ :frame_rate => [29.97, 25]
87
+ }
88
+ }.tap do |p|
89
+ p[:default] = p[:w768]
90
+ end
91
+ end
92
+ end
93
+
94
+ def self.file_extension
95
+ 'mp4'
96
+ end
97
+
98
+ private
99
+
100
+ flag(:audio_bit_rate) { |value| "-ab #{value}" }
101
+ flag(:audio_channels) { |value| "-ac #{value}" }
102
+ flag(:audio_sample_rate) { |value| "-ar #{value}" }
103
+ flag(:aspect_ratio) { |value| "-aspect #{value}" }
104
+ flag(:video_profile) { |value| "-profile #{value}" }
105
+ flag(:video_codec_level) { |value| "-level #{value}" }
106
+
107
+ flag(:video_bit_rate) do |value|
108
+ output = "-b #{value} "
109
+ if profile.constant_bit_rate
110
+ output << " -vmaxrate #{value} -vbufsize #{value}"
111
+ end
112
+ output
113
+ end
114
+
115
+ # Set dimensions and aspect ratio to remove anamorphosis.
116
+ flag(:dimensions) do
117
+ modulus = profile.dimensions_modulus || 8
118
+ value = profile.dimensions(modulus)
119
+ "-s #{value} -aspect #{profile.aspect_ratio(modulus)}"
120
+ end
121
+
122
+ # Try to find a matching frame rate, if several ones are given. If no
123
+ # matching frame rate can be found, the first one will be used.
124
+ # Unless a gop duration is given, a keyframe will be set every 4 seconds.
125
+ flag(:frame_rate) do |value|
126
+ if value.is_a?(Array)
127
+ value = matching_frame_rate(value) || value.first
128
+ end
129
+ gop_duration = profile.try!(:gop_duration) || 4000
130
+ gop = gop_duration/1000*value
131
+ "-r #{value} -g #{gop} -keyint_min #{gop}"
132
+ end
133
+
134
+ # Convert the preset args
135
+ flag(:preset) do |value|
136
+ '-' + value.gsub(/\s+/, ' -').gsub(/\=/, ' ')
137
+ end
138
+
139
+ flag(:audio_codec) do |value|
140
+ if value == 'aac'
141
+ 'libfaac'
142
+ else
143
+ raise 'aac is the only audio codec supported right now'
144
+ end
145
+ end
146
+
147
+ flag(:video_codec) do |value|
148
+ if value == 'h264'
149
+ 'libx264'
150
+ else
151
+ raise 'h264 is the only video codec supported right now'
152
+ end
153
+ end
154
+
155
+ # Set default options for current profile:
156
+ #
157
+ # audio_codec: 'aac'
158
+ # video_codec: 'h264'
159
+ # video_profile: 'main'
160
+ # video_codec_level: '3.1'
161
+ # preset: [the :main present]
162
+ def preprocess
163
+ profile.settings[:audio_codec] ||= DEFAULT_AUDIO_CODEC
164
+ profile.settings[:video_codec] ||= DEFAULT_VIDEO_CODEC
165
+ profile.settings[:video_profile] ||= DEFAULT_VIDEO_PROFILE
166
+ profile.settings[:video_codec_level] ||= begin
167
+ profile.video_profile.to_s == 'baseline' ? '3.0': DEFAULT_VIDEO_CODEC_LEVEL
168
+ end
169
+ profile.settings[:preset] ||= DEFAULT_PRESETS[profile.video_profile.to_sym]
170
+ super
171
+ end
172
+
173
+ # Log encoding errors.
174
+ def handle_response(stdout, stderr)
175
+ stderr.each("\r") do |line|
176
+ if line =~ /error/i
177
+ logger.error("Encoder error:\n#{line}")
178
+ end
179
+ end
180
+ end
181
+
182
+ # The encoding recipe.
183
+ def recipe
184
+ audio = %(-acodec %{audio_codec} %{audio_sample_rate} %{audio_bit_rate} %{audio_channels} -async 2)
185
+ video = %(-vcodec %{video_codec} %{dimensions} %{video_bit_rate} %{frame_rate} %{video_profile} %{video_codec_level} %{preset})
186
+ "ffmpeg -i %{input} #{audio} #{video} -y -threads 0 %{output}"
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,5 @@
1
+ require 'vidibus-encoder'
2
+
3
+ require 'vidibus/mp4_encoder'
4
+
5
+ Vidibus::Encoder.register_format(:mp4, Vidibus::Mp4Encoder)
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vidibus-mp4_encoder
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - "Andr\xC3\xA9 Pankratz"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-20 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: vidibus-encoder
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 23
44
+ segments:
45
+ - 1
46
+ - 0
47
+ - 0
48
+ version: 1.0.0
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rake
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rdoc
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: rcov
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: rspec
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ hash: 7
102
+ segments:
103
+ - 2
104
+ version: "2"
105
+ type: :development
106
+ version_requirements: *id006
107
+ - !ruby/object:Gem::Dependency
108
+ name: rr
109
+ prerelease: false
110
+ requirement: &id007 !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ type: :development
120
+ version_requirements: *id007
121
+ description: MP4 (H.264) Encoder
122
+ email: andre@vidibus.com
123
+ executables: []
124
+
125
+ extensions: []
126
+
127
+ extra_rdoc_files: []
128
+
129
+ files:
130
+ - lib/vidibus/mp4_encoder.rb
131
+ - lib/vidibus-mp4_encoder.rb
132
+ - LICENSE
133
+ - README.md
134
+ - Rakefile
135
+ has_rdoc: true
136
+ homepage: https://github.com/vidibus/vidibus-mp4_encoder
137
+ licenses: []
138
+
139
+ post_install_message:
140
+ rdoc_options: []
141
+
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ hash: 3
150
+ segments:
151
+ - 0
152
+ version: "0"
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ hash: 23
159
+ segments:
160
+ - 1
161
+ - 3
162
+ - 6
163
+ version: 1.3.6
164
+ requirements: []
165
+
166
+ rubyforge_project: vidibus-mp4_encoder
167
+ rubygems_version: 1.3.7
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: MP4 (H.264) Encoder
171
+ test_files: []
172
+