Skip to content

Instantly share code, notes, and snippets.

@clutchski
Created September 22, 2012 21:47
Show Gist options
  • Save clutchski/3767935 to your computer and use it in GitHub Desktop.
Save clutchski/3767935 to your computer and use it in GitHub Desktop.
A small script to transcode a directory tree of media files with ffmpeg.
#!/usr/bin/env ruby
#
# This is a small script to transcode a directory of media files
# with ffmpeg.
require 'fileutils'
# These are config values are for my project. Swap in your own.
input_dir="/Volumes/severn.5/video"
output_dir="/Volumes/severn.4/video/transcoded"
input_type="MOV"
ffmpeg_options="-y -vcodec prores -profile:v 2 -acodec copy"
to_convert = Dir.glob("#{input_dir}/**/*.#{input_type}")
# Build a list of files to convert.
File.open('transcode_todo.txt', 'w') do |f|
f.write(to_convert.join("\n"))
end
total = to_convert.length
count = 0
def log_completed(path)
File.open('transcode_done.txt', 'a') do |f|
f.write(path + "\n")
end
end
def log_failed(path)
File.open('transcode_failed.txt', 'a') do |f|
f.write(path + "\n")
end
end
to_convert.each do |input_path|
count += 1
# Get the new file path.
target_path = "#{output_dir}/#{input_path[input_dir.length+1..-1]}"
# Add the mod date into the filename
clip_name = File.basename target_path
date_label = File.mtime(input_path).strftime("%Y.%m.%d-%H.%M.%S")
target_filename = "#{date_label}__#{clip_name}"
# Build the output path
target_dir = File.dirname target_path
FileUtils.mkdir_p target_dir
output_path = "#{target_dir}/#{target_filename}"
# Do it.
10.times.each{|i| puts "\n"}
puts "[#{count}/#{total}] Converting #{input_path} to #{output_path}"
%x{ffmpeg -i #{input_path} #{ffmpeg_options} #{output_path}}
if $?.exitstatus == 0
log_completed(input_path)
else
log_failed(input_path)
end
end
#!/usr/bin/env ruby
#
# This is a small script to transcode a directory of media files
# with ffmpeg.
require 'fileutils'
require 'thread'
# These are config values are for my project. Swap in your own.
INPUT_DIR="/Volumes/severn.5/video"
OUTPUT_DIR="/Volumes/severn.4/video/transcoded"
input_type="MOV"
FFMPEG_OPTIONS="-y -vcodec prores -profile:v 2 -acodec copy -threads 4"
def log_completed(path)
File.open('transcode_done.txt', 'a') do |f|
f.write(path + "\n")
end
end
def log_failed(path)
File.open('transcode_failed.txt', 'a') do |f|
f.write(path + "\n")
end
end
def convert_path(input_path)
# Get the new file path.
target_path = "#{OUTPUT_DIR}/#{input_path[INPUT_DIR.length+1..-1]}"
# Add the mod date into the filename
clip_name = File.basename target_path
date_label = File.mtime(input_path).strftime("%Y.%m.%d-%H.%M.%S")
target_filename = "#{date_label}__#{clip_name}"
# Build the output path
target_dir = File.dirname target_path
FileUtils.mkdir_p target_dir
output_path = "#{target_dir}/#{target_filename}"
# Do it.
10.times.each{|i| puts "\n"}
puts "Converting #{input_path} to #{output_path}"
%x{ffmpeg -i #{input_path} #{FFMPEG_OPTIONS} #{output_path}}
if $?.exitstatus == 0
log_completed(input_path)
else
log_failed(input_path)
end
end
queue = Queue.new
FileUtils.touch('transcode_done.txt')
already_converted = File.open('transcode_done.txt',
'r').readlines().collect{|v| v.strip() }
all_videos = Dir.glob("#{INPUT_DIR}/**/*.#{input_type}")
all_videos.each do |v|
if already_converted.include? v
puts "already converted #{v}"
else
queue.push v
end
end
threads = 7.times.collect do
Thread.new do
while !queue.empty?
path = queue.pop
convert_path(path)
end
end
end
threads.each {|t| t.join}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment