Class: RVideo::Tools::Ffmpeg
- Inherits:
-
Object
- Object
- RVideo::Tools::Ffmpeg
- Includes:
- AbstractTool::InstanceMethods
- Defined in:
- lib/rvideo/tools/ffmpeg.rb
Constant Summary collapse
- RESOLUTION_ABBREVIATIONS =
{ "sqcif" => "128x96", "qcif" => "176x144", "cif" => "352x288", "4cif" => "704x576", "qqvga" => "160x120", "qvga" => "320x240", "vga" => "640x480", "svga" => "800x600", "xga" => "1024x768", "uxga" => "1600x1200", "qxga" => "2048x1536", "sxga" => "1280x1024", "qsxga" => "2560x2048", "hsxga" => "5120x4096", "wvga" => "852x480", "wxga" => "1366x768", "wsxga" => "1600x1024", "wuxga" => "1920x1200", "woxga" => "2560x1600", "wqsxga" => "3200x2048", "wquxga" => "3840x2400", "whsxga" => "6400x4096", "whuxga" => "7680x4800", "cga" => "320x200", "ega" => "640x350", "hd480" => "852x480", "hd720" => "1280x720", "hd1080" => "1920x1080" }
- VALID_ASPECT_STRINGS =
["4:3", "16:9"]
- VALID_ASPECT_FLOATS =
[1.3333, 1.7777]
- DEFAULT_VIDEO_BIT_RATE_PARAMETER =
The flag used to set video bitrate has apparently changed between different ffmpeg versions. In the latest builds -b is used. In older builds it was -v which is now used to set verbosity of logging.
"b"
Instance Attribute Summary collapse
-
#audio_size ⇒ Object
readonly
Returns the value of attribute audio_size.
-
#frame ⇒ Object
readonly
Returns the value of attribute frame.
-
#header_size ⇒ Object
readonly
Returns the value of attribute header_size.
-
#output_bitrate ⇒ Object
readonly
Returns the value of attribute output_bitrate.
-
#output_fps ⇒ Object
readonly
Returns the value of attribute output_fps.
-
#overhead ⇒ Object
readonly
Returns the value of attribute overhead.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
-
#psnr ⇒ Object
readonly
Returns the value of attribute psnr.
-
#q ⇒ Object
readonly
Returns the value of attribute q.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#time ⇒ Object
readonly
Returns the value of attribute time.
-
#video_size ⇒ Object
readonly
Returns the value of attribute video_size.
Attributes included from AbstractTool::InstanceMethods
#command, #options, #original, #progress, #raw_result
Instance Method Summary collapse
- #execute_with_progress ⇒ Object
- #format_audio_bit_rate(params = {}) ⇒ Object
- #format_audio_channels(params = {}) ⇒ Object
- #format_audio_sample_rate(params = {}) ⇒ Object
- #format_deinterlace(params = {}) ⇒ Object
- #format_fps(params = {}) ⇒ Object
- #format_resolution(params = {}) ⇒ Object
- #format_video_bit_rate(params = {}) ⇒ Object
- #format_video_bit_rate_max(params = {}) ⇒ Object
- #format_video_bit_rate_min(params = {}) ⇒ Object
- #format_video_bit_rate_tolerance(params = {}) ⇒ Object
- #format_video_quality(params = {}) ⇒ Object
-
#initialize(raw_command, options = {}) ⇒ Ffmpeg
constructor
A new instance of Ffmpeg.
- #kill ⇒ Object
-
#tool_command ⇒ Object
Not sure if this is needed anymore…
Methods included from AbstractTool::InstanceMethods
abstract_attribute_formatter, #audio_bit_rate, #audio_channels, #audio_sample_rate, #calculate_height, #calculate_width, #deinterlace, #do_execute, #execute, #fps, #get_audio_bit_rate, #get_audio_channels, #get_audio_sample_rate, #get_deinterlace, #get_fit_to_height_resolution, #get_fit_to_width_resolution, #get_fps, #get_letterbox_resolution, #get_mono_audio, #get_original_fps, #get_original_resolution, #get_resolution, #get_specific_audio_bit_rate, #get_specific_audio_sample_rate, #get_specific_fps, #get_specific_resolution, #get_stereo_audio, #get_video_bit_rate, #get_video_bit_rate_max, #get_video_bit_rate_min, #get_video_bit_rate_tolerance, #get_video_quality, #resolution, #temp_dir, #valid_dimension?, #video_bit_rate, #video_bit_rate_max, #video_bit_rate_min, #video_bit_rate_tolerance, #video_quality
Constructor Details
#initialize(raw_command, options = {}) ⇒ Ffmpeg
Returns a new instance of Ffmpeg.
49 50 51 52 53 54 55 56 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 49 def initialize(raw_command, = {}) @progress_sample_rate = .delete(:progress_sample_rate) @progress_timeout = .delete(:progress_timeout) @raw_command = raw_command @options = HashWithIndifferentAccess.new() @command = interpolate_variables(raw_command) end |
Instance Attribute Details
#audio_size ⇒ Object (readonly)
Returns the value of attribute audio_size.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def audio_size @audio_size end |
#frame ⇒ Object (readonly)
Returns the value of attribute frame.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def frame @frame end |
#header_size ⇒ Object (readonly)
Returns the value of attribute header_size.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def header_size @header_size end |
#output_bitrate ⇒ Object (readonly)
Returns the value of attribute output_bitrate.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def output_bitrate @output_bitrate end |
#output_fps ⇒ Object (readonly)
Returns the value of attribute output_fps.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def output_fps @output_fps end |
#overhead ⇒ Object (readonly)
Returns the value of attribute overhead.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def overhead @overhead end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def pid @pid end |
#psnr ⇒ Object (readonly)
Returns the value of attribute psnr.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def psnr @psnr end |
#q ⇒ Object (readonly)
Returns the value of attribute q.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def q @q end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def size @size end |
#time ⇒ Object (readonly)
Returns the value of attribute time.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def time @time end |
#video_size ⇒ Object (readonly)
Returns the value of attribute video_size.
47 48 49 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 47 def video_size @video_size end |
Instance Method Details
#execute_with_progress ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 132 def execute_with_progress # TODO put progress_counter stuff back in because long videos might not update their progress for some time and we wouldn't want to accidently kill them! final_command = @command RVideo.logger.info("\nExecuting Command: #{final_command}\n") @raw_result = '' duration = 0 previous_line = nil mutex = Mutex.new command_thread = Thread.new do @pid, stdin, stdout, stderr = Open4::popen4(final_command) stderr.each("\r") do |line| if line != previous_line previous_line = line new_progress, duration = parse_progress(line, duration) mutex.synchronize do @progress = new_progress end $defout.flush end # WARNING: we may need to set a limit to how many lines are appended to @raw_result as ffmpeg can spit out a massive amount of info if things go pear shaped @raw_result += line + "\r" end end # Yield the progress and monitor the process current_timeout = 0 progress_to_yeild = nil loop do # Exit when the command is done break unless command_thread.alive? # Yield the progress mutex.synchronize do # First check if we're actually making progress! We should kill the command if it's not, as it's probably because ffmpeg has frozen if progress_to_yeild == @progress current_timeout += @progress_sample_rate end progress_to_yeild = @progress end unless @progress_timeout == false self.kill if current_timeout >= @progress_timeout end yield progress_to_yeild sleep @progress_sample_rate end end |
#format_audio_bit_rate(params = {}) ⇒ Object
124 125 126 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 124 def format_audio_bit_rate(params={}) "-ab #{params[:bit_rate]}k" end |
#format_audio_channels(params = {}) ⇒ Object
120 121 122 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 120 def format_audio_channels(params={}) "-ac #{params[:channels]}" end |
#format_audio_sample_rate(params = {}) ⇒ Object
128 129 130 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 128 def format_audio_sample_rate(params={}) "-ar #{params[:sample_rate]}" end |
#format_deinterlace(params = {}) ⇒ Object
63 64 65 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 63 def format_deinterlace(params={}) params[:deinterlace] ? "-deinterlace" : "" end |
#format_fps(params = {}) ⇒ Object
67 68 69 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 67 def format_fps(params={}) "-r #{params[:fps]}" end |
#format_resolution(params = {}) ⇒ Object
110 111 112 113 114 115 116 117 118 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 110 def format_resolution(params={}) p = "-s #{params[:scale][:width]}x#{params[:scale][:height]}" if params[:letterbox] plr = ((params[:letterbox][:width] - params[:scale][:width]) / 2).to_i ptb = ((params[:letterbox][:height] - params[:scale][:height]) / 2).to_i p += " -padtop #{ptb} -padbottom #{ptb} -padleft #{plr} -padright #{plr} " end p end |
#format_video_bit_rate(params = {}) ⇒ Object
71 72 73 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 71 def format_video_bit_rate(params = {}) "-#{video_bit_rate_parameter} #{params[:video_bit_rate]}k" end |
#format_video_bit_rate_max(params = {}) ⇒ Object
83 84 85 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 83 def format_video_bit_rate_max(params = {}) "-maxrate #{params[:video_bit_rate_max]}k" end |
#format_video_bit_rate_min(params = {}) ⇒ Object
79 80 81 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 79 def format_video_bit_rate_min(params = {}) "-minrate #{params[:video_bit_rate_min]}k" end |
#format_video_bit_rate_tolerance(params = {}) ⇒ Object
75 76 77 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 75 def format_video_bit_rate_tolerance(params = {}) "-bt #{params[:video_bit_rate_tolerance]}k" end |
#format_video_quality(params = {}) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 87 def format_video_quality(params={}) bitrate = params[:video_bit_rate].blank? ? nil : params[:video_bit_rate] params.merge! get_original_fps unless params[:fps] factor = params[:scale][:width].to_f * params[:scale][:height].to_f * params[:fps].to_f case params[:video_quality] when 'low' bitrate ||= (factor / 12000).to_i params[:video_bit_rate] = bitrate "#{format_video_bit_rate params} -crf 30 -me zero -subq 1 -refs 1 -threads auto" when 'medium' bitrate ||= (factor / 9000).to_i params[:video_bit_rate] = bitrate "#{format_video_bit_rate params} -crf 22 -flags +loop -cmp +sad -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me hex -subq 3 -trellis 1 -refs 2 -bf 3 -b_strategy 1 -coder 1 -me_range 16 -g 250" when 'high' bitrate ||= (factor / 3600).to_i params[:video_bit_rate] = bitrate "#{format_video_bit_rate params} -crf 18 -flags +loop -cmp +sad -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me full -subq 6 -trellis 1 -refs 3 -bf 3 -b_strategy 1 -coder 1 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71" end end |
#kill ⇒ Object
182 183 184 185 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 182 def kill Process.kill("SIGKILL", @pid) raise TranscoderError, "Transcoder hung." end |
#tool_command ⇒ Object
Not sure if this is needed anymore…
59 60 61 |
# File 'lib/rvideo/tools/ffmpeg.rb', line 59 def tool_command 'ffmpeg' end |