#!/bin/bash
#
# Make the highest quality possible NTSC
# dvd's from almost anything.
#
# Requires: mplayer, ffmpeg, and sox.
#
# An eternal "work in progress".
#
# Phil Ehrens <phil@slug.org>
#
vbitrate=5000
abitrate=224
copy_audio=0
# Set bassboost to "1" to boost the audio bass.
bassboost=0
# Audio gain factor - Less than 1 to reduce.
audiogain=1
# OVERRIDE target aspect ratio - 4:3, 16:9 or 2.35
# 2.35 will be letterboxed into 16:9 (anamorphic).
# Normally the asr will be dynamically determined,
# but if the script fails to get it right (which
# will be the case with source that is 720x480
# anamorphic for example) setting it here will
# override the calculated value.
uasr=""
##
## - MPLAYER FILTER OPTIONS -
##
#
# Note the "echo", which is required.
#
# for ass styled subs in .mkv container - perfectly useful in
# general however. Best not to change it if you don't know
# what you're up to.
#filters='echo -ass -embeddedfonts -sub $file.ass -sid 0 -aid 1'
# for anime:
#filters='echo -vf hqdn3d=3:3:0:0,unsharp=l3x3:0.1,hqdn3d=3:3:0:0,eq2=0.8'
# for old-school anime on VHS - denoising and sharping:
#filters='echo -vf pp7,hqdn3d=7:6:7:7,unsharp=l3x3:0.4,noise=1h'
# example of a full-on mkv with ass invocation
#filters='echo -vf eq2=0.9 -ass -ass-force-style main.PrimaryColor=\&H0077B7D9,main.OutlineColor=\&H000A0A3C,main.Fontsize=36,main.MarginV=25,main.Outline=2,main.Shadow=2 -ass -sid 0 -slang en'
# example for a video file with an smi or styled srt subscript
#filters='echo -ass -sub $file.srt -ass-force-style Fontname=Jester,Fontsize=22,PrimaryColour=\&H0072D1F5,SecondaryColour=\&H000000FF,OutlineColour=\&H00121D2F,BackColour=\&H80000000,Spacing=1,Outline=1.5,Shadow=0,MarginL=10,MarginR=10,MarginV=20 -vf unsharp=l3x3:0.01,eq2=1.1:1.1:0.02'
# Always use this unsharp - The eq2 options (defaults shown) are:
# gamma:contrast:brightness:saturation:red:green:blue
# where red:green:blue can be used to adjust the hue.
filters='echo -vf unsharp=l3x3:0.01,eq2=1:1:0:1:1:1:1'
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## END OF USER OPTIONS
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ ! -z "$1" ] && files="$@";
for arg in $files ;
do
# strip the .avi, .mkv, .mov, or .ogm file extension
file=`echo $arg | sed -e 's/\.[amo][vkpgo][iv4m]$//'`
ext=`echo $arg | sed -e 's/^.*\.//'`
# Get source info for calculations
foo=`mplayer -identify -frames 0 -ao null -vo null $arg 2>/dev/null |grep -oP ID_.+=[0-9\.]+`
eval "$foo";
if [ "$ID_VIDEO_FPS" == "23.976" ]
then
framerate=24000/1001
dfps=""
pal2ntsc=0
elif [ "$ID_VIDEO_FPS" == "25" ] || [ "$ID_VIDEO_FPS" == "25.000" ]
then
framerate=24000/1001
dfps="-fps 24000/1001"
pal2ntsc=1;
elif [ "$ID_VIDEO_FPS" == "29.970" ]
then
framerate=30000/1001
dfps=""
pal2ntsc=0;
elif [ "$ID_VIDEO_FPS" == "59.940" ]
then
framerate=30000/1001
dfps=""
pal2ntsc=0;
else
echo "Don't know how to handle $ID_VIDEO_FPS fps content, sorry."
exit
fi
if [ "$uasr" == "" ]
then
asr=`bc -l << _EOF
define asr(w,h) {
if (w/h >= 2.0) return (4);
if (w/h >= 1.6) return (3);
if (w/h >= 0.0) return (2);
}
asr($ID_VIDEO_WIDTH,$ID_VIDEO_HEIGHT)
_EOF
`
else
asr="$uasr"
fi
## - Overscan compensation and scaling geometry -
if [ "$asr" == "3" ] || [ "$asr" == "16:9" ]
then
## For 16:9 material on a widescreen TV:
overscan='-padleft 32 -padright 32 -padtop 16 -padbottom 16'
geometry=656x448
asr=16:9
elif [ "$asr" == "4" ] || [ "$asr" == "2.20" ] || [ "$asr" == "2.35" ]
then
## For widescreen (2.35 asr) letterboxed into 16:9:
overscan='-padleft 32 -padright 32 -padtop 64 -padbottom 64'
geometry=656x352
asr=16:9
elif [ "$asr" == "2" ] || [ "$asr" == "4:3" ]
then
## For 4:3 material:
overscan='-padleft 32 -padright 32 -padtop 16 -padbottom 16'
geometry=656x448
asr=4:3
else
echo "* Don't know how to handle aspect ratio $asr."
exit
fi
echo "* Encode will be $asr at $framerate fps"
echo ""
if [ "$copy_audio" == "0" ]
then
## AUDIO PRE-PROCESSING STAGE ##
if [ ! -f audiodump.wav ]
then
# dump the audio as pcm
mplayer -ao pcm:fast -vo null -vc dummy $arg > /dev/null 2>&1 &
echo "mplayer: dumping pcm audio from $arg to audiodump.wav"
while ps -p $! > /dev/null; do printf . ; sleep 1; done ; echo
fi
# adjust the volume downward slightly
if [ "$audiogain" != "1" ] ; then
sox -v "$audiogain" audiodump.wav output.wav &
echo "sox: reducing audio gain to 0.7"
while ps -p $! > /dev/null; do printf . ; sleep 1; done ; echo
mv -f output.wav audiodump.wav
fi
# For PAL -> NTSC
if [ "$pal2ntsc" == "1" ] ; then
sox audiodump.wav output.wav speed 0.95904 &
echo "sox: Changing audio speed from PAL to NTSC"
while ps -p $! > /dev/null; do printf . ; sleep 1; done ; echo
mv -f output.wav audiodump.wav
fi
# boost the bass!!
if [ "$bassboost" == "1" ] ; then
sox audiodump.wav output.wav mcompand \
"0.005,0.1 -60,-30 0 0 0" 800 "0.005,0.1 -60,-60 0 0 0" &
echo "sox: boosting low level bass frequencies"
while ps -p $! > /dev/null; do printf . ; sleep 1; done ; echo
mv -f output.wav audiodump.wav
fi
audio_opts="-i audiodump.wav"
else
audio_opts="-acodec copy -i $arg -map 0:0 -map 1:1"
fi
rm -f ${file}.yuv
mkfifo ${file}.yuv
ffilters=`eval $filters`
mplayer $arg $dfps $ffilters -vo yuv4mpeg:file=${file}.yuv \
-cache 8192 -noframedrop -ao null -really-quiet < /dev/null &
ffmpeg -f yuv4mpegpipe -i ${file}.yuv $audio_opts \
-target ntsc-dvd -r $framerate -aspect $asr -s $geometry \
$overscan -cmp 3 -subcmp 3 -qcomp 0.7 -qblur 0.3 -mbd rd \
-ab ${abitrate}k -b ${vbitrate}k -trellis 2 -pass 1 \
-passlogfile $file -y $file.mpg
rm -f ${file}.yuv
mkfifo ${file}.yuv
mplayer $arg $dfps $ffilters -vo yuv4mpeg:file=${file}.yuv \
-cache 8192 -noframedrop -ao null -really-quiet < /dev/null &
ffmpeg -f yuv4mpegpipe -i ${file}.yuv $audio_opts \
-target ntsc-dvd -r $framerate -aspect $asr -s $geometry \
$overscan -cmp 3 -subcmp 3 -qcomp 0.7 -qblur 0.3 -mbd rd \
-ab ${abitrate}k -b ${vbitrate}k -trellis 2 -dia_size 4 \
-pass 2 -passlogfile $file -y $file.mpg
rm -f audiodump.wav ${file}.yuv passlog-*.log
done;
mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf \
-vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 \
-lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:\
keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 \
-o movie.mpg movie.avi
mencoder -oac copy -ovc lavc -of mpeg -mpegopts format=dvd:tsaf:telecine \
-vf scale=720:480,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:\
vrc_maxrate=9800:vbitrate=5000:keyint=15:vstrict=0:aspect=16/9 -ofps 24000/1001 \
-o movie.mpg movie.avi
-lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=8000:\
keyint=15:trell:mbd=2:precmp=2:subcmp=2:cmp=2:dia=-10:predia=-10:cbp:mv0:\
vqmin=1:lmin=1:dc=10:vstrict=0
-channels 6 -oac lavc -lavcopts acodec=ac3:abitrate=384