mhs-rvideo 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,43 @@
1
+ == 0.9.4 2007-12-12
2
+
3
+ 3 major enhancements:
4
+ * Changed transcoder interface. The preferred interface is now to pass the input file to RVideo::Transcoder.new. This allows you to create multiple output files from the same Transcoder object, and inspects the input file metadata before the job is transcoded.
5
+ * Added screengrab functionality to the Inspector class. Fire up an inspector instance on a file, and you can take one or more screenshots through inspected_file.capture_frame("50%").
6
+ * Added resolution/aspect support. Pass :width and :height parameters to a Transcoder instance, and include $resolution$ or $aspect_ratio$ in the recipe.
7
+
8
+ 4 minor enhancements:
9
+ * Remove old/unnecessary files and features
10
+ * Three additional ffmpeg results: unsupported codec and no output streams
11
+ * One additional flvtool2 result: empty input file
12
+ * Check that input file exists earlier in the transcoding process
13
+
14
+ == 0.9.3 2007-10-30
15
+
16
+ One minor enhancement:
17
+ * Reraise all unhandled RVideo exceptions as TranscoderErrors
18
+
19
+ == 0.9.2 2007-10-30
20
+
21
+ One minor bug fix:
22
+ * Correctly parse invalid files, where duration and bitrate are N/A, but start: 0.000 is included
23
+
24
+ == 0.9.1 2007-10-11
25
+
26
+ One major enhancement:
27
+ * Added Mencoder support. (Andre Medeiros)
28
+
29
+ Two minor enhancements:
30
+ * Added total_time method to RVideo::Transcoder instances.
31
+ * Added another error condition for ffmpeg - codec not found.
32
+
33
+ Two notes:
34
+ * Tried and tested using open3 and open4 for command execution, but mencoder would unexpectedly hang with certain files when using these. Reverted these changes.
35
+ * Mencoder has basic unit tests, but needs more tests. In particular, example output should be added for a variety of cases (especially failures and errors).
36
+
37
+ == 0.9.0 2007-09-27
38
+
39
+ * Public RVideo release.
40
+
41
+ == 0.8.0 2007-09-27
42
+
43
+ * RVideo rewrite.
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Jonathan Dahl and Slantwise Design
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.txt ADDED
@@ -0,0 +1,91 @@
1
+ RVideo
2
+
3
+ RVideo allows you to inspect and process video files.
4
+
5
+
6
+ Installation is a little involved. First, install the gem:
7
+
8
+ sudo gem install rvideo
9
+
10
+ Next, install ffmpeg and (possibly) other related libraries. This is
11
+ documented elsewhere on the web, and can be a headache. If you are on OS X,
12
+ the Darwinports build is reasonably good (though not perfect). Install with:
13
+
14
+ sudo port install ffmpeg
15
+
16
+ Or, for a better build (recommended), add additional video- and audio-related
17
+ libraries, like this:
18
+
19
+ sudo port install ffmpeg +lame +libogg +vorbis +faac +faad +xvid +x264 +a52
20
+
21
+ Most package management systems include a build of ffmpeg, but many include a
22
+ poor build. So you may need to compile from scratch.
23
+
24
+ If you want to create Flash Video files, also install flvtool2:
25
+
26
+ sudo gem install flvtool2
27
+
28
+ Once ffmpeg and RVideo are installed, you're set.
29
+
30
+ To inspect a file, initialize an RVideo file inspector object. See the
31
+ documentation for details.
32
+
33
+ A few examples:
34
+
35
+ file = RVideo::Inspector.new(:file => "#{APP_ROOT}/files/input.mp4")
36
+
37
+ file = RVideo::Inspector.new(:raw_response => @existing_response)
38
+
39
+ file = RVideo::Inspector.new(:file => "#{APP_ROOT}/files/input.mp4",
40
+ :ffmpeg_binary => "#{APP_ROOT}/bin/ffmpeg")
41
+
42
+ file.fps # "29.97"
43
+ file.duration # "00:05:23.4"
44
+
45
+ To transcode a video, initialize a Transcoder object.
46
+
47
+ transcoder = RVideo::Transcoder.new
48
+
49
+ Then pass a command and valid options to the execute method
50
+
51
+ recipe = "ffmpeg -i $input_file$ -ar 22050 -ab 64 -f flv -r 29.97 -s"
52
+ recipe += " $resolution$ -y $output_file$"
53
+ recipe += "\nflvtool2 -U $output_file$"
54
+ begin
55
+ transcoder.execute(recipe, {:input_file => "/path/to/input.mp4",
56
+ :output_file => "/path/to/output.flv", :resolution => "640x360"})
57
+ rescue TranscoderError => e
58
+ puts "Unable to transcode file: #{e.class} - #{e.message}"
59
+ end
60
+
61
+ If the job succeeds, you can access the metadata of the input and output
62
+ files with:
63
+
64
+ transcoder.original # RVideo::Inspector object
65
+ transcoder.processed # RVideo::Inspector object
66
+
67
+ If the transcoding succeeds, the file may still have problems. RVideo
68
+ will populate an errors array if the duration of the processed video
69
+ differs from the duration of the original video, or if the processed
70
+ file is unreadable.
71
+
72
+ Thanks to Peter Boling for early work on RVideo.
73
+
74
+ Contribute to RVideo! If you want to help out, there are a few things you can
75
+ do.
76
+
77
+ - Use, test, and submit bugs/patches
78
+ - We need a RVideo::Tools::Mencoder class to add mencoder support.
79
+ - Other tool classes would be great - On2, mp4box, Quicktime (?), etc.
80
+ - Submit other fixes, features, optimizations, and refactorings
81
+
82
+ If RVideo is useful to you, you may also be interested in RMovie, another Ruby
83
+ video library. See http://rmovie.rubyforge.org/ for more.
84
+
85
+ Finally, watch for Spinoza, a commercial video transcoder built by Slantwise
86
+ Design. Spinoza uses RVideo for its video processing, but adds file queuing,
87
+ distributed transcoding, a web-based transcoder dashboard, and more. See
88
+ http://spinoza.tv or http://slantwisedesign.com for more.
89
+
90
+ Copyright (c) 2007 Jonathan Dahl and Slantwise Design. Released under the MIT
91
+ license.
data/RULES ADDED
@@ -0,0 +1,11 @@
1
+ Collection of transcoding edge cases and rules
2
+ ------------------------
3
+
4
+ * mpeg4 output errors out if frame rate is not supplied
5
+
6
+ [mpeg4 @ 0x149e810]timebase not supported by mpeg 4 standard
7
+ Error while opening codec for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height
8
+
9
+ Solution: provide a frame rate with -r (any frame rate will do)
10
+
11
+
data/Rakefile ADDED
@@ -0,0 +1,178 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ begin
12
+ require 'spec/rake/spectask'
13
+ rescue LoadError
14
+ puts 'To use rspec for testing you must install rspec gem:'
15
+ puts '$ sudo gem install rspec'
16
+ exit
17
+ end
18
+
19
+ include FileUtils
20
+ require File.join(File.dirname(__FILE__), 'lib', 'rvideo', 'version')
21
+
22
+ AUTHOR = 'Jonathan Dahl (Slantwise Design)' # can also be an array of Authors
23
+ EMAIL = "jon@slantwisedesign.com"
24
+ DESCRIPTION = "Inspect and process video or audio files."
25
+ GEM_NAME = 'mhs-rvideo' # what ppl will type to install your gem
26
+
27
+ @config_file = "~/.rubyforge/user-config.yml"
28
+ @config = nil
29
+ def rubyforge_username
30
+ unless @config
31
+ begin
32
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
33
+ rescue
34
+ puts <<-EOS
35
+ ERROR: No rubyforge config file found: #{@config_file}"
36
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
37
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
38
+ EOS
39
+ exit
40
+ end
41
+ end
42
+ @rubyforge_username ||= @config["username"]
43
+ end
44
+
45
+ RUBYFORGE_PROJECT = 'rvideo' # The unix name for your project
46
+ HOMEPATH = "http://github.com/mhs/rvideo"
47
+ DOWNLOAD_PATH = "http://github.com/mhs/rvideo"
48
+
49
+ NAME = "rvideo"
50
+ REV = nil
51
+ # UNCOMMENT IF REQUIRED:
52
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
53
+ VERS = Rvideo::VERSION::STRING + (REV ? ".#{REV}" : "")
54
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
55
+ RDOC_OPTS = ['--quiet', '--title', 'rvideo documentation',
56
+ "--opname", "index.html",
57
+ "--line-numbers",
58
+ "--main", "README",
59
+ "--inline-source"]
60
+
61
+ class Hoe
62
+ def extra_deps
63
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
64
+ end
65
+ end
66
+
67
+ # Generate all the Rake tasks
68
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
69
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
70
+ p.author = AUTHOR
71
+ p.description = DESCRIPTION
72
+ p.email = EMAIL
73
+ p.summary = DESCRIPTION
74
+ p.url = HOMEPATH
75
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
76
+ p.test_globs = ["test/**/test_*.rb"]
77
+ p.clean_globs |= CLEAN #An array of file patterns to delete on clean.
78
+
79
+ # == Optional
80
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
81
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
82
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
83
+ end
84
+
85
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\n\n")
86
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
87
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
88
+
89
+ desc 'Generate website files'
90
+ task :website_generate do
91
+ Dir['website/**/*.txt'].each do |txt|
92
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
93
+ end
94
+ end
95
+
96
+ desc 'Upload website files to rubyforge'
97
+ task :website_upload do
98
+ host = "#{rubyforge_username}@rubyforge.org"
99
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
100
+ local_dir = 'website'
101
+ sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
102
+ end
103
+
104
+ desc 'Generate and upload website files'
105
+ task :website => [:website_generate, :website_upload, :publish_docs]
106
+
107
+ desc 'Release the website and new gem version'
108
+ task :deploy => [:check_version, :website, :release] do
109
+ puts "Remember to create SVN tag:"
110
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
111
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
112
+ puts "Suggested comment:"
113
+ puts "Tagging release #{CHANGES}"
114
+ end
115
+
116
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
117
+ task :local_deploy => [:website_generate, :install_gem]
118
+
119
+ task :check_version do
120
+ unless ENV['VERSION']
121
+ puts 'Must pass a VERSION=x.y.z release version'
122
+ exit
123
+ end
124
+ unless ENV['VERSION'] == VERS
125
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
126
+ exit
127
+ end
128
+ end
129
+
130
+ #require 'rake'
131
+ #require 'spec/rake/spectask'
132
+ require File.dirname(__FILE__) + '/lib/rvideo'
133
+
134
+ namespace :spec do
135
+ desc "Run Unit Specs"
136
+ Spec::Rake::SpecTask.new("units") do |t|
137
+ t.spec_files = FileList['spec/units/**/*.rb']
138
+ end
139
+
140
+ desc "Run Integration Specs"
141
+ Spec::Rake::SpecTask.new("integrations") do |t|
142
+ t.spec_files = FileList['spec/integrations/**/*.rb']
143
+ end
144
+ end
145
+
146
+ desc "Process a file"
147
+ task(:transcode) do
148
+ RVideo::Transcoder.logger = Logger.new(STDOUT)
149
+ transcode_single_job(ENV['RECIPE'], ENV['FILE'])
150
+ end
151
+
152
+ desc "Batch transcode files"
153
+ task(:batch_transcode) do
154
+ RVideo::Transcoder.logger = Logger.new(File.dirname(__FILE__) + '/test/output.log')
155
+ f = YAML::load(File.open(File.dirname(__FILE__) + '/test/batch_transcode.yml'))
156
+ recipes = f['recipes']
157
+ files = f['files']
158
+ files.each do |f|
159
+ file = "#{File.dirname(__FILE__)}/test/files/#{f}"
160
+ recipes.each do |recipe|
161
+ transcode_single_job(recipe, file)
162
+ end
163
+ end
164
+ end
165
+
166
+ def transcode_single_job(recipe, input_file)
167
+ puts "Transcoding #{File.basename(input_file)} to #{recipe}"
168
+ r = YAML::load(File.open(File.dirname(__FILE__) + '/test/recipes.yml'))[recipe]
169
+ transcoder = RVideo::Transcoder.new(input_file)
170
+ output_file = "#{TEMP_PATH}/#{File.basename(input_file, ".*")}-#{recipe}.#{r['extension']}"
171
+ FileUtils.mkdir_p(File.dirname(output_file))
172
+ begin
173
+ transcoder.execute(r['command'], {:output_file => output_file}.merge(r))
174
+ puts "Finished #{File.basename(output_file)} in #{transcoder.total_time}"
175
+ rescue StandardError => e
176
+ puts "Error transcoding #{File.basename(output_file)} - #{e.class} (#{e.message}\n#{e.backtrace})"
177
+ end
178
+ end
@@ -0,0 +1,24 @@
1
+ module RVideo
2
+ class TranscoderError < RuntimeError
3
+ class InvalidCommand < TranscoderError
4
+ end
5
+
6
+ class InvalidFile < TranscoderError
7
+ end
8
+
9
+ class InputFileNotFound < TranscoderError
10
+ end
11
+
12
+ class UnexpectedResult < TranscoderError
13
+ end
14
+
15
+ class ParameterError < TranscoderError
16
+ end
17
+
18
+ class UnknownError < TranscoderError
19
+ end
20
+
21
+ class UnknownTool < TranscoderError
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ # Add a rounding method to the Float class.
2
+ class Float
3
+ def round_to(x)
4
+ (self * 10**x).round.to_f / 10**x
5
+ end
6
+ end
7
+