Skip to content

Instantly share code, notes, and snippets.

@brysonian
Created April 5, 2009 17:21
Show Gist options
  • Save brysonian/90487 to your computer and use it in GitHub Desktop.
Save brysonian/90487 to your computer and use it in GitHub Desktop.
Script to transcode DMA .rm videos to mp4 and mp3
#!/usr/bin/env ruby
require 'yaml'
require 'fileutils'
require 'mysql'
class Transcoder
#Path to tools
@@MENCODER = "/usr/local/bin/mencoder"
@@MPLAYER = "/usr/local/bin/mplayer"
@@FFMPEG = "/opt/local/bin/ffmpeg"
@@ATOMICPARSLEY = '/opt/local/bin/AtomicParsley'
@@LAME = '/opt/local/bin/lame'
# commands
MENCODER_TO_MP4 = '%s "%s" -o "%s" -vf dsize=320:240:2,scale=-8:-8,harddup -oac faac -faacopts mpeg=4:object=2:raw:br=128 -channels 1 -srate 44100 -of lavf -lavfopts format=mp4 -ovc x264 -x264encopts bitrate=256:nocabac:level_idc=30:bframes=0:global_header:threads=auto:partitions=all -ofps 15'
FFMPEG_TO_IMG = '%s -i "%s" -r 1 -t 00:00:01 -ss 00:20:00 -f image2 -y "%s"';
ADD_MP4_METADATA = '%s "%s" --metaEnema --stik Movie --freefree --overWrite --artist "%s" --title "%s" --album "%s" --year "%s"--genre "%s" --comment "%s" --artwork "%s"'
MPLAYER_TO_WAV = '%s -quiet -vo null -vc dummy -af volume=0,resample=44100:0:1 -ao pcm:waveheader:file="temp.wav" "%s"'
LAME_TO_MP3 = '%s -V7 -h -B 56 --vbr-new --tt "%s" --ta "%s" --tl "%s" --ty "%s" --ti "%s" "temp.wav" "%s"'
VIDEO_ROOT = '/mnt/video/design/video/'
GENRE = "UCLA Design | Media Arts"
@@LOCAL_ROOT = '/home/video/design/video/'
@@DEBUG = true
@@MYSQL_HOST = 'localhost'
@@MYSQL_USER = 'root'
@@MYSQL_PASS = ''
# Init and set config values
def initialize
if ENV['DMA_TRANSCODE_DEBUG']
@@DEBUG = ENV['DMA_TRANSCODE_DEBUG'] == 'true'
end
if ENV['DMA_TRANSCODE_LOCAL_ROOT']
@@LOCAL_ROOT = ENV['DMA_TRANSCODE_LOCAL_ROOT']
end
# set tool paths
cmd = `which mencoder`.chomp!
@@MENCODER = cmd if cmd != ''
cmd = `which mplayer`.chomp!
@@MPLAYER = cmd if cmd != ''
cmd = `which ffmpeg`.chomp!
@@FFMPEG = cmd if cmd != ''
cmd = `which AtomicParsley`.chomp!
@@ATOMICPARSLEY = cmd if cmd != ''
cmd = `which lame`.chomp!
@@LAME = cmd if cmd != ''
end
def transcode(path, outpath, artist, title, album, year, genre, comment)
# strip video root
path = path.gsub(VIDEO_ROOT, @@LOCAL_ROOT)
# get the output paths
mp4 = "%s/mp4/%s" % [outpath, path.gsub("rm", "mp4").gsub(@@LOCAL_ROOT, '')]
mp3 = "%s/mp3/%s" % [outpath, path.gsub("rm", "mp3").gsub(@@LOCAL_ROOT, '')]
img_format = "%s/img/%s" % [outpath, path.gsub(".rm", "_%d.jpg").gsub(@@LOCAL_ROOT, '')]
img = "%s/img/%s" % [outpath, path.gsub("rm", "jpg").gsub(@@LOCAL_ROOT, '')]
# create the mp4
if !@@DEBUG
if File::exists?(path)
print(MENCODER_TO_MP4 % [@@MENCODER, path, mp4])
print "\n"
system(MENCODER_TO_MP4 % [@@MENCODER, path, mp4])
else
print "------ ERROR ------\n COULD NOT FIND FILE #{path}.\n"
return
end
# create the thumbnail
if File::exists?(mp4)
print(FFMPEG_TO_IMG % [@@FFMPEG, mp4, img_format])
print "\n"
system(FFMPEG_TO_IMG % [@@FFMPEG, mp4, img_format])
File.rename(img_format % 1, img);
# add the metadata
print(ADD_MP4_METADATA % [@@ATOMICPARSLEY, mp4, artist, title, album, year, genre, comment, img])
print "\n"
system(ADD_MP4_METADATA % [@@ATOMICPARSLEY, mp4, artist, title, album, year, genre, comment, img])
else
print "------ ERROR ------\n COULD NOT FIND FILE #{mp4}.\n"
return
end
if File::exists?("temp.wav")
File.delete("temp.wav")
end
if File::exists?(path)
print(MPLAYER_TO_WAV % [@@MPLAYER, path])
print "\n"
system(MPLAYER_TO_WAV % [@@MPLAYER, path])
else
print "------ ERROR ------\n COULD NOT FIND FILE #{path}.\n"
return
end
if File::exists?("temp.wav")
print(LAME_TO_MP3 % [@@LAME, title, artist, album, year, img, mp3])
print "\n"
system(LAME_TO_MP3 % [@@LAME, title, artist, album, year, img, mp3])
else
print "------ ERROR ------\n COULD NOT FIND FILE temp.wav (MPLAYER must've failed).\n"
return
end
if File::exists?("temp.wav")
File.delete("temp.wav")
end
end
print "%s\n%s\n%s\n" % [mp4,mp3,img]
print " artist: %s\n title: %s\n album: %s\n year: %s\n genre: %s\ncomment: %s\n\n" % [artist, title, album, year, genre, comment]
end
def process_from_yaml(srcyaml, outpath)
f = open(srcyaml)
data = YAML.load(f)
f.close()
process_array(data, outpath)
end
def process_array(data, outpath)
# get output dir names
mp4_path = "%s/mp4/" % outpath;
mp3_path = "%s/mp3/" % outpath;
img_path = "%s/img/" % outpath;
# make output dirs
FileUtils.mkdir_p(mp4_path)
FileUtils.mkdir_p(mp3_path)
FileUtils.mkdir_p(img_path)
data['Video'].each do |k, video|
transcode(video['stream_link'],
outpath,
artist=video['author'],
title=video['title'],
album=video['series_name'],
year=DateTime.strptime(video['date_filmed'], "%Y-%m-%d %H:%M:%S").year,
genre=GENRE,
comment=video['description'])
end
end
def mysql_to_yaml
db = Mysql::new(@@MYSQL_HOST, @@MYSQL_USER, @@MYSQL_PASS, 'dma')
video_root = /^\/mnt\/video\/design\/video\//
videos = {"Video" => {}}
python_data = {"Video" => {}}
skipped = {"Video" => {}}
count = 1
skipped_count = 1
res = db.query('select * from dma_events where type="Lecture"')
res.each_hash do |row|
temp = {}
temp['author'] = row['subtitle']
temp['title'] = row['title']
temp['biography'] = ""
temp['description'] = row['longDescription']
temp['date_filmed'] = row['startDate']
temp['video_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".mp4")
temp['dl_url'] = temp['video_url']
temp['audio_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".mp3")
temp['image_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".jpg")
temp['is_public'] = true
if video_root.match(row['streamLink'])
videos['Video']["v#{count}"] = temp
pytemp = temp.clone;
pytemp.delete('biography');
pytemp.delete('video_url');
pytemp.delete('dl_url');
pytemp.delete('audio_url');
pytemp.delete('image_url');
pytemp.delete('is_public');
pytemp['stream_link'] = row['streamLink']
pytemp['series_name'] = "UCLA Design | Media Arts"
python_data['Video']["v#{count}"] = pytemp
count += 1
else
skipped['Video']["v#{skipped_count}"] = temp
skipped_count += 1
end
end
if (true)
# save fixture
File.open( "dma_video_php.yml", "w" ) do |the_file|
the_file.puts YAML::dump(videos)
end
# save python data
File.open( "dma_video_full.yml", "w" ) do |the_file|
the_file.puts YAML::dump(python_data)
end
# save log of skipped videos
File.open( "dma_video_skipped.yml", "w" ) do |the_file|
the_file.puts YAML::dump(skipped)
end
else
print YAML::dump(videos)
end
print count;
end
def process_ids(ids, outpath)
db = Mysql::new(@@MYSQL_HOST, @@MYSQL_USER, @@MYSQL_PASS, 'dma')
video_root = /^\/mnt\/video\/design\/video\//
videos = {"Video" => {}}
python_data = {"Video" => {}}
count = 1
skipped_count = 1
res = db.query("select * from dma_events where id IN (#{ids})")
res.each_hash do |row|
temp = {}
temp['author'] = row['subtitle']
temp['title'] = row['title']
temp['biography'] = ""
temp['description'] = row['longDescription']
temp['date_filmed'] = row['startDate']
temp['video_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".mp4")
temp['dl_url'] = temp['video_url']
temp['audio_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".mp3")
temp['image_url'] = row['streamLink'].gsub(video_root, "").gsub(/\.rm/, ".jpg")
temp['is_public'] = true
if video_root.match(row['streamLink'])
videos['Video']["v#{count}"] = temp
pytemp = temp.clone;
pytemp.delete('biography');
pytemp.delete('video_url');
pytemp.delete('dl_url');
pytemp.delete('audio_url');
pytemp.delete('image_url');
pytemp.delete('is_public');
pytemp['stream_link'] = row['streamLink']
pytemp['series_name'] = "UCLA Design | Media Arts"
python_data['Video']["v#{count}"] = pytemp
count += 1
end
end
# save fixture
File.open( "dma_video_php.yml", "w" ) do |the_file|
the_file.puts YAML::dump(videos)
end
process_array(python_data, outpath)
end
# HELPERS TO GET MYSQL CONFIG FROM THE USER
def ask(prompt, default)
loop do
print prompt, ' '
$stdout.flush
s = STDIN.gets
exit if s == nil
s.chomp!
if s != ''
return s
elsif s == ''
return default
end
end
end
def ask_for_config
@@MYSQL_HOST = ask("Please enter MySQL host [localhost]:", 'localhost')
@@MYSQL_USER = ask("Please enter MySQL user [root]:", 'root')
@@MYSQL_PASS = ask("Please enter MySQL pass []:", '')
end
end
# ===========================================================
# - Execute based on command line args
# ===========================================================
print "Welcome to the video.dma transcoder\n"
t = Transcoder.new
if !ARGV.empty?
case ARGV[0]
when 'gen_yaml'
t.ask_for_config
t.mysql_to_yaml
when 'process'
t.process_from_yaml(ARGV[1], ARGV[2], ARGV[3])
when 'process_ids'
t.ask_for_config
t.process_ids(ARGV[1], ARGV[2])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment