Log in

No account? Create an account
26 December 2008 @ 03:19 pm
mmplayer_encode: Re-encode AVI files for playing on PDAs with mmplayer  
This one is going to be a bit confusing, because it will talk about two different pieces of software with similar names: mplayer and mmplayer.  mplayer is a Linux/Unix movie player and converter.  mmplayer is a movie player designed for PDAs and other handheld devices.  mmplayer is available here: www.mmplayer.com/

I still use a Palm OS-based PDA.  I have a Treo 650 cell phone.  I was going to hold out for Android to become prevalent, but that might take a while, so I'm now eyeing the Palm Centro, assuming it can doe Bluetooth Dial-Up Networking (DUN).  Palm lost the PDA/handheld/smart phone wars years ago when they didn't realize that I/O was they key to victory, around 2000.  But I still have a soft spot for them.  And several hundred lines of custom Perl, shell, and C code that I use daily to synchronize my Palm phone into the rest of my life.  ANYWAYS, I use a tool called mmplayer to watch videos on my Treo.  Actually, I haven't done that since the novelty wore off (about 15 days after purchasing it), but that's not my point.

My point, and I do have one, is that this script, mmplayer_encode, uses mplayer and mencoder to transcode movies into the resolution, framerate, and audio bitrate that I consider near-optimal for my Treo 650.  The Treo has a 320x240 screen resolution, and while mmplayer can auto scale, doing so requires CPU resources.  Similarly, the built-in speaker is not BOSE quality, so a high audio bitrate is wasteful.  This scripts automatically rescales everything, resulting in a smaller file.  It also changes the video bitrate, but I'm not sure if that's technically changing the frames/second rate.  It might be the same thing.

jdimpson@artoo:~/bin$ mmplayer_encode
Usage: mmplayer_encode <avi to recode for mmplayer>

On completion, it creates a file witht he same name as the original, but replaces *.avi with *_treo650.avi.  One thing to note is that this script really should be called mmplayer_encode_treo650 or something, or even mmplayer_encode_jdimpson, because it's really configured to run for my particular phone.  A more general purpose version would have a lot more tuning options.



if [ ! -e "$SRC" ]; then
        ME=`basename $0`;
        echo "Usage: $ME <avi to recode for mmplayer>"
        exit 1;

DST=`basename "$SRC" .avi`_treo650.avi
VCODEC="msmpeg4"; # mmplayer for palmOS likes this
rm -f "$VID_LOG" "$AUD_LOG";

echo "re-encoding $SRC to $DST ratio $SCALE with video bitrate of $VBITRATE kbps, audio sample at $ASAMPLE kHz, audio bitrate at $ABITRATE kbps";

function first_video_pass {
        echo first video pass started;
        mencoder -nosound -vf scale=$XSCALE:-3 -ovc lavc -lavcopts vcodec=$VCODEC:vbitrate=$VBITRATE:vhq:keyint=250:vqmin=3:vpass=1:turbo -o "$DST" "$SRC" >> "$VID_LOG" 2>&1 ;
        echo first video pass finished;

function second_video_pass {
        echo second video pass started;
        mencoder -nosound -vf scale=$XSCALE:-3 -ovc lavc -lavcopts vcodec=$VCODEC:vbitrate=$VBITRATE:vhq:keyint=250:vqmin=3:vpass=2 -o "$DST" "$SRC" >> "$VID_LOG" 2>&1 ;
        echo second video pass finished;

function audio_dump {
        echo audio dump started;
        mplayer -aid 1 -dumpaudio -dumpfile "$DST.dump" "$SRC" >> "$AUD_LOG" 2>&1 ;
        echo audio dump finished;

function audio_pass {
        echo audio pass started;
        lame --cbr --mp3input --resample $ASAMPLE -b $ABITRATE "$DST.dump" "$DST.dump.mp3" >> "$AUD_LOG" 2>&1 ;
        mv "$DST.dump.mp3" "$DST.dump"
        echo audio pass finished;

function merge {
        echo merge started;
        avimerge -i "$DST" -o "$DST.tmp" -p "$DST.dump" -a 1
        rm -f "$DST.dump"
        mv "$DST.tmp" "$DST"
        echo merge finished;

( first_video_pass; second_video_pass ) &
sleep 5;
( audio_dump; audio_pass ) &

exit 0;

It starts up with the command line check and usage statement, then defines some variables.  These are the ones that would be reconfigurable with command line switches in a more perfect world.  The SCALE and XSCALE values control the resolution (so-separated because they are needed by separate applications).  VBITRATE affects the video bitrate. ASAMPLE sets the audio sample size, and ABITRATE sets the audio compression ratio.

Then it defines four bash functions.  I'll skip these for a second.  After the functions are defined, it does the following:
  1. Kicks off one thread to do a two pass re-encoding of JUST the video.
  2. Waits 5 seconds for the video thread to start up
  3. Kicks off another thread to dump out then re-encode the audio
  4. Waits for both threads to finish
  5. Then merges the new audio back with the video.
The two pass video re-encoding (which are the first two bash functions defined) are two calls to mencoder.  The two passes are part of how the lavc (libavcodec) driver in mencoder works to optimize the re-encoding process. To be honest, I didn't do any exhaustive testing to see what the right re-encoding options were.  I think I just found these two command lines somewhere on the net and incorporated them.

Similarly, I don't recall now why I split the audio out and process it separately.  It's either because one has to do that when using the two phase video processing, or, more likely, because I wanted to take advantage of my then dual CPU system (now replaced by single Dua Core CPU system).  The audio is dumped out with mplayer, then resampled with lame.

The audio and video are merged back together with avimerge.  This is part of the transcode suite of tools, which has a lot of functionality in common with mplayer/mencoder., including the fact that both are hard to use.  I've focused my limited mential facilities on learning mplayer, but to date I haven't figured out how to use mplayer/mencoder to merge audio with video.  I didn't try hard, because I quickly found avimerge, and I'm not a glutton for punishment.  But it would be nice to remove the dependency on the transcode software package. 

BTW, everything gets written to an audio or video log file for debugging.  The result is a file with lower CPU requirements, optimized for 320x240 resolution displays.