Class: FfmpegWrapper::FFmpeg
- Inherits:
-
Object
- Object
- FfmpegWrapper::FFmpeg
- Defined in:
- lib/ffmpeg_wrapper/ffmpeg.rb,
lib/ffmpeg_wrapper/filters/concat.rb,
lib/ffmpeg_wrapper/filters/blackdetect.rb
Class Method Summary collapse
-
.and_write_to(filename) ⇒ Object
Singleton method defined on FFmpeg after calling #filter_blackdetect.
-
.run(*flags, &block) ⇒ FFmpeg
Construct ffmpeg command using that function, then execute.
Instance Method Summary collapse
-
#audio(filename, opts = {}) ⇒ Object
Adds input audio file (no video will be extracted anyway).
-
#filter_blackdetect(opts = {}) ⇒ Object
(also: #detect_black)
Find intervals of blackness in a video file.
-
#filter_concat(_mappings = {}) ⇒ Object
This function extends basic FFmpeg functionality providing filter command.
-
#initialize ⇒ FFmpeg
constructor
A new instance of FFmpeg.
-
#map(file, index = nil) ⇒ String
Specify mapping: what input stream or alias (from format, e. g. [a]).
-
#media(filename, opts = {}) ⇒ Object
Adds input file, containing audio and video.
-
#output(filename) ⇒ Object
Specify filename for output file.
-
#video(filename, opts = {}) ⇒ Object
Adds input video file (no audio will be extracted anyway).
Constructor Details
#initialize ⇒ FFmpeg
Returns a new instance of FFmpeg.
3 4 5 6 7 8 9 10 11 12 13 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 3 def initialize @command = 'ffmpeg -y -hide_banner' @inputs = [] @audios = [] @videos = [] @mappings = [] @filters = [] @n = 0 @result = {} @post_exec_hooks = [] end |
Class Method Details
.and_write_to(filename) ⇒ Object
Singleton method defined on FFmpeg after calling #filter_blackdetect. Writes info about black intervals as a plain text to a file.
27 28 29 30 31 32 33 34 35 |
# File 'lib/ffmpeg_wrapper/filters/blackdetect.rb', line 27 def self.and_write_to(filename) @post_exec_hooks << proc do File.open(filename, 'w') do |f| @result[:blacks].each do |black| f.puts 'black_interval start: %f end: %f duration: %f' % [black[:start], black[:end], black[:duration]] end end end end |
.run(*flags, &block) ⇒ FFmpeg
Construct ffmpeg command using that function, then execute. All opts hashe’s option meant to be axactly the same as according ffmpeg flags. That is -pix_fmt => :pix_fmt
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 28 def self.run(*flags, &block) lo = Logger.new(STDOUT) if flags.include?(:debug) ff = FFmpeg.new ff.instance_eval do instance_eval(&block) @command << ' ' << @inputs.join(' ') @command << ' ' << @filters.join(' ') if @filters.any? @command << ' ' << @mappings.join(' ') if @mappings.any? @command << ' ' << @output if @output lo.info @command if lo @out = IO.popen(@command, err: [:child, :out]) do |io| io.read end @post_exec_hooks.each { |h| instance_eval(&h) } fail @out.to_s unless $?.success? end ff.instance_variable_get(:@result) end |
Instance Method Details
#audio(filename, opts = {}) ⇒ Object
Adds input audio file (no video will be extracted anyway)
84 85 86 87 88 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 84 def audio(filename, opts = {}) n = input(filename, opts) @audios << n n end |
#filter_blackdetect(opts = {}) ⇒ Object Also known as: detect_black
Find intervals of blackness in a video file. This info then can be found in a hash, returned from FFmpeg.run by key :blacks. TODO: add argument support
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ffmpeg_wrapper/filters/blackdetect.rb', line 16 def filter_blackdetect(opts = {}) @filters << '-vf blackdetect' @output = ' -f null /dev/null ' @redirection = [:child, :out] @result[:blacks] = [] # Singleton method defined on FFmpeg # after calling #filter_blackdetect. # Writes info about black intervals as a plain text to # a file. # @param (String) filename def self.and_write_to(filename) @post_exec_hooks << proc do File.open(filename, 'w') do |f| @result[:blacks].each do |black| f.puts 'black_interval start: %f end: %f duration: %f' % [black[:start], black[:end], black[:duration]] end end end end @post_exec_hooks << proc do bdlines = @out.lines.grep(/blackdetect/) bdlines.map do |l| /black_start:(?<st>\S+).* black_end:(?<en>\S+).* black_duration:(?<du>\S+)/x =~ l @result[:blacks] << { start: st.to_f, end: en.to_f, duration: du.to_f } end end self end |
#filter_concat(_mappings = {}) ⇒ Object
This function extends basic FfmpegWrapper::FFmpeg functionality providing filter command. TODO: non-trivial mappings(i.e. multi-streamed inputs)
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/ffmpeg_wrapper/filters/concat.rb', line 6 def filter_concat(_mappings = {}) line = '' line << filter_complex(:audio) line << filter_complex(:video) @filters << line mappings = [] mappings << (@videos.size > 1 ? '[v]' : @videos.first) mappings << (@audios.size > 1 ? '[a]' : @audios.first) mappings end |
#map(file, index = nil) ⇒ String
Specify mapping: what input stream or alias (from format, e. g. [a])
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 103 def map(file, index = nil) line = "-map #{file}#{':' + index.to_s if index}" @mappings << line def line.(opts = {}) opts.each do |k, v| self << " -#{k} #{v}" end end line end |
#media(filename, opts = {}) ⇒ Object
Adds input file, containing audio and video. of options below. If input file is a media container,
-
mpeg4 or avi you don’t need to explicitly specify any.
-
If file is raw video or audio, specify V for video and A for audio
63 64 65 66 67 68 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 63 def media(filename, opts = {}) n = input(filename, opts) @videos << n @audios << n n end |
#output(filename) ⇒ Object
Specify filename for output file
92 93 94 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 92 def output(filename) @output = " #{filename}" end |
#video(filename, opts = {}) ⇒ Object
Adds input video file (no audio will be extracted anyway)
74 75 76 77 78 |
# File 'lib/ffmpeg_wrapper/ffmpeg.rb', line 74 def video(filename, opts = {}) n = input(filename, opts) @videos << n n end |