ffmpeg_wrapper 0.0.2
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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +11 -0
- data/ffmpeg_wrapper.gemspec +25 -0
- data/lib/ffmpeg_wrapper.rb +22 -0
- data/lib/ffmpeg_wrapper/ffmpeg.rb +128 -0
- data/lib/ffmpeg_wrapper/ffprobe.rb +73 -0
- data/lib/ffmpeg_wrapper/filters/blackdetect.rb +50 -0
- data/lib/ffmpeg_wrapper/filters/concat.rb +56 -0
- data/lib/ffmpeg_wrapper/format.rb +15 -0
- data/lib/ffmpeg_wrapper/hash.rb +9 -0
- data/lib/ffmpeg_wrapper/stream.rb +11 -0
- data/lib/ffmpeg_wrapper/version.rb +3 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5a4bfe1a276bbee90d906cf305d6d650c9e15b3b
|
4
|
+
data.tar.gz: 8e8bb0c17f3a4c9353c2af6cbc5fc91005724d38
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a06e520d53ea7485a11ed1dca162002700151976561f68ccc9e3c0f2bc7fc6ad896d74e07a1bea091668f4b4a5ccbbed438f42a48cdddf7e8fe6d4094ec0d07f
|
7
|
+
data.tar.gz: f59b4818b62a19566955661e50c4a23e3159737aee9f3f2c003e85eec2482e9234bdb48c3b6de0de3a7655ea11ea96fe468282e2843fd50c264b111b07d33809
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 slowness pc
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# FfmpegWrapper
|
2
|
+
|
3
|
+
Ruby gem wrapping cli utility FFmpeg.
|
4
|
+
Now it lacks lots of features, but
|
5
|
+
this will change in time as I need new
|
6
|
+
functions myself or just feel like
|
7
|
+
enhancing it.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'ffmpeg_wrapper'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install ffmpeg_wrapper
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### FFmpeg
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'ffmpeg_wrapper'
|
31
|
+
|
32
|
+
FFmpeg.run do
|
33
|
+
media 'somefile.mp4'
|
34
|
+
map(0,1).applying acodec: 'libmp3lame',
|
35
|
+
ac: 2, ar: '44.1k'
|
36
|
+
# .applying is a dynamic method of a
|
37
|
+
# String returned from #map
|
38
|
+
output 'out.mp3'
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
|
43
|
+
### FFprobe
|
44
|
+
|
45
|
+
``ruby
|
46
|
+
info = FFprobe.run('video.mp4') do
|
47
|
+
show_streams
|
48
|
+
show_format
|
49
|
+
end
|
50
|
+
info #=> { "format" => ..., "streams"=>... }
|
51
|
+
info['format']['codec_type'] #=> 'video'
|
52
|
+
``
|
53
|
+
|
54
|
+
Look in the documentation for details.
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
1. Fork it ( https://github.com/[my-github-username]/ffmpeg_wrapper/fork )
|
59
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
61
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ffmpeg_wrapper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ffmpeg_wrapper"
|
8
|
+
spec.version = FfmpegWrapper::VERSION
|
9
|
+
spec.authors = ['slowness']
|
10
|
+
spec.email = ['slma0x02@gmail.com']
|
11
|
+
spec.summary = 'Wrapper for FFmpeg.'
|
12
|
+
spec.description = 'FFmpeg is a powerful video, audio or image editing tool \
|
13
|
+
with tons of useful (and not so) functions.'
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'rspec-its'
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'ffmpeg_wrapper/version'
|
2
|
+
|
3
|
+
module FfmpegWrapper
|
4
|
+
# Check if ffmpeg is present in the system
|
5
|
+
def self.method_missing(meth, *_args, &_blk)
|
6
|
+
case meth.to_s
|
7
|
+
when /has_(?<cmd>.*)\?/ then system "which #{$1} &>/dev/null"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
fail 'No ffmpeg found in $PATH' unless has_ffmpeg?
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'ostruct'
|
15
|
+
require 'logger'
|
16
|
+
|
17
|
+
require 'ffmpeg_wrapper/hash.rb'
|
18
|
+
require 'ffmpeg_wrapper/ffmpeg.rb'
|
19
|
+
require 'ffmpeg_wrapper/ffprobe.rb'
|
20
|
+
require 'ffmpeg_wrapper/format.rb'
|
21
|
+
require 'ffmpeg_wrapper/stream.rb'
|
22
|
+
require 'ffmpeg_wrapper/version.rb'
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module FfmpegWrapper
|
2
|
+
class FFmpeg
|
3
|
+
def initialize
|
4
|
+
@command = 'ffmpeg -y -hide_banner'
|
5
|
+
@inputs = []
|
6
|
+
@audios = []
|
7
|
+
@videos = []
|
8
|
+
@mappings = []
|
9
|
+
@filters = []
|
10
|
+
@n = 0
|
11
|
+
@result = {}
|
12
|
+
@post_exec_hooks = []
|
13
|
+
end
|
14
|
+
# Construct ffmpeg command using that
|
15
|
+
# function, then execute. All opts hashe's
|
16
|
+
# option meant to be axactly the same as according
|
17
|
+
# ffmpeg flags. That is <tt>-pix_fmt => :pix_fmt</tt>
|
18
|
+
# @return [FFmpeg]
|
19
|
+
# @example
|
20
|
+
# FFmpeg.run do
|
21
|
+
# media 'somefile.mp4'
|
22
|
+
# map(0,1).applying acodec: 'libmp3lame',
|
23
|
+
# ac: 2, ar: '44.1k'
|
24
|
+
# # .applying is a dynamic method of a
|
25
|
+
# # String returned from #map
|
26
|
+
# output 'out.mp3'
|
27
|
+
# end
|
28
|
+
def self.run(*flags, &block)
|
29
|
+
lo = Logger.new(STDOUT) if flags.include?(:debug)
|
30
|
+
ff = FFmpeg.new
|
31
|
+
ff.instance_eval do
|
32
|
+
instance_eval(&block)
|
33
|
+
@command << ' ' << @inputs.join(' ')
|
34
|
+
@command << ' ' << @filters.join(' ') if @filters.any?
|
35
|
+
@command << ' ' << @mappings.join(' ') if @mappings.any?
|
36
|
+
@command << ' ' << @output if @output
|
37
|
+
lo.info @command if lo
|
38
|
+
@out = IO.popen(@command, err: [:child, :out]) do |io|
|
39
|
+
io.read
|
40
|
+
end
|
41
|
+
@post_exec_hooks.each { |h| instance_eval(&h) }
|
42
|
+
fail @out.to_s unless $?.success?
|
43
|
+
end
|
44
|
+
ff.instance_variable_get(:@result)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Adds input file, containing audio and video.
|
48
|
+
# @param filename [String]
|
49
|
+
# @param opts [Hash] options for this input file. See list
|
50
|
+
# of options below. If input file is a media container,
|
51
|
+
# e. g. mpeg4 or avi you don't need to explicitly specify any.
|
52
|
+
# If file is raw video or audio, specify _V_ for video
|
53
|
+
# and _A_ for audio
|
54
|
+
# @option opts [String] :f _V_ format 'rawvideo'
|
55
|
+
# @option opts [String] :s _V_ geometry WxH(+X,Y)
|
56
|
+
# @option opts [String] :pix_fmt _V_ pixel format bgr8, rgba, etc...
|
57
|
+
# @option opts [Int] :r _V_ fps
|
58
|
+
# @option opts [String] :f _A_ format 'alaw', etc...
|
59
|
+
# @option opts [String] :ar _A_ sample rate, e.g. '44.1k'
|
60
|
+
# @option opts [Int] :ac _A_ channels
|
61
|
+
# @see FFmpeg.map .run method example for call sequence
|
62
|
+
# @return id [Integer] input file id
|
63
|
+
def media(filename, opts = {})
|
64
|
+
n = input(filename, opts)
|
65
|
+
@videos << n
|
66
|
+
@audios << n
|
67
|
+
n
|
68
|
+
end
|
69
|
+
|
70
|
+
# Adds input video file (no audio will be extracted anyway)
|
71
|
+
# @param filename [String]
|
72
|
+
# @param opts [Hash] options for this input file
|
73
|
+
# @return id [Integer] input file id
|
74
|
+
def video(filename, opts = {})
|
75
|
+
n = input(filename, opts)
|
76
|
+
@videos << n
|
77
|
+
n
|
78
|
+
end
|
79
|
+
|
80
|
+
# Adds input audio file (no video will be extracted anyway)
|
81
|
+
# @param filename [String]
|
82
|
+
# @param opts [Hash] options for this input file
|
83
|
+
# @return id [Integer] input file id
|
84
|
+
def audio(filename, opts = {})
|
85
|
+
n = input(filename, opts)
|
86
|
+
@audios << n
|
87
|
+
n
|
88
|
+
end
|
89
|
+
|
90
|
+
# Specify filename for output file
|
91
|
+
# @param filename [String]
|
92
|
+
def output(filename)
|
93
|
+
@output = " #{filename}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# Specify mapping: what input stream or alias (from format, e. g. \[a\])
|
97
|
+
# @param file [String, Int] file number or alias
|
98
|
+
# @param index [Int] stream specifier
|
99
|
+
# @see FFmpeg#map #map method example for call sequence
|
100
|
+
# @see https://trac.ffmpeg.org/wiki/How%20to%20use%20-map%20option ffmpeg
|
101
|
+
# map option guide
|
102
|
+
# @return [String]
|
103
|
+
def map(file, index = nil)
|
104
|
+
line = "-map #{file}#{':' + index.to_s if index}"
|
105
|
+
@mappings << line
|
106
|
+
def line.applying(opts = {})
|
107
|
+
opts.each do |k, v|
|
108
|
+
self << " -#{k} #{v}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
line
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def input(filename, opts = {})
|
117
|
+
line = ''
|
118
|
+
opts.each do |k, v|
|
119
|
+
line << " -#{k} #{v}"
|
120
|
+
end
|
121
|
+
line << " -i #{filename}"
|
122
|
+
@inputs << line
|
123
|
+
@n += 1
|
124
|
+
@n - 1
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module FfmpegWrapper
|
4
|
+
class FFprobe
|
5
|
+
class << self
|
6
|
+
# Execute ffprobe command.
|
7
|
+
# @param [String] filename
|
8
|
+
# @return [Hash]
|
9
|
+
# @example
|
10
|
+
# info = FFprobe.run('video.mp4') do
|
11
|
+
# show_streams
|
12
|
+
# show_format
|
13
|
+
# end
|
14
|
+
# info #=> { "format" => ..., "streams"=>... }
|
15
|
+
# info['format']['codec_type'] #=> 'video'
|
16
|
+
def run(filename, &block)
|
17
|
+
ff = FFprobe.new filename
|
18
|
+
ff.instance_eval do
|
19
|
+
@command << ' -v quiet -of json'
|
20
|
+
instance_eval &block if block
|
21
|
+
@command << @show_specifiers.reduce(' ') do |acc, v|
|
22
|
+
acc << " -#{v}"
|
23
|
+
acc
|
24
|
+
end
|
25
|
+
@command << ' ' << @options.to_shellflags
|
26
|
+
@command << ' ' << @input
|
27
|
+
out = `#{@command} 2>/dev/null`
|
28
|
+
begin
|
29
|
+
@result = JSON.parse out
|
30
|
+
fail if @result.keys.empty?
|
31
|
+
rescue
|
32
|
+
@result = { 'errors' => error }
|
33
|
+
# FIXME: Do not return from ensure
|
34
|
+
ensure
|
35
|
+
return @result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [String] filename
|
42
|
+
def initialize(filename)
|
43
|
+
@input = filename || fail(ArgumentError 'No input specified')
|
44
|
+
@command = 'ffprobe '
|
45
|
+
@show_specifiers = []
|
46
|
+
@options = {}
|
47
|
+
end
|
48
|
+
|
49
|
+
# Specify input file options
|
50
|
+
# @param [Hash] options
|
51
|
+
def options(hash)
|
52
|
+
@options.merge! hash
|
53
|
+
end
|
54
|
+
alias_method :option, :options
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def method_missing(meth, *args, &blk)
|
59
|
+
case meth
|
60
|
+
when /show_(\w+)/ then
|
61
|
+
@show_specifiers << meth
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def error
|
68
|
+
@command.gsub!('-v quiet', '-v error')
|
69
|
+
@command.gsub!('-of json', '')
|
70
|
+
`#{@command} 2>&1`
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module FfmpegWrapper
|
4
|
+
class FFmpeg
|
5
|
+
# Find intervals of blackness in a video file.
|
6
|
+
# This info then can be found in a hash, returned
|
7
|
+
# from FFmpeg.run by key :blacks.
|
8
|
+
# TODO: add argument support
|
9
|
+
# @param opts [Hash]
|
10
|
+
# @return FFmpeg self. Chainable, see example.
|
11
|
+
# @example
|
12
|
+
# FFmpeg.run do
|
13
|
+
# media 'video.mp4'
|
14
|
+
# detect_black.and_write_to 'black_intervals.txt'
|
15
|
+
# end # => { ... :blacks => [ { :start => x, :end => y, :duration => z}, ... ] }
|
16
|
+
def filter_blackdetect(opts = {})
|
17
|
+
@filters << '-vf blackdetect'
|
18
|
+
@output = ' -f null /dev/null '
|
19
|
+
@redirection = [:child, :out]
|
20
|
+
@result[:blacks] = []
|
21
|
+
|
22
|
+
# Singleton method defined on FFmpeg
|
23
|
+
# after calling #filter_blackdetect.
|
24
|
+
# Writes info about black intervals as a plain text to
|
25
|
+
# a file.
|
26
|
+
# @param (String) filename
|
27
|
+
def self.and_write_to(filename)
|
28
|
+
@post_exec_hooks << proc do
|
29
|
+
File.open(filename, 'w') do |f|
|
30
|
+
@result[:blacks].each do |black|
|
31
|
+
f.puts 'black_interval start: %f end: %f duration: %f' % [black[:start], black[:end], black[:duration]]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@post_exec_hooks << proc do
|
37
|
+
bdlines = @out.lines.grep(/blackdetect/)
|
38
|
+
bdlines.map do |l|
|
39
|
+
/black_start:(?<st>\S+).*
|
40
|
+
black_end:(?<en>\S+).*
|
41
|
+
black_duration:(?<du>\S+)/x =~ l
|
42
|
+
@result[:blacks] << { start: st.to_f, end: en.to_f, duration: du.to_f }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
alias_method :detect_black, :filter_blackdetect
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module FfmpegWrapper
|
2
|
+
class FFmpeg
|
3
|
+
# This function extends basic {FFmpeg} functionality
|
4
|
+
# providing filter command.
|
5
|
+
# TODO: non-trivial mappings(i.e. multi-streamed inputs)
|
6
|
+
def filter_concat(_mappings = {})
|
7
|
+
line = ''
|
8
|
+
line << filter_complex(:audio)
|
9
|
+
line << filter_complex(:video)
|
10
|
+
@filters << line
|
11
|
+
mappings = []
|
12
|
+
mappings << (@videos.size > 1 ? '[v]' : @videos.first)
|
13
|
+
mappings << (@audios.size > 1 ? '[a]' : @audios.first)
|
14
|
+
mappings
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def stream_map_for_video
|
20
|
+
return if @videos.empty?
|
21
|
+
line = ''
|
22
|
+
@videos.each do |file|
|
23
|
+
line << " [#{file}:0] "
|
24
|
+
end
|
25
|
+
line
|
26
|
+
end
|
27
|
+
|
28
|
+
def stream_map_for_audio
|
29
|
+
return if @audios.empty?
|
30
|
+
line = ''
|
31
|
+
@audios.each do |file|
|
32
|
+
line << " [#{file}:0] "
|
33
|
+
end
|
34
|
+
line
|
35
|
+
end
|
36
|
+
|
37
|
+
def concat_for_video
|
38
|
+
"concat=n=#{@videos.size}:v=1:a=0 [v]"
|
39
|
+
end
|
40
|
+
|
41
|
+
def concat_for_audio
|
42
|
+
"concat=n=#{@audios.size}:v=0:a=1 [a]"
|
43
|
+
end
|
44
|
+
|
45
|
+
def filter_complex(str)
|
46
|
+
fail ArgumentError unless [:audio, :video].include?(str)
|
47
|
+
str = str.to_s
|
48
|
+
return '' if instance_variable_get('@' + str + 's').count < 2
|
49
|
+
line = ' -filter_complex '
|
50
|
+
line << "'"
|
51
|
+
line << send("stream_map_for_#{str}")
|
52
|
+
line << send("concat_for_#{str}")
|
53
|
+
line << "'"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module FfmpegWrapper
|
2
|
+
class Format < ::OpenStruct
|
3
|
+
CMDLINE_NAMES = {
|
4
|
+
format_name: 'f'
|
5
|
+
}
|
6
|
+
def to_cmdline
|
7
|
+
cmd = ''
|
8
|
+
each_pair do |field, value|
|
9
|
+
field_for_cmd = CMDLINE_NAMES[field]
|
10
|
+
cmd << " #{field_for_cmd} #{value}" if field_for_cmd
|
11
|
+
end
|
12
|
+
cmd
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffmpeg_wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- slowness
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-its
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: |-
|
70
|
+
FFmpeg is a powerful video, audio or image editing tool \
|
71
|
+
with tons of useful (and not so) functions.
|
72
|
+
email:
|
73
|
+
- slma0x02@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- .gitignore
|
79
|
+
- .rspec
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- ffmpeg_wrapper.gemspec
|
85
|
+
- lib/ffmpeg_wrapper.rb
|
86
|
+
- lib/ffmpeg_wrapper/ffmpeg.rb
|
87
|
+
- lib/ffmpeg_wrapper/ffprobe.rb
|
88
|
+
- lib/ffmpeg_wrapper/filters/blackdetect.rb
|
89
|
+
- lib/ffmpeg_wrapper/filters/concat.rb
|
90
|
+
- lib/ffmpeg_wrapper/format.rb
|
91
|
+
- lib/ffmpeg_wrapper/hash.rb
|
92
|
+
- lib/ffmpeg_wrapper/stream.rb
|
93
|
+
- lib/ffmpeg_wrapper/version.rb
|
94
|
+
homepage:
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 2.0.14
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: Wrapper for FFmpeg.
|
118
|
+
test_files: []
|
119
|
+
has_rdoc:
|