streamio-ffmpeg 1.0.0 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG +16 -0
- data/README.md +30 -4
- data/lib/ffmpeg/encoding_options.rb +34 -3
- data/lib/ffmpeg/movie.rb +101 -48
- data/lib/ffmpeg/transcoder.rb +2 -2
- data/lib/ffmpeg/version.rb +1 -1
- data/lib/streamio-ffmpeg.rb +43 -1
- metadata +29 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f7d05b3e4d5f1e43f04cea131e8f5f7e3772dec
|
4
|
+
data.tar.gz: 645f8fcfd8691bb62c27e4182374316512b78de9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ec0c612684983472f87288d1f8216c1762969ab4271f53a092d5e34141d975ec3121e9f54667467fc5e11364517d54fef17a9d858c04b1c042c8494b0b727b6
|
7
|
+
data.tar.gz: f362e03fcc8c05558e46cda6b6f4ab62ab3b9aadb5f67e030806403a29f6ffca3a0d5e58dc6f1dea175005e42094f20e2a1a7fc4fcfde136d1ecc17b7ac332b9
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== Master
|
2
|
+
|
3
|
+
Current with 2.0.0
|
4
|
+
|
5
|
+
== 2.0.0 2016-01-14
|
6
|
+
|
7
|
+
New:
|
8
|
+
* Support watermarking (thanks smoothdvd)
|
9
|
+
* Bumped target ffmpeg version to 2.8
|
10
|
+
|
11
|
+
Improvements:
|
12
|
+
* Allow parenthesis in colorspace (thanks walterdavis for initial code and rociiu for finding a bug with it)
|
13
|
+
* Width and height now switched if video is filmed in portrait mode. ffmpeg 2.7 or later now automatically rotates output
|
14
|
+
* Movie metadata now provided with ffprobe (#114). Thanks to Ryan Lovelett for the contributions!
|
15
|
+
* Ability to create multiple screenshots at consistent intervals in one pass (#113)
|
16
|
+
|
1
17
|
== 1.0.0 2013-07-08
|
2
18
|
|
3
19
|
New:
|
data/README.md
CHANGED
@@ -23,7 +23,9 @@ Will not work in jruby until they fix: http://goo.gl/Z4UcX (should work in the u
|
|
23
23
|
|
24
24
|
### ffmpeg
|
25
25
|
|
26
|
-
The current gem is tested against ffmpeg
|
26
|
+
The current gem is tested against ffmpeg 2.8.4. So no guarantees with earlier (or much later)
|
27
|
+
versions. Output and input standards have inconveniently changed rather a lot between versions
|
28
|
+
of ffmpeg. My goal is to keep this library in sync with new versions of ffmpeg as they come along.
|
27
29
|
|
28
30
|
Usage
|
29
31
|
-----
|
@@ -85,7 +87,7 @@ Use the EncodingOptions parser for humanly readable transcoding options. Below y
|
|
85
87
|
``` ruby
|
86
88
|
options = {video_codec: "libx264", frame_rate: 10, resolution: "320x240", video_bitrate: 300, video_bitrate_tolerance: 100,
|
87
89
|
aspect: 1.333333, keyframe_interval: 90,
|
88
|
-
|
90
|
+
x264_vprofile: "high", x264_preset: "slow",
|
89
91
|
audio_codec: "libfaac", audio_bitrate: 32, audio_sample_rate: 22050, audio_channels: 1,
|
90
92
|
threads: 2,
|
91
93
|
custom: "-vf crop=60:60:10:10"}
|
@@ -128,6 +130,16 @@ options = {video_min_bitrate: 600, video_max_bitrate: 600, buffer_size: 2000}
|
|
128
130
|
movie.transcode("movie.flv", options)
|
129
131
|
```
|
130
132
|
|
133
|
+
Add watermark image on the video.
|
134
|
+
|
135
|
+
For example, you want to add a watermark on the video at right top corner with 10px padding.
|
136
|
+
|
137
|
+
``` ruby
|
138
|
+
options = { watermark: "full_path_of_watermark.png", resolution: "640x360", watermark_filter: { position: "RT", padding_x: 10, padding_y: 10 } }
|
139
|
+
```
|
140
|
+
|
141
|
+
Position can be "LT" (Left Top Corner), "RT" (Right Top Corner), "LB" (Left Bottom Corner), "RB" (Right Bottom Corner).
|
142
|
+
|
131
143
|
### Taking Screenshots
|
132
144
|
|
133
145
|
You can use the screenshot method to make taking screenshots a bit simpler.
|
@@ -142,6 +154,20 @@ The screenshot method has the very same API as transcode so the same options wil
|
|
142
154
|
movie.screenshot("screenshot.bmp", seek_time: 5, resolution: '320x240')
|
143
155
|
```
|
144
156
|
|
157
|
+
To generate multiple screenshots in a single pass, specify `vframes`. The following code
|
158
|
+
generates up to 20 screenshots every 10 seconds:
|
159
|
+
|
160
|
+
``` ruby
|
161
|
+
movie.screenshot("screenshot.jpg", vframes: 20, frame_rate: '1/6')
|
162
|
+
```
|
163
|
+
|
164
|
+
To specify the quality when generating compressed screenshots (.jpg), use `quality` which specifies
|
165
|
+
ffmpeg `-v:q` option. Quality is an integer between 1 and 31, where lower is better quality:
|
166
|
+
|
167
|
+
``` ruby
|
168
|
+
movie.screenshot("screenshot.jpg", quality: 3)
|
169
|
+
```
|
170
|
+
|
145
171
|
You can preserve aspect ratio the same way as when using transcode.
|
146
172
|
|
147
173
|
``` ruby
|
@@ -151,7 +177,7 @@ movie.screenshot("screenshot.png", { seek_time: 2, resolution: '200x120' }, pres
|
|
151
177
|
Specify the path to ffmpeg
|
152
178
|
--------------------------
|
153
179
|
|
154
|
-
By default,
|
180
|
+
By default, the gem assumes that the ffmpeg binary is available in the execution path and named ffmpeg and so will run commands that look something like "ffmpeg -i /path/to/input.file ...". Use the FFMPEG.ffmpeg_binary setter to specify the full path to the binary if necessary:
|
155
181
|
|
156
182
|
``` ruby
|
157
183
|
FFMPEG.ffmpeg_binary = '/usr/local/bin/ffmpeg'
|
@@ -163,7 +189,7 @@ This will cause the same command to run as "/usr/local/bin/ffmpeg -i /path/to/in
|
|
163
189
|
Automatically kill hung processes
|
164
190
|
---------------------------------
|
165
191
|
|
166
|
-
By default,
|
192
|
+
By default, the gem will wait for 30 seconds between IO feedback from the FFMPEG process. After which an error is logged and the process killed.
|
167
193
|
It is possible to modify this behaviour by setting a new default:
|
168
194
|
|
169
195
|
``` ruby
|
@@ -13,8 +13,9 @@ module FFMPEG
|
|
13
13
|
# all other parameters go after so that we can override whatever is in the preset
|
14
14
|
codecs = params.select { |p| p =~ /codec/ }
|
15
15
|
presets = params.select { |p| p =~ /\-.pre/ }
|
16
|
-
|
17
|
-
|
16
|
+
watermarkoptions = params.select { |p| p =~ /i / || p=~ /filter_complex/ }
|
17
|
+
other = params - codecs - presets - watermarkoptions
|
18
|
+
params = watermarkoptions + codecs + presets + other
|
18
19
|
|
19
20
|
params_string = params.join(" ")
|
20
21
|
params_string << " #{convert_aspect(calculate_aspect)}" if calculate_aspect?
|
@@ -100,6 +101,10 @@ module FFMPEG
|
|
100
101
|
"-threads #{value}"
|
101
102
|
end
|
102
103
|
|
104
|
+
def convert_target(value)
|
105
|
+
"-target #{value}"
|
106
|
+
end
|
107
|
+
|
103
108
|
def convert_duration(value)
|
104
109
|
"-t #{value}"
|
105
110
|
end
|
@@ -125,7 +130,16 @@ module FFMPEG
|
|
125
130
|
end
|
126
131
|
|
127
132
|
def convert_screenshot(value)
|
128
|
-
|
133
|
+
vframes = '-vframes 1 ' unless self[:vframes]
|
134
|
+
value ? "#{vframes}-f image2" : ""
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_quality(value)
|
138
|
+
"-q:v #{value}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def convert_vframes(value)
|
142
|
+
"-vframes #{value}"
|
129
143
|
end
|
130
144
|
|
131
145
|
def convert_x264_vprofile(value)
|
@@ -136,6 +150,23 @@ module FFMPEG
|
|
136
150
|
"-preset #{value}"
|
137
151
|
end
|
138
152
|
|
153
|
+
def convert_watermark(value)
|
154
|
+
"-i #{value}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def convert_watermark_filter(value)
|
158
|
+
case value[:position].to_s
|
159
|
+
when "LT"
|
160
|
+
"-filter_complex 'scale=#{self[:resolution]},overlay=x=#{value[:padding_x]}:y=#{value[:padding_y]}'"
|
161
|
+
when "RT"
|
162
|
+
"-filter_complex 'scale=#{self[:resolution]},overlay=x=main_w-overlay_w-#{value[:padding_x]}:y=#{value[:padding_y]}'"
|
163
|
+
when "LB"
|
164
|
+
"-filter_complex 'scale=#{self[:resolution]},overlay=x=#{value[:padding_x]}:y=main_h-overlay_h-#{value[:padding_y]}'"
|
165
|
+
when "RB"
|
166
|
+
"-filter_complex 'scale=#{self[:resolution]},overlay=x=main_w-overlay_w-#{value[:padding_x]}:y=main_h-overlay_h-#{value[:padding_y]}'"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
139
170
|
def convert_custom(value)
|
140
171
|
value
|
141
172
|
end
|
data/lib/ffmpeg/movie.rb
CHANGED
@@ -1,63 +1,98 @@
|
|
1
1
|
require 'time'
|
2
|
+
require 'multi_json'
|
2
3
|
|
3
4
|
module FFMPEG
|
4
5
|
class Movie
|
5
6
|
attr_reader :path, :duration, :time, :bitrate, :rotation, :creation_time
|
6
|
-
attr_reader :video_stream, :video_codec, :video_bitrate, :colorspace, :
|
7
|
-
attr_reader :audio_stream, :audio_codec, :audio_bitrate, :audio_sample_rate
|
7
|
+
attr_reader :video_stream, :video_codec, :video_bitrate, :colorspace, :width, :height, :sar, :dar, :frame_rate
|
8
|
+
attr_reader :audio_stream, :audio_codec, :audio_bitrate, :audio_sample_rate, :audio_channels
|
8
9
|
attr_reader :container
|
9
10
|
|
10
11
|
def initialize(path)
|
11
|
-
raise Errno::ENOENT, "the file '#{path}' does not exist" unless File.
|
12
|
+
raise Errno::ENOENT, "the file '#{path}' does not exist" unless File.exist?(path)
|
12
13
|
|
13
14
|
@path = path
|
14
15
|
|
15
16
|
# ffmpeg will output to stderr
|
16
|
-
command = "#{FFMPEG.
|
17
|
-
|
17
|
+
command = "#{FFMPEG.ffprobe_binary} -i #{Shellwords.escape(path)} -print_format json -show_format -show_streams -show_error"
|
18
|
+
std_output = ''
|
19
|
+
std_error = ''
|
18
20
|
|
19
|
-
|
21
|
+
Open3.popen3(command) do |stdin, stdout, stderr|
|
22
|
+
std_output = stdout.read unless stdout.nil?
|
23
|
+
std_error = stderr.read unless stderr.nil?
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
@container = $1
|
26
|
+
fix_encoding(std_output)
|
23
27
|
|
24
|
-
|
25
|
-
@duration = ($1.to_i*60*60) + ($2.to_i*60) + $3.to_f
|
28
|
+
metadata = MultiJson.load(std_output, symbolize_keys: true)
|
26
29
|
|
27
|
-
|
28
|
-
@time = $1 ? $1.to_f : 0.0
|
30
|
+
if metadata.key?(:error)
|
29
31
|
|
30
|
-
|
31
|
-
@creation_time = $1 ? Time.parse("#{$1}") : nil
|
32
|
+
@duration = 0
|
32
33
|
|
33
|
-
|
34
|
-
@bitrate = $1 ? $1.to_i : nil
|
34
|
+
else
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
video_streams = metadata[:streams].select { |stream| stream.key?(:codec_type) and stream[:codec_type] === 'video' }
|
37
|
+
audio_streams = metadata[:streams].select { |stream| stream.key?(:codec_type) and stream[:codec_type] === 'audio' }
|
38
38
|
|
39
|
-
|
40
|
-
@video_stream = $1
|
39
|
+
@container = metadata[:format][:format_name]
|
41
40
|
|
42
|
-
|
43
|
-
@audio_stream = $1
|
41
|
+
@duration = metadata[:format][:duration].to_f
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
@
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
@time = metadata[:format][:start_time].to_f
|
44
|
+
|
45
|
+
@creation_time = if metadata[:format].key?(:tags) and metadata[:format][:tags].key?(:creation_time)
|
46
|
+
Time.parse(metadata[:format][:tags][:creation_time])
|
47
|
+
else
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
@bitrate = metadata[:format][:bit_rate].to_i
|
52
|
+
|
53
|
+
unless video_streams.empty?
|
54
|
+
# TODO: Handle multiple video codecs (is that possible?)
|
55
|
+
video_stream = video_streams.first
|
56
|
+
@video_codec = video_stream[:codec_name]
|
57
|
+
@colorspace = video_stream[:pix_fmt]
|
58
|
+
@width = video_stream[:width]
|
59
|
+
@height = video_stream[:height]
|
60
|
+
@video_bitrate = video_stream[:bit_rate].to_i
|
61
|
+
@sar = video_stream[:sample_aspect_ratio]
|
62
|
+
@dar = video_stream[:display_aspect_ratio]
|
63
|
+
|
64
|
+
@frame_rate = unless video_stream[:avg_frame_rate] == '0/0'
|
65
|
+
Rational(video_stream[:avg_frame_rate])
|
66
|
+
else
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
@video_stream = "#{video_stream[:codec_name]} (#{video_stream[:profile]}) (#{video_stream[:codec_tag_string]} / #{video_stream[:codec_tag]}), #{colorspace}, #{resolution} [SAR #{sar} DAR #{dar}]"
|
71
|
+
|
72
|
+
@rotation = if video_stream.key?(:tags) and video_stream[:tags].key?(:rotate)
|
73
|
+
video_stream[:tags][:rotate].to_i
|
74
|
+
else
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless audio_streams.empty?
|
80
|
+
# TODO: Handle multiple audio codecs
|
81
|
+
audio_stream = audio_streams.first
|
82
|
+
@audio_channels = audio_stream[:channels].to_i
|
83
|
+
@audio_codec = audio_stream[:codec_name]
|
84
|
+
@audio_sample_rate = audio_stream[:sample_rate].to_i
|
85
|
+
@audio_bitrate = audio_stream[:bit_rate].to_i
|
86
|
+
@audio_channel_layout = audio_stream[:channel_layout]
|
87
|
+
@audio_stream = "#{audio_codec} (#{audio_stream[:codec_tag_string]} / #{audio_stream[:codec_tag]}), #{audio_sample_rate} Hz, #{audio_channel_layout}, #{audio_stream[:sample_fmt]}, #{audio_bitrate} bit/s"
|
88
|
+
end
|
51
89
|
|
52
|
-
if audio_stream
|
53
|
-
@audio_codec, audio_sample_rate, @audio_channels, unused, audio_bitrate = audio_stream.split(/\s?,\s?/)
|
54
|
-
@audio_bitrate = audio_bitrate =~ %r(\A(\d+) kb/s\Z) ? $1.to_i : nil
|
55
|
-
@audio_sample_rate = audio_sample_rate[/\d*/].to_i
|
56
90
|
end
|
57
91
|
|
58
|
-
@invalid = true if
|
59
|
-
@invalid = true if
|
60
|
-
@invalid = true if
|
92
|
+
@invalid = true if metadata.key?(:error)
|
93
|
+
@invalid = true if std_error.include?("Unsupported codec")
|
94
|
+
@invalid = true if std_error.include?("is not supported")
|
95
|
+
@invalid = true if std_error.include?("could not find codec parameters")
|
61
96
|
end
|
62
97
|
|
63
98
|
def valid?
|
@@ -65,32 +100,43 @@ module FFMPEG
|
|
65
100
|
end
|
66
101
|
|
67
102
|
def width
|
68
|
-
|
103
|
+
rotation.nil? || rotation == 180 ? @width : @height;
|
69
104
|
end
|
70
105
|
|
71
106
|
def height
|
72
|
-
|
107
|
+
rotation.nil? || rotation == 180 ? @height : @width;
|
108
|
+
end
|
109
|
+
|
110
|
+
def resolution
|
111
|
+
unless width.nil? or height.nil?
|
112
|
+
"#{width}x#{height}"
|
113
|
+
end
|
73
114
|
end
|
74
115
|
|
75
116
|
def calculated_aspect_ratio
|
76
117
|
aspect_from_dar || aspect_from_dimensions
|
77
118
|
end
|
78
119
|
|
79
|
-
def
|
80
|
-
|
120
|
+
def calculated_pixel_aspect_ratio
|
121
|
+
aspect_from_sar || 1
|
81
122
|
end
|
82
123
|
|
83
|
-
def
|
84
|
-
|
85
|
-
return @audio_channels[/\d*/].to_i if @audio_channels["channels"]
|
86
|
-
return 1 if @audio_channels["mono"]
|
87
|
-
return 2 if @audio_channels["stereo"]
|
88
|
-
return 6 if @audio_channels["5.1"]
|
124
|
+
def size
|
125
|
+
File.size(@path)
|
89
126
|
end
|
90
127
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
128
|
+
def audio_channel_layout
|
129
|
+
# TODO Whenever support for ffmpeg/ffprobe 1.2.1 is dropped this is no longer needed
|
130
|
+
@audio_channel_layout || case(audio_channels)
|
131
|
+
when 1
|
132
|
+
'stereo'
|
133
|
+
when 2
|
134
|
+
'stereo'
|
135
|
+
when 6
|
136
|
+
'5.1'
|
137
|
+
else
|
138
|
+
'unknown'
|
139
|
+
end
|
94
140
|
end
|
95
141
|
|
96
142
|
def transcode(output_file, options = EncodingOptions.new, transcoder_options = {}, &block)
|
@@ -109,6 +155,13 @@ module FFMPEG
|
|
109
155
|
aspect.zero? ? nil : aspect
|
110
156
|
end
|
111
157
|
|
158
|
+
def aspect_from_sar
|
159
|
+
return nil unless sar
|
160
|
+
w, h = sar.split(":")
|
161
|
+
aspect = w.to_f / h.to_f
|
162
|
+
aspect.zero? ? nil : aspect
|
163
|
+
end
|
164
|
+
|
112
165
|
def aspect_from_dimensions
|
113
166
|
aspect = width.to_f / height.to_f
|
114
167
|
aspect.nan? ? nil : aspect
|
data/lib/ffmpeg/transcoder.rb
CHANGED
@@ -42,7 +42,7 @@ module FFMPEG
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def encoding_succeeded?
|
45
|
-
@errors << "no output file created" and return false unless File.
|
45
|
+
@errors << "no output file created" and return false unless File.exist?(@output_file)
|
46
46
|
@errors << "encoded file is invalid" and return false unless encoded.valid?
|
47
47
|
true
|
48
48
|
end
|
@@ -58,7 +58,7 @@ module FFMPEG
|
|
58
58
|
FFMPEG.logger.info("Running transcoding...\n#{@command}\n")
|
59
59
|
@output = ""
|
60
60
|
|
61
|
-
Open3.popen3(@command) do |
|
61
|
+
Open3.popen3(@command) do |_stdin, _stdout, stderr, wait_thr|
|
62
62
|
begin
|
63
63
|
yield(0.0) if block_given?
|
64
64
|
next_line = Proc.new do |line|
|
data/lib/ffmpeg/version.rb
CHANGED
data/lib/streamio-ffmpeg.rb
CHANGED
@@ -35,14 +35,56 @@ module FFMPEG
|
|
35
35
|
#
|
36
36
|
# @param [String] path to the ffmpeg binary
|
37
37
|
# @return [String] the path you set
|
38
|
+
# @raise Errno::ENOENT if the ffmpeg binary cannot be found
|
38
39
|
def self.ffmpeg_binary=(bin)
|
40
|
+
if bin.is_a?(String) && !File.executable?(bin)
|
41
|
+
raise Errno::ENOENT, "the ffmpeg binary, \'#{bin}\', is not executable"
|
42
|
+
end
|
39
43
|
@ffmpeg_binary = bin
|
40
44
|
end
|
41
45
|
|
42
46
|
# Get the path to the ffmpeg binary, defaulting to 'ffmpeg'
|
43
47
|
#
|
44
48
|
# @return [String] the path to the ffmpeg binary
|
49
|
+
# @raise Errno::ENOENT if the ffmpeg binary cannot be found
|
45
50
|
def self.ffmpeg_binary
|
46
|
-
@ffmpeg_binary || 'ffmpeg'
|
51
|
+
@ffmpeg_binary || which('ffmpeg')
|
47
52
|
end
|
53
|
+
|
54
|
+
# Get the path to the ffprobe binary, defaulting to what is on ENV['PATH']
|
55
|
+
#
|
56
|
+
# @return [String] the path to the ffprobe binary
|
57
|
+
# @raise Errno::ENOENT if the ffprobe binary cannot be found
|
58
|
+
def self.ffprobe_binary
|
59
|
+
@ffprobe_binary || which('ffprobe')
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set the path of the ffprobe binary.
|
63
|
+
# Can be useful if you need to specify a path such as /usr/local/bin/ffprobe
|
64
|
+
#
|
65
|
+
# @param [String] path to the ffprobe binary
|
66
|
+
# @return [String] the path you set
|
67
|
+
# @raise Errno::ENOENT if the ffprobe binary cannot be found
|
68
|
+
def self.ffprobe_binary=(bin)
|
69
|
+
if bin.is_a?(String) && !File.executable?(bin)
|
70
|
+
raise Errno::ENOENT, "the ffprobe binary, \'#{bin}\', is not executable"
|
71
|
+
end
|
72
|
+
@ffprobe_binary = bin
|
73
|
+
end
|
74
|
+
|
75
|
+
# Cross-platform way of finding an executable in the $PATH.
|
76
|
+
#
|
77
|
+
# which('ruby') #=> /usr/bin/ruby
|
78
|
+
# see: http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
79
|
+
def self.which(cmd)
|
80
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
81
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
82
|
+
exts.each { |ext|
|
83
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
84
|
+
return exe if File.executable? exe
|
85
|
+
}
|
86
|
+
end
|
87
|
+
raise Errno::ENOENT, "the #{cmd} binary could not be found in #{ENV['PATH']}"
|
88
|
+
end
|
89
|
+
|
48
90
|
end
|
metadata
CHANGED
@@ -1,50 +1,68 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: streamio-ffmpeg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Rackfish AB
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: multi_json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rspec
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - ~>
|
31
|
+
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '2.14'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- - ~>
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '2.14'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- - ~>
|
45
|
+
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '10.1'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- - ~>
|
52
|
+
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '10.1'
|
41
55
|
description:
|
42
56
|
email:
|
43
|
-
-
|
57
|
+
- support@rackfish.com
|
58
|
+
- bikeath1337.com
|
44
59
|
executables: []
|
45
60
|
extensions: []
|
46
61
|
extra_rdoc_files: []
|
47
62
|
files:
|
63
|
+
- CHANGELOG
|
64
|
+
- LICENSE
|
65
|
+
- README.md
|
48
66
|
- lib/ffmpeg/encoding_options.rb
|
49
67
|
- lib/ffmpeg/errors.rb
|
50
68
|
- lib/ffmpeg/io_monkey.rb
|
@@ -52,9 +70,6 @@ files:
|
|
52
70
|
- lib/ffmpeg/transcoder.rb
|
53
71
|
- lib/ffmpeg/version.rb
|
54
72
|
- lib/streamio-ffmpeg.rb
|
55
|
-
- README.md
|
56
|
-
- LICENSE
|
57
|
-
- CHANGELOG
|
58
73
|
homepage: http://github.com/streamio/streamio-ffmpeg
|
59
74
|
licenses: []
|
60
75
|
metadata: {}
|
@@ -64,17 +79,17 @@ require_paths:
|
|
64
79
|
- lib
|
65
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
66
81
|
requirements:
|
67
|
-
- -
|
82
|
+
- - ">="
|
68
83
|
- !ruby/object:Gem::Version
|
69
84
|
version: '0'
|
70
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
86
|
requirements:
|
72
|
-
- -
|
87
|
+
- - ">="
|
73
88
|
- !ruby/object:Gem::Version
|
74
89
|
version: '0'
|
75
90
|
requirements: []
|
76
91
|
rubyforge_project:
|
77
|
-
rubygems_version: 2.
|
92
|
+
rubygems_version: 2.4.3
|
78
93
|
signing_key:
|
79
94
|
specification_version: 4
|
80
95
|
summary: Wraps ffmpeg to read metadata and transcodes videos.
|