Transcoding video for Motorola Droid on Linux
There’s a neat video player available for android called yxFlash, which can play a wide variety of formats that the built-in player cannot. The droid does a decent job of playing back foreign video formats such as wmv, divx, flv, mkv, but sadly it doesn’t quite have enough grunt to play back high resolution clips smoothly.
So, here’s how to use ffmpeg in Linux to transcode and resize pretty much any video to a format that the Motorola Droid or Milestone plays with the greatest ease – h264 & aac. The command also resizes the video to 480 pixels high, so it’s the right size for the droid / milestone’s screen.
Firstly find out the width and height of the video so we can figure out what the new width must be in order to keep the aspect ratio when resizing to 480 pixels high:
ffplay -stats -vn -an file.flv 2>&1 | perl -lne 'if(/\s(\d+)x(\d+),/){print "$1\t$2"}'
Calculate the new width = (480/height) * width.
Then go ahead and transcode the video:
ffmpeg -i file.flv -s 640x480 -vcodec libx264 -b 480k -acodec libfaac -ab 96k -sameq -pass 1 file.mp4
Where 640 is the new width from the calculation above.
Here is a script which does the above. Run it with a video’s filename as the single parameter, and a [whatever].mp4 file will be created. Tested in Ubuntu 9. (Doesn’t work in 8 unless you change libx264 with x264, and libfaac with aac, after having recompiled ffmpeg to have aac support!)
#!/bin/bash info=$(ffplay -stats -vn -an "$1" 2>&1 | perl -lne ‘if(/s(d+)x(d+)[ ,]/){print "$1t$2"}’) width=`echo "$info" | cut -f1` height=`echo "$info" | cut -f2` newwidth=`perl -e "print int($width * (480/$height))"` # some codecs require width to be a multiple of 16 :- padding=`perle"print (16($newwidth % 16));"` if [ $padding == 16 ] ; then stretched=$newwidth ; else stretched=`expr $padding + $newwidth` ; fi ffmpeg -i "$1" -s ${stretched}x480 -vcodec libx264 -b 480k -acodec libfaac -ab 96k -sameq -pass 1 "$(echo "$1" | perl -pe ‘s/.w+$/.mp4/’)" if [ -e ffmpeg2pass-0.log ] ; then rm ffmpeg2pass-0.log ; fi if [ -e x264_2pass.log ] ; then rm x264_2pass.log ; fi
Of course you can use this to batch convert a bunch of videos in the usual linux way:
for i in *.flv ; do droidify-video.sh "$i" ; done