DVD rip script for mencoder

I've got a little script that does all the annoying things like calculating the bitrate to reach a target size.
Code:
#!/bin/sh

command=mencoder
source=dvd://
mp3rate=96
mp3vol=4
xvidthreads=0
xvidrate=500
xvidqpel="noqpel"
xvidgmc="gmc"
xvidchopt="nochroma_opt"
cache="8192"
fps=25
parameters=""
filename=movie.avi
dump=""
type=""
filesize=""
seek=""
for parameter; {
	case "$parameter" in
		-dump) {
			# Dump the first pass output into a file.
			# This file will be used for the second pass,
			# and sound conversion will already be performed
			# during the first pass. So this should give a slight
			# speedup and allow much earlier access to the optical
			# drive.
			dump=1
		};;
		-dvd-sub-bottom) {
			# Show DVD subtitles at the bottom.
			parameters="$parameters -spuaa 16 -spualign 2"
		};;
		-noxvidgmc) {
			# Deactivate global motion compensation.
			xvidgmc="nogmc"
		};;
		-xvidqpel) {
			# Activate quarter pixel precission.
			xvidqpel="qpel"
		};;
		-xvidchopt) {
			# Activate chroma optimization.
			xvidchopt="chroma_opt"
		};;
		*://*) {
			# Set the video source.
			source="$parameter"
		};;
		-*) {
			# Set parameter type.
			type=`echo "$parameter"|sed -E 's|^-||1'`
			# Go to proceed parameter.
			continue
		};;
		*) {
			# Proceed parameters.
			case "$type" in
				size) {
					# Set wanted filesize in mb.
					# This will override '-xvidrate'.
					filesize=$parameter
				};;
				fps) {
					# Assume a diffrent frame rate when
					# calculating the length of the video.
					fps=$parameter
				};;
				mp3rate) {
					# Set mp3 rate in kbps.
					mp3rate=$parameter
				};;
				mp3gain) {
					# Increase volume (0-9).
					mp3vol=$parameter
				};;
				xvidrate) {
					# Set the video bitrate.
					xvidrate=$parameter
				};;
				xvidthreads) {
					# Set the number of threads.
					xvidthreads=$parameter
				};;
				o) {
					# Set the video filename.
					filename="$parameter"
				};;
				ss) {
					# Seeking a certain position in the
					# source video.
					seek="-ss $parameter"
				};;
				width) {
					# Scale the video to the given width.
					scale="-vf scale -zoom -xy $parameter"
				};;
				cache) {
					# Choose the media read cache size.
					cache="$parameter"
				};;
				*) {
					# Add unknown parameters.
					if [ "$type" ]; then
						parameters="$parameters -$type"
					fi
					parameters="$parameters $parameter"
				};;
			esac
		};;
	esac
	type=""
}

# Create working directory.
wrkdir="$filename.$(basename $0)"
if ! mkdir -p "$wrkdir"; then
	echo "Creating working directory '$wrkdir' failed"
	return 129
fi

# Prepare for clean operation.
rm "$wrkdir/xvid2pass.log" 2> /dev/null

if test -n "$dump"; then
	dumpfile="$wrkdir/pass1.avi"
	audio_first="-oac mp3lame -lameopts aq=0:abr:br=$mp3rate:vol=$mp3vol"
	audio_second="-oac copy"
	cache_first="-cache $cache"
	cache_second=""
	seek_first="$seek"
	seek_second=""
else
	dumpfile="/dev/null"
	audio_first="-nosound"
	audio_second="-oac mp3lame -lameopts aq=0:abr:br=$mp3rate:vol=$mp3vol"
	cache_first="-cache $cache"
	cache_second="-cache $cache"
	seek_first="$seek"
	seek_second="$seek"
fi

if ! [ -f "$wrkdir/pass1.log" -a -e "$dumpfile" ]; then
	if ! ($command $source $scale $cache_first -ovc xvid $audio_first \
		-xvidencopts pass=1:autoaspect:$xvidqpel:$xvidgmc:$xvidchopt \
		-xvidencopts threads=$xvidthreads \
		-passlogfile "$wrkdir/xvid2pass.log" \
		-o "$dumpfile" $seek_first $parameters \
		&& cp "$wrkdir/xvid2pass.log" "$wrkdir/pass1.log"); then
		error=$?
		echo "First pass failed."
		return $error
	fi
else
	echo "Skipping first pass, apparently already done."
fi

if test -n "$filesize"; then
	echo "****** determine video bitrate *******************************************"
	printf "%-16s %-55s %s\n" "* wanted size: " "${filesize}m" "*"
	# Calculate the length of the film in seconds.
	seconds=`export LANG=C ; wc -l "$wrkdir/pass1.log" | awk "{print((\\$1 - 3) / $fps);}"`
	printf "%-16s %-55s %s\n" "* length: " "${seconds}s" "*"
	printf "%-16s %-55s %s\n" "* mp3rate: " "${mp3rate}kb/s" "*"
	# Calculate bitrate to match size (mb).
	xvidrate=`awk "BEGIN {printf(\"%d\", ($filesize * 2^23) / (1000*$seconds) - $mp3rate);}"`
	printf "%-16s %-55s %s\n" "* xvidrate: " "${xvidrate}kb/s" "*"
	echo "**************************************************************************"
fi

test -n "$dump" && source="$dumpfile"

if cp "$wrkdir/pass1.log" "$wrkdir/xvid2pass.log"; then
	if ! $command "$source" $scale $cache_second \
		$audio_second -ovc xvid \
		-xvidencopts pass=2:bitrate=$xvidrate:autoaspect:$xvidqpel \
		-xvidencopts $xvidgmc:$xvidchopt:threads=$xvidthreads \
		-passlogfile "$wrkdir/xvid2pass.log" \
		-o "$filename" $seek_second $parameters; then
		error=$?
		echo "Second pass failed."
		return $error
	fi
else
	echo "Cannot perform second pass. Apparently the first pass failed."
	return 130
fi

The following command would rip a DVD into a 1450MB avi:

# ripXviD -size 1450 -mp3rate 192

Of course the script supports many more features such as subtitle placing or the -dump parameter that lets you take out the media after the first pass.
 
Back
Top