Skip to content

Instantly share code, notes, and snippets.

@nickpelone
Created July 21, 2020 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickpelone/66d8352b2059a8645c04de76cad569e3 to your computer and use it in GitHub Desktop.
Save nickpelone/66d8352b2059a8645c04de76cad569e3 to your computer and use it in GitHub Desktop.
quick and dirty wrapper around ffmpeg for encoding VP9 WebM files
#! /usr/bin/env ruby
# frozen_string_literal: true
# author: Nick Pelone <nick.pelone@gmail.com>
# Convert an input video file into VP9/WebM via a two-pass encoding process.
# The null file descriptor, platform-dependent.
# (This is where we send the first pass to, see: https://trac.ffmpeg.org/wiki/Encode/VP9)
NULL_FILEPTR = Gem.win_platform? ? 'NUL' : '/dev/null'
# Prints a message then a countdown timer of specified `length`
# @param [String] msg
# @param [Integer] length
# @return [void]
def countdown(msg, length = 3)
puts msg
length.times.reverse_each do |i|
puts "#{i + 1}..."
sleep(1)
end
end
# Forms a ffmpeg invocation given input and output filenames,
# video and audio bitrates (in shortform, eg. 5M, 320k, etc),
# the pass number (for 2-pass encodes), and an `overwrite` option
# (defaults to true), which overwrites the target output file without
# interactive confirmation.
#
# @param [String] input
# @param [String] output
# @param [String] video_br
# @param [String] audio_br
# @param [Integer] pass
# @param [Boolean] overwrite
# @return [String]
def ffmpeg_cmd(input:, output:, video_br:, audio_br:, pass: 1, overwrite: true)
overwrite_arg_pass2 = overwrite ? '-y' : ''
case pass
when 1
"ffmpeg -i #{File.expand_path(input)} -c:v libvpx-vp9 -b:v #{video_br} -pass 1 -row-mt 1 -an -f webm -y #{NULL_FILEPTR}"
when 2
"ffmpeg -i #{File.expand_path(input)} -c:v libvpx-vp9 -b:v #{video_br} -pass 2 -row-mt 1 -c:a libopus -b:a #{audio_br} #{overwrite_arg_pass2} #{File.expand_path(output)}"
end
end
#
# 'main'
#
abort("Usage: #{File.basename($PROGRAM_NAME)} [input] [video bitrate] [audio bitrate] [output]") if ARGV.empty?
system(
ffmpeg_cmd(
input: ARGV[0],
video_br: ARGV[1],
audio_br: ARGV[2],
output: ARGV[3],
pass: 1
)
)
countdown('Starting second-pass endode in:')
system(
ffmpeg_cmd(
input: ARGV[0],
video_br: ARGV[1],
audio_br: ARGV[2],
output: ARGV[3],
pass: 2
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment