Thursday, October 1, 2009

Nostalgic: Encode DVD Rips

There are now a lot of easy ways to encode DVDs on Linux. I don't even use Linux much any more, and on OS X I'd just use Handbrake. Anyway, this is a script I used to use:

#!/bin/sh

# NAME
# xcode.sh
#
# DESCRIPTION
# Encode a [concatenated] VOB file into an MPEG4/MP3 video
# using mencoder (a la mplayer) and create a lower quality
# video for iPods using ffmpeg.
#
# The reason I wrote this was because I had a bunch of VOBs
# and concatenated them together. Then I decided, "Hey, it's
# OK to lose some quality to gain more disk space!"
#
# DEPENDENCIES
# * mplayer (transcode VOBs to AVI)
# * ffmpeg (transcode to iPod supported format)
# * vobcopy (optional - to rip VOBs from movie DVD)
#
# KNOWN BUGS
# * Requires the user to rip the DVD manually using vobcopy
# or similar application and manually concatenate the
# appropriate VOB files into 1 big VOB which this script
# then will transcode.
# * The output video may be too large for a single 700MB CD.
# * The output video is not the proper format (h.264/aac)
# for a Video iPod.
# * Command line options parsing and features are pathetic.
# * Doesn't handle cropping at all (no -vf cropdetect, etc.)
#
# USAGE
# you can use mplayer to dump a dvd title
# # mplayer dvd://1 -dumpstream -dumpfile title1.vob
#
# or, you can rip the whole dvd with vobcopy
# # mount -o ro /dev/dvd /mnt
# # cd ~/dvd && vobcopy -I /mnt -m
#
# determine which VOBs you want and concatenate them
# # cat VTS_01_[1-8].xVOB > movie.vob
#
# ensure xcode.sh is configured right (srcdir and outdir)
# # vi xcode.sh
#
# run it to process fullscreen (4:3) video (-w for 16:9)
# # xcode.sh -f movie
#
# LICENSE
# Public domain. Distribute freely.
#
# This script is provided "as is" and comes with no warranty
# whatsoever. Any liability and responsibility is hereby
# fully disclaimed. Use at your own risk.
#

#################################################################
#
# STATIC CONFIGURATION
#
#################################################################

# where to find VOB
srcdir="/mnt/media/dvdrip"
# if you uncomment the following, find comment out line 100, also
#srcdir="`pwd`"

# here to dump the products
outdir="/home/packetjunkie/movies"

# 16:9 (widescreen)
widescale="640:360"

# 4:3 (fullscreen)
fullscale="640:480"

# default
scale=$widescale

# video bitrate
vbr="700"

# logfile
log="${outdir}/xcode.log"


#################################################################
#
# SETTINGS DETERMINED AT RUN TIME
#
#################################################################

# aspect ratio?
if [ "x$2" != "x" ] ; then
if [ "$1" = "-w" ] ; then scale=$widescale; shift; fi
if [ "$1" = "-f" ] ; then scale=$fullscale; shift; fi
fi

# movie?
if [ "x$1" = "x" ] ; then echo "Usage: $0 [-w|-f] <movie>"; exit 1; fi
movie="$1"
srcdir="${srcdir}/${movie}"
echo "[`date +"%F %T"`] $movie - scale = $scale - $srcdir" >> "$log"

# determine path information based on settings
vob="${srcdir}/${movie}.vob"
avi="${outdir}/${movie}.avi"
pod="${outdir}/${movie}.mp4"

tmp="${outdir}/${movie}.vob.avi"
snd="${outdir}/${movie}.snd.avi"
prv="${outdir}/${movie}.prv.avi"


#################################################################
#
# DO THE ACTUAL WORK
#
#################################################################

# fix broken index
echo "[`date +"%F %T"`] $movie - fixing index" >> "$log"
mencoder "${vob}" -o "${tmp}" -ovc copy -oac copy

# encode audio
echo "[`date +"%F %T"`] $movie - encoding audio" >> "$log"
mencoder "${tmp}" -ovc frameno -o "${snd}" \
-oac mp3lame \
-lameopts abr:br=128 \
-alang en

# pass 1
echo "[`date +"%F %T"`] $movie - pass 1" >> "$log"
mencoder -oac copy -o /dev/null \
-ovc lavc \
-lavcopts vcodec=mpeg4:vbitrate=$vbr:vhq:vpass=1 \
-vf scale=$scale \
-ss 0:20 -endpos 0:30 \
"${tmp}"

# pass 2
echo "[`date +"%F %T"`] $movie - pass 2" >> "$log"
mencoder -oac copy -o "${prv}" \
-ovc lavc \
-lavcopts vcodec=mpeg4:vbitrate=$vbr:vhq:vpass=2 \
-vf scale=$scale \
-ss 0:20 -endpos 0:30 \
"${tmp}"

# final
echo "[`date +"%F %T"`] $movie - fully transcoding" >> "$log"
mencoder -oac copy -o /dev/null \
-ovc lavc \
-lavcopts vcodec=mpeg4:vbitrate=$vbr:vhq:vpass=1:vqmin=2:vqmax=31 \
-vf scale=$scale \
"${tmp}"
mencoder -oac copy -o "${avi}" \
-ovc lavc \
-lavcopts vcodec=mpeg4:vbitrate=$vbr:vhq:vpass=2:vqmin=2:vqmax=31 \
-vf scale=$scale \
"${tmp}"

# clean
echo "[`date +"%F %T"`] $movie - cleaning" >> "$log"
rm -f "${tmp}" "${snd}" "${prv}"
rm -f divx2pass.log

# ipod
echo "[`date +"%F %T"`] $movie - making ipod mpeg4" >> "$log"

# reduced resolution for ipod
if [ "$scale" = "640:480" ] ; then
podscale="320x240"
aspect="4:3"
else
podscale="320x180"
aspect="16:9"
fi

# process it
ffmpeg -i "${avi}" -f mp4 -vcodec mpeg4 \
-maxrate 1000 -b 700 -qmin 3 -qmax 5 -bufsize 4096 -g 300 \
-acodec aac -ab 192 -s $podscale -aspect $aspect "${pod}"

# done
(echo "[`date +"%F %T"`] $movie - finished";echo) >> "$log"