I did this a while ago with around 200 of my DVD's. As you've hinted at, I had the ripping and re-encoding separate. Here's how I did it:
-Use mplayer to dump the raw dvd mpeg data to a file.
-Use mencoder to do the re-encode.
These are the scripts I used. Put them into a ripping directory. To rip, run 'ripdvd NAME_OF_FILM titlenumber'. The main title number is usually 1, so it's the default if you don't supply a number. (You can do the other titles too if you want, just provide a different name, e.g. './ripdvd moviename-track1', './ripdvd moviename-track2' etc.
While you're ripping, start up (in a new terminal) the 'multiencode' script. It doesn't have any arguments. It basically keeps scanning the directory to see if there are any new files to encode. If there are, it does it. Otherwise it goes to sleep for a bit then checks again. I'd run it with a high nice value. You can start up multiple instances of the 'multiencode' script, if you've got multiple cpus or cores. They
shouldn't interfere with each other.
Overall, it cut the
effective encode time (that which I had to spend in front of the machine) to about 5 minutes per disc.
Okay, first the ripping script, which is dead simple
Code:
#!/bin/bash
#Arguments are name and title number (defaults to 1)
basename=$1
if [ $2 ]
then
title=$2
else
title=1
fi
echo "Dumping title $title from $basename"
mplayer -dumpstream -dumpfile ${basename}.dump dvd://${title}
touch ${basename}-ready
Now the encoder
Code:
#!/bin/sh
#This sets some parameters for the encoding
targetsize=750 # Target size of the final xvid in MB
abitrate=192 # Audio bitrate (It'll come out as 2 channel
vfscale='scale=640:-2'
vfhq='hqdn3d=2:1.5:3'
#vfpp='pp=ac/fd'
#vfilmdeint='filmdint'
#build up the global filter line here
vfbaseline="${vfscale},${vfhq}"
vhq=4
aid=128 #This is the default audio language (english) to extract.
#This returns the crop values from cropdetect. Args are filename and position (in frames)
function cropparams {
cropval=$(mplayer -vo null -ao null -vf cropdetect $1 -ss $2 -frames 3 2>&1 \
| grep 'crop=[0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+' -o \
| sed -e 's/crop=//' )
echo $cropval
}
#This gets a load of crop values and picks the most common (best?) one
#parameters are $1=base name $2=length of file
function getbestcrop {
cropstep=$(( ${2%.*} / 10 ))
length=${2%.*}
for (( x=0;x<=$length;x+=${cropstep%.*} ))
do
cropparams ${1}.dump $x >> ${1}-crops
uniquecrops=$( cat ${1}-crops | sort | uniq )
for curcrop in ${uniquecrops}
do
curcount=$( grep -c ${curcrop} ${1}-crops )
if [[ $curcount -gt $bestcount ]]
then
bestcount=$curcount
bestcrop=$curcrop
fi
done
done
rm ${1}-crops
echo $bestcrop
}
#**************************************************************************
#The main bit of the script. It loops endlessly, looking for new dump files
#**************************************************************************
while [ 1 ]
do
#Get list of all FINISHED rips
for cur in `ls *-ready`
do
curbase=${cur%-ready}
#Have they been processed already? are they running at the moment?
if [ -e ${curbase}-xvid.avi -o -e ${curbase}-working ]
then
echo " Not processing $curbase "
else
echo "Doing ${curbase}"
touch ${curbase}-working
vidlength=`midentify "${curbase}.dump" | grep 'ID_LENGTH=' | sed 's/ID_LENGTH=//'`
cropparams=$(getbestcrop $curbase $vidlength)
echo "Cropping parameters are $cropparams"
vfcrop="crop=$cropparams"
vfline="$vfcrop,$vfbaseline"
echo "Current filters are $vfline"
#Calculate the bitrate
audiosize=$(( $abitrate*1000*${vidlength%.*}/1024/1024/8 ))
videosize=$(( ($targetsize-$audiosize)*1024 ))
mencoder "${curbase}.dump" -ovc xvid -xvidencopts \
bitrate=-$videosize:vhq=$vhq:quant_type=h263:pass=1:turbo \
-vf "$vfline" -passlogfile "${curbase}-xvid.log" \
-oac copy -o /dev/null
mencoder "${curbase}.dump" -ovc xvid -xvidencopts \
bitrate=-$videosize:vhq=$vhq:quant_type=h263:pass=2 \
-vf "$vfline" -oac mp3lame -lameopts preset=$abitrate \
-aid $aid -passlogfile "${curbase}-xvid.log" \
-o "${curbase}-xvid.avi"
#Clean up
rm ${curbase}-working
rm ${curbase}-ready
rm ${curbase}.dump
rm ${curbase}-xvid.log
fi
done
echo "Going to sleep, nothing to do"
sleep 10
done
echo "All done"
I should say that the script is very far from perfect. The 'autocropping' is a bit ugly, but worked for most of my discs. The quality settings are okay, but you can get better (with a longer encode time). Also, you might need a deinterlace filter for some discs (I did).
You'll probably want to tweak some things in it, since it was for backing my dvds up onto a cd so I could watch on my divx player. You might want to change the file size, use a fixed bitrate or whatever. Also, this encodes into xvid, you might want something else.
There's plenty of other encoding scripts around, have a search of this site.
Anyway, it should give you the idea, hope it helps.