Created
April 5, 2009 17:21
-
-
Save brysonian/90487 to your computer and use it in GitHub Desktop.
Script to transcode DMA .rm videos to mp4 and mp3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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