Skip to content

Instantly share code, notes, and snippets.

@iloveitaly
Last active December 18, 2015 04:19
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 iloveitaly/5724615 to your computer and use it in GitHub Desktop.
Save iloveitaly/5724615 to your computer and use it in GitHub Desktop.
#!/bin/ruby
# we need some CLI tools:
# * ffmpeg (install via http://www.evermeet.cx/ffmpeg/)
# * qt-faststart `brew install qtfaststart`
# global vars are a cheap hack for the get_output method
# based on: https://develop.participatoryculture.org/index.php/ConversionMatrix
# detailed information on encoding here: https://www.virag.si/2012/01/web-video-encoding-tutorial-with-ffmpeg-0-9/
# other resources:
# http://users.ece.gatech.edu/~msalman/ffmpeg.html
# http://en.wikipedia.org/wiki/Pixel_aspect_ratio
# http://rodrigopolo.com/ffmpeg/cheats.php
$target_dir = target_dir = ARGV[0]
skip_count = (ENV['SKIP'] || 0).to_i
sd_video = (ARGV[1] || 0).to_i != 0
formats = (ENV['FORMATS'] || 'all')
target_file = ""
# native export from FCP will get you here
full_hd_mp4_video_sizes = [
{ :size => '848x480', :suffix => '_mobile', :bitrate => 500 }, # old iphones
{ :size => '1280x720', :suffix => '', :bitrate => 1000 }, # desktops, iphone 4+
{ :size => '1920x1080', :suffix => '_hd', :bitrate => 1200 } # full 1080
]
# this is the best you'll get from DVD ripping
hd_mp4_video_sizes = [
{ :size => '872x480', :suffix => '', :bitrate => 1000 }, # desktops, iphone 4+
]
# for the SD vidoes the size is ignored – we output the full resolution of the SD video that we have
# SD videos are usually 720x480 (although the actual resolution of the video on the DVD is less: https://trac.handbrake.fr/wiki/AnamorphicGuide)
sd_mp4_video_sizes = [
{ :size => '654x480', :suffix => '', :bitrate => 700 },
]
if target_dir.empty?
puts "Need valid target directory"
return
end
if `uname`.strip != 'Darwin'
puts "Script designed for OS X"
return
end
# create a 'converted' directory inside the source files directory
# this is where all the versions of the videos are created
$output_dir = output_dir = File.join(target_dir, 'converted')
$valid_extensions = ['.mov', '.mp4', '.mpeg', '.mpg']
Dir.mkdir output_dir if !File.exists?(output_dir)
def get_output(template)
extension = $valid_extensions.detect { |s| $target_file.end_with? s }
File.join($output_dir, File.basename($target_file, extension) + template)
end
Dir.entries(target_dir).sort.each do |target_file|
next if target_file == '.DS_Store'
$target_file = target_file = File.join(target_dir, target_file)
next if !$valid_extensions.detect { |e| $target_file.end_with? e }
next if File.directory? target_file
next if (skip_count -= 1) >= 0
puts "Processing: #{target_file}"
if formats == 'all' || formats.include?('mp4')
faststart_post_process = []
# MP4 container + AAC audio + H.264 codec
# baseline profile important
# TODO conditionally insert the yadif filter
# -filter:v yadif fixes the interlacing problem on SD videos (and possibly hd?)
(sd_video ? sd_mp4_video_sizes : hd_mp4_video_sizes).each do |mp4_template|
faststart_post_process << get_output(mp4_template[:suffix] + '.mp4')
%x[ffmpeg -i "#{target_file}" \
-acodec aac -ac 2 -strict experimental -ab 160k \
-vf scale=-1:480 \
-s "#{mp4_template[:size]}" \
-vcodec libx264 -preset slow -profile:v baseline -level 30 -maxrate 10000000 -bufsize 10000000 -b #{mp4_template[:bitrate]}k -f mp4 -threads 0 \
"#{faststart_post_process.last}"
]
end
faststart_post_process.each do |quicktime_file|
# faststart moves the metadata to the beginning of the video file
%x[
qt-faststart "#{quicktime_file}" "#{quicktime_file}_temp" && \
rm "#{quicktime_file}" && \
mv "#{quicktime_file}_temp" "#{quicktime_file}"
]
end
end
# webm + mp3 are not multi core conversions – we can run them all at the same time
# webm - hd
# for now we are disabling HD video since we are working with content pulled from 16/9 DVDs (maxes out at 480p)
# if !sd_video
# fork do
# %x[ffmpeg -i "#{target_file}" -s hd720 -vcodec libvpx -g 120 -lag-in-frames 16 -deadline good -cpu-used 0 -vprofile 0 -qmax 51 -qmin 11 -slices 4 -b:v 2M -acodec libvorbis -ab 112k -ar 44100 -f webm "#{get_output('_hd.webm')}"]
# end
# end
# webm - sd
fork do
%x[ffmpeg -i "#{target_file}" -s hd480 -vcodec libvpx -g 120 -lag-in-frames 16 -deadline good -cpu-used 0 -vprofile 0 -qmax 63 -qmin 0 -b:v 768k -acodec libvorbis -ab 112k -ar 44100 -f webm "#{get_output('.webm')}"]
end if formats == 'all' || formats.include?('webm')
fork do
%x[ffmpeg -i "#{target_file}" -f mp3 -y "#{get_output('.mp3')}"]
end if formats == 'all' || formats.include?('mp3')
Process.waitall
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment