2010-06-15

Lecture videos on android phone with increased playback speed and pitch correction

I like watching lectures. Often, the lectures could use an increase in playback speed (I like 1.6x-1.7x). Additionally, I want to speed up the videos without having the professors sound like the chipmunks.

I have an android phone. It has limited space. Android doesn't seem to have a video player that supports variable speed video playback (especially with pitch correction; really, I don't want to stress the battery any more than I have to).

As far as I can tell, there are no applications available which make this a simple process.

After scouring the net and experimenting, I came up with this horrible little thing.

#!/bin/bash
VIDEO_BITRATE=128
AUDIO_BITRATE=128
AUDIO_SAMPLERATE=44100
SCREEN_WIDTH=480
SCREEN_HEIGHT=352
TARGET_FPS=24
SPEED=1.7
SEMITONE_SHIFT=$(echo "scale=4; (100-100*${SPEED})/${SPEED}" | bc)

mencoder "${1}" -o "${2}"\
-speed "${SPEED}"\
\
-oac faac\
-faacopts "br=${AUDIO_BITRATE}:mpeg=4:raw:object=2"\
-srate "${AUDIO_SAMPLERATE}"\
\
-af "volnorm=1,ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:${SEMITONE_SHIFT}:-90:0"\
\
-of lavf\
-lavfopts format=mp4\
\
-ovc x264\
-sws 9\
-x264encopts "nocabac:level_idc=30:bframes=0:threads=auto:turbo=1:global_header:subq=5:frameref=3:partitions=all:trellis=1:chroma_me:me=umh:bitrate=${VIDEO_BITRATE}"\
\
-ofps "${TARGET_FPS}"\
-vf "dsize=${SCREEN_WIDTH}:${SCREEN_HEIGHT}:2:scale=-8:-8:harddup"

Usage is
./script INVIDEO.xxx OUTVIDEO.mp4


This re-encodes the video as H.264 (one of the few formats the android supports). When speeding up the video, it's really important to use "-ofps" or you'll end up with a high fps video that will just waste space and bog down the android. Also, the command will only scale a video down if it's larger than the specified resolution (it won't scale up).

The audio is re-encoded as AAC after being run through a volume normalization filter and a pitch correction filter. For whatever reason, the scaletempo filter will not work with mencoder, so that's why I ended up using tap_pitch. You are limited to pitch correcting up to a speed of 2 with a single use of tap_pitch. Anything more and you supposedly have to chain the filters together (see bottom links).

And of course, the video and audio are then put into the mp4 container. There were reports that mencoder did this incorrectly, but it seemed to work fine.

You may want to toy with some of the environment variables to suit your needs. I picked a relatively low video bitrate to conserve space.

Relevant links:
http://ubuntuforums.org/showthread.php?t=1226982
http://www.axllent.org/docs/video/mencoder_for_iphone_android