vtranscoder 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.markdown +85 -0
- data/VERSION +1 -1
- data/lib/vtranscoder.rb +71 -6
- data/vtranscoder.gemspec +50 -0
- metadata +4 -3
- data/README.rdoc +0 -18
data/README.markdown
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# vtranscoder
|
2
|
+
|
3
|
+
VTranscoder is a collection of utility methods for transcoding and 'publishing' videos with FFMPEG. The goal of this project is to make transcoding video to web formats like FLV and commonly associated tasks easier.
|
4
|
+
|
5
|
+
VTanscoder also provides connivence methods for taking screenshots, uploading to S3/CloudFront etc.
|
6
|
+
|
7
|
+
## Dependencies
|
8
|
+
|
9
|
+
You'll need FFMPEG and libmp3lame (if you want to use the default MP3 conversion options).
|
10
|
+
|
11
|
+
If you're on Mac OSX:
|
12
|
+
|
13
|
+
sudo port install ffmpeg
|
14
|
+
|
15
|
+
If you're on Fedora:
|
16
|
+
|
17
|
+
yum install ffmpeg
|
18
|
+
|
19
|
+
For Ubuntu:
|
20
|
+
|
21
|
+
apt-get install ffmpeg
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Installation is really simple--thanks Gemcutter!
|
26
|
+
|
27
|
+
gem install vtranscoder
|
28
|
+
|
29
|
+
## Getting Started
|
30
|
+
|
31
|
+
Consider this block of code:
|
32
|
+
|
33
|
+
require 'rubygems'
|
34
|
+
require 'vtranscoder'
|
35
|
+
|
36
|
+
# open a video
|
37
|
+
@video = VTranscoder.new('/path/to/some/video.avi')
|
38
|
+
|
39
|
+
# how big is the file?
|
40
|
+
puts "File size: #{@video.meta[:size]}"
|
41
|
+
|
42
|
+
# print more information
|
43
|
+
puts "Meta data: #{@video.meta.inspect}"
|
44
|
+
puts "Duration (seconds): #{@video.duration_in_seconds}"
|
45
|
+
|
46
|
+
# take five equally spaced out screenshots
|
47
|
+
5.times do |i|
|
48
|
+
@video.take_screenshot :at => (@video.duration_in_seconds/5)*i, :to => "screenshot_#{i}.jpg"
|
49
|
+
end
|
50
|
+
|
51
|
+
# create Flash video from it
|
52
|
+
@video.convert 'video-transcoded.flv'
|
53
|
+
|
54
|
+
## Advanced Usage
|
55
|
+
|
56
|
+
Should you need to pass your own options to the FFMPEG command-line binary, most methods (with the exception of *convert*) take an optional _options_ hash, which is structured as such:
|
57
|
+
|
58
|
+
some_ffmpeg_options_hash = {
|
59
|
+
:i => @source,
|
60
|
+
:y => '',
|
61
|
+
...
|
62
|
+
}
|
63
|
+
|
64
|
+
(Notice how the "-y" flag is represented by an empty string.)
|
65
|
+
|
66
|
+
You can use *convert_with_options* to start conversion with your own options hash:
|
67
|
+
|
68
|
+
@video.convert_with_options('outfile.mpg',{
|
69
|
+
:b => "200"
|
70
|
+
})
|
71
|
+
|
72
|
+
The default options for FLV conversion used with *convert* are:
|
73
|
+
|
74
|
+
FFMPEG_OPTIONS = {
|
75
|
+
:b => 800,
|
76
|
+
:r => 25,
|
77
|
+
:vcodec => 'flv',
|
78
|
+
:acodec => 'libmp3lame',
|
79
|
+
:ab => 128,
|
80
|
+
:ar => 44100
|
81
|
+
}
|
82
|
+
|
83
|
+
## Copyright
|
84
|
+
|
85
|
+
Copyright (c) 2009 Chris Bielinski. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/vtranscoder.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
# VTranscoder is a utility/convienece class for transcoding video. More specificially it provides any easy-to-use
|
2
|
+
# interface for FFMPEG which VTranscoder depends on. Zero-configuration default options are provided for converting
|
3
|
+
# video to Flash (FLV) format, commonly used for delivering web video.
|
4
|
+
#
|
5
|
+
# Feel free to contribute because I'm no expert on FFMPEG or it's complex configuration options.
|
6
|
+
#
|
7
|
+
# @author Chris Bielinski <chris@shadowreactor.com>
|
8
|
+
#
|
1
9
|
class VTranscoder
|
2
10
|
|
3
|
-
attr_accessor :source
|
11
|
+
attr_accessor :source, :meta
|
4
12
|
|
5
13
|
FFMPEG_OPTIONS = {
|
6
14
|
:b => 800,
|
@@ -17,7 +25,58 @@ class VTranscoder
|
|
17
25
|
|
18
26
|
def initialize(source)
|
19
27
|
@source = source
|
28
|
+
@meta = {}
|
29
|
+
get_video_information
|
30
|
+
end
|
31
|
+
|
32
|
+
def duration_in_seconds
|
33
|
+
# 00:21:41.18
|
34
|
+
( $1.to_i * 60 * 60 ) + ( $2.to_i * 60 ) + ( $3.to_i ) + ( ($4.to_i/100) * 60 ) if @meta[:duration] =~ /([0-9][0-9])\:([0-9][0-9])\:([0-9][0-9])\.([0-9][0-9])/
|
35
|
+
end
|
36
|
+
|
37
|
+
# options[:at] => number of seconds into video to take the screenshot
|
38
|
+
# options[:size] => desired pixel dimensions of screenshot (default is '320*240')
|
39
|
+
# options[:to] => path to destination image (/path/to/some/image.jpg)
|
40
|
+
def take_screenshot(options)
|
41
|
+
verify_ffmpeg_exists
|
42
|
+
verify_source_exists
|
43
|
+
options = { :size => '320*240' }.merge(options)
|
44
|
+
|
45
|
+
ffmpeg_options = {
|
46
|
+
:i => @source,
|
47
|
+
:y => '',
|
48
|
+
:ss => options[:at],
|
49
|
+
:sameq => '',
|
50
|
+
:t => '0.001',
|
51
|
+
:s => options[:size]
|
52
|
+
}
|
53
|
+
|
54
|
+
output = run_ffmpeg( ffmpeg_options, options[:to], true )
|
55
|
+
raise "unable to take screenshot:\n\n#{output}" unless File.exists?(options[:to])
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_video_information
|
59
|
+
verify_ffmpeg_exists
|
20
60
|
verify_source_exists
|
61
|
+
|
62
|
+
# Sample FFMPEG output
|
63
|
+
#
|
64
|
+
# Input #0, avi, from 'video.filename.avi':
|
65
|
+
# Duration: 00:21:41.18, start: 0.000000, bitrate: 1126 kb/s
|
66
|
+
# Stream #0.0: Video: mpeg4, yuv420p, 624x352 [PAR 1:1 DAR 39:22], 23.98 tbr, 23.98 tbn, 23.98 tbc
|
67
|
+
# Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s
|
68
|
+
|
69
|
+
ffmpeg_output = `ffmpeg -i #{@source} 2>&1` # we know we're going to get an error but we want to capture
|
70
|
+
# the output anyways, so 2>&1 routes STDERR to STDOUT
|
71
|
+
|
72
|
+
@meta[:size] = File.size(@source)
|
73
|
+
@meta[:duration] = $1 if ffmpeg_output =~ /Duration\: ([0-9][0-9]\:[0-9][0-9]\:[0-9][0-9]\.[0-9][0-9])\,/
|
74
|
+
@meta[:bitrate] = $1 if ffmpeg_output =~ /\, bitrate\: (.*)$/
|
75
|
+
|
76
|
+
@meta[:streams] = []
|
77
|
+
ffmpeg_output.scan(/Stream #0.([0-9]): (.*): (.*), (.*)/).each do |match|
|
78
|
+
@meta[:streams][match[0].to_i] = { :type => match[1], :codec => match[2], :details => match[3] }
|
79
|
+
end
|
21
80
|
end
|
22
81
|
|
23
82
|
def convert_with_options(destination,options)
|
@@ -29,19 +88,25 @@ class VTranscoder
|
|
29
88
|
convert_with_options destination, FFMPEG_OPTIONS
|
30
89
|
end
|
31
90
|
|
91
|
+
def file
|
92
|
+
verify_source_exists
|
93
|
+
File.open(@source)
|
94
|
+
end
|
95
|
+
|
32
96
|
protected
|
33
97
|
|
34
|
-
def run(command,parameters)
|
35
|
-
actual_command = "#{command} #{parameters}"
|
98
|
+
def run(command,parameters,reroute_output=false)
|
99
|
+
actual_command = "#{command} #{parameters}#{' 2>&1' if reroute_output}"
|
100
|
+
puts " ===> #{actual_command}"
|
36
101
|
`#{actual_command}`
|
37
102
|
end
|
38
103
|
|
39
|
-
def run_ffmpeg(options,outputfile)
|
40
|
-
run('ffmpeg',"#{command_params options.merge({ :i => @source})} #{outputfile}")
|
104
|
+
def run_ffmpeg(options,outputfile,reroute_output=false)
|
105
|
+
run('ffmpeg',"#{command_params options.merge({ :i => @source})} #{outputfile}",reroute_output)
|
41
106
|
end
|
42
107
|
|
43
108
|
def command_params(hsh)
|
44
|
-
hsh.each_key.map { |key| "-#{key.to_s}
|
109
|
+
hsh.each_key.map { |key| "-#{key.to_s}#{ hsh[key].to_s == '' ? '' : ' '+hsh[key].to_s }" }.join(' ')
|
45
110
|
end
|
46
111
|
|
47
112
|
def verify_source_exists
|
data/vtranscoder.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{vtranscoder}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Chris Bielinski"]
|
12
|
+
s.date = %q{2009-10-18}
|
13
|
+
s.description = %q{VTranscoder is a collection of utility methods for transcoding and 'publishing' videos, with the intent to make transcoding video to web formats like FLV easier. VTanscoder also provides convience methods for taking screenshots, uploading to S3/CloudFront etc.}
|
14
|
+
s.email = %q{chris@shadowreactor.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.markdown",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/vtranscoder.rb",
|
27
|
+
"test/test_helper.rb",
|
28
|
+
"test/vtranscoder_test.rb",
|
29
|
+
"vtranscoder.gemspec"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/chrisb/vtranscoder}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.5}
|
35
|
+
s.summary = %q{Provides a simple, zero-configuration front end to encoding videos with FFMPEG.}
|
36
|
+
s.test_files = [
|
37
|
+
"test/test_helper.rb",
|
38
|
+
"test/vtranscoder_test.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
|
+
else
|
47
|
+
end
|
48
|
+
else
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vtranscoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Bielinski
|
@@ -21,17 +21,18 @@ extensions: []
|
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- LICENSE
|
24
|
-
- README.
|
24
|
+
- README.markdown
|
25
25
|
files:
|
26
26
|
- .document
|
27
27
|
- .gitignore
|
28
28
|
- LICENSE
|
29
|
-
- README.
|
29
|
+
- README.markdown
|
30
30
|
- Rakefile
|
31
31
|
- VERSION
|
32
32
|
- lib/vtranscoder.rb
|
33
33
|
- test/test_helper.rb
|
34
34
|
- test/vtranscoder_test.rb
|
35
|
+
- vtranscoder.gemspec
|
35
36
|
has_rdoc: true
|
36
37
|
homepage: http://github.com/chrisb/vtranscoder
|
37
38
|
licenses: []
|
data/README.rdoc
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
= vtranscoder
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but
|
13
|
-
bump version in a commit by itself I can ignore when I pull)
|
14
|
-
* Send me a pull request. Bonus points for topic branches.
|
15
|
-
|
16
|
-
== Copyright
|
17
|
-
|
18
|
-
Copyright (c) 2009 Chris Bielinski. See LICENSE for details.
|