class EasyVideoUtils
Public Class Methods
# File lib/easyvideo_utils.rb, line 75 def initialize(vid_in=nil, vid_out='video.mp4', out: vid_out, working_dir: '/tmp', debug: false) @file_out, @working_dir, @debug = out, working_dir, debug if vid_in.is_a? String then @file_in = vid_in elsif vid_in.is_a? Array @files_in = vid_in end end
Public Instance Methods
Add an audio track to a video which contains no audio
# File lib/easyvideo_utils.rb, line 90 def add_audio(audio_file, show: false) command = "ffmpeg -i #{@file_in} -i #{audio_file} -codec copy " + "-shortest #{@file_out} -y" run command, show end
To add subtitles, supply a .srt file
# File lib/easyvideo_utils.rb, line 100 def add_subtitles(file, show: false) command = "ffmpeg -i #{@file_in} -i #{file} -c copy -c:s mov_" + "text #{@file_out} -y" run command, show end
# File lib/easyvideo_utils.rb, line 108 def capture_desktop(show: false) command = "ffmpeg -video_size 1024x768 -framerate 25 -f x11grab -i " + ":0.0+0,0 #{@file_out}" run command, show end
Concatenate 2 or more videos
Notes:
-
Video must be of same format and codec
-
Only video with no audio is currently supported
# File lib/easyvideo_utils.rb, line 122 def concat(files=@files_in, show: false) inputs = files.map {|file| "-i #{file}"}.join(' ') filter = files.map.with_index {|file,i| "[%s:v]" % i}.join(' ') command = "ffmpeg #{inputs} \ " + " -filter_complex \"#{filter} concat=n=#{files.length}:v=1 [v]\" \ " + " -map \"[v]\" #{@file_out}" run command, show end
creates a video from an audio file along with a single image file
# File lib/easyvideo_utils.rb, line 137 def create_poster(audiox=nil, imagex=nil, image: imagex, audio: audiox, show: false) command = "ffmpeg -loop 1 -i #{image} -i #{audio} -c:v libx264 -c:a " + "aac -strict experimental -b:a 192k -shortest #{@file_out}" run command, show end
# File lib/easyvideo_utils.rb, line 144 def create_slideshow(ext: '.jpg', image_duration: 5, show: false) file_mask = @file_in || "image-%03d" + ext command = "ffmpeg -r 1/#{image_duration} -i #{file_mask} -c:v " + "libx264 -r 30 -pix_fmt yuv420p #{@file_out}" run command, show end
Duration returned in seconds
# File lib/easyvideo_utils.rb, line 155 def duration() s = `exiftool #{@file_in}` puts 's: ' + s.inspect if @debug r = s[/Duration.*(\d{1,2}:\d{2}:\d{2})/,1] puts 'r: ' + r.inspect if @debug if r then a = r.split(':').map(&:to_i) return Subunit.new(units={minutes:60, hours:60, seconds: 0}, a).to_i end puts 'r: ' + r.inspect if @debug s[/Duration.*: (\d+\.\d+) s/,1].to_f end
Extract images from the video
switches used:
-r – Set the frame rate. I.e the number of frames to be extracted into images per second. -f – Indicates the output format i.e image format in our case.
# File lib/easyvideo_utils.rb, line 180 def extract_images(show: false, ext: '.png', rate: 1) command = "ffmpeg -i #{@file_in} -r #{rate} -f image2 image-%2d#{ext}" run command, show end
# File lib/easyvideo_utils.rb, line 190 def grab_image(start_time=1, show: false) command = "avconv -i #{@file_in} -ss #{start_time.to_s} -frames:v 1 #{@file_out} -y" run command, show end
# File lib/easyvideo_utils.rb, line 185 def info(show: false) command = "avprobe #{@file_in}" run command, show end
# File lib/easyvideo_utils.rb, line 195 def play(show: false) command = "mplayer #{@file_out}" run command, show end
# File lib/easyvideo_utils.rb, line 200 def preview(show: false) command = "ffplay #{@file_out}" run command, show end
# File lib/easyvideo_utils.rb, line 205 def remove_audio(show: false) command = "ffmpeg -i #{@file_in} -an #{@file_out}" run command, show end
removes the video track which leaves the audio track e.g. ffmpeg -i input.mp4 -vn output.mp3
# File lib/easyvideo_utils.rb, line 213 def remove_video(show: false) command = "ffmpeg -i #{@file_in} -vn #{@file_out}" run command, show end
Resize e.g. to 320x240
# File lib/easyvideo_utils.rb, line 220 def resize(scale='320x240', show: false) command = "avconv -i #{@file_in} -s #{scale} #{@file_out} -y" run command, show end
starts recoring after 2 seconds for a duration of 6 seconds
# File lib/easyvideo_utils.rb, line 230 def screencast(duration: 6, scale: 0.75, window: true) gif_file = @file_out.sub(/\w+$/,'gif') EasyImgUtils.new(out: gif_file)\ .screencast(duration: duration, scale: scale, window: window) EasyVideoUtils.new(gif_file, @file_out).transcode end
slow down a video
note: presentation timestamp (PTS) 'x2' = half speed; 'x4' = quarter speed
# File lib/easyvideo_utils.rb, line 245 def slowdown(speed=:x2, show: false) factor = {x1_5: 1.5, x2: 2.0, x4: 4.0}[speed.to_s.sub('.','_').to_sym] command = "ffmpeg -i #{@file_in} -vf \"setpts=#{factor}*PTS\" " + "#{@file_out} -y" run command, show end
speed up a video
note: presentation timestamp (PTS) 'x2' = double speed; 'x4' = quadruple speed
# File lib/easyvideo_utils.rb, line 259 def speedup(speed=:x2, show: false) h = {x1_5: 0.75, x2: 0.5, x4: 0.25, x6: 0.166, x8: 0.125, x16: 0.0625, x32: 0.03125, x64: 0.015625} factor = h[speed.to_s.sub('.','_').to_sym] command = "ffmpeg -i #{@file_in} -vf \"setpts=#{factor}*PTS\" " + "#{@file_out} -y" run command, show end
Transcodes avi -> mp4
# File lib/easyvideo_utils.rb, line 272 def transcode(show: false) return gif_to_mp4() if File.extname(@file_in) == '.gif' command = "ffmpeg -i #{@file_in} #{@file_out} -y" run command, show end
Trim the start and end of the video times can be expressed in human time format e.g. '1m 4s', '2m 30'
# File lib/easyvideo_utils.rb, line 286 def trim(start_time, duration, show: false) t1 = "%02d:%02d:%02d" % (start_time.to_s.sub(/m/,'\00s').split(/\D/)\ .reverse + [0,0]).take(3).reverse command = "avconv -i #{@file_in} -ss #{t1} -t #{duration.to_s} " + "-codec copy #{@file_out}" run command, show end
Download a video from YouTube
# File lib/easyvideo_utils.rb, line 299 def youtube_dl(show: false) command = "youtube-dl -f 'bestvideo[ext=mp4]+" + "bestaudio[ext=m4a]/best[ext=mp4]/best' #{@file_in}" command += ' -o ' + @file_out if @file_out run command, show end
Private Instance Methods
# File lib/easyvideo_utils.rb, line 312 def gif_to_mp4(show: false) command = "ffmpeg -i %s -movflags faststart -pix_fmt yuv420p \ -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" %s" % [@file_in, @file_out] run command, show end
# File lib/easyvideo_utils.rb, line 320 def run(command, show=false) if show then command else puts "Using ->" + command system command end end