Making Flv Flash Video Seekable
The short version:
ffmpeg -i video.flv -vcodec copy -acodec copy video.avi
The story
A few weeks ago I got interested in Google TechTalks, UC Berkeley webcasts and a number of other stuff published via YouTube and Google Video which I could watch without self-reproach for wasting my time. I wrote a few scripts to download playlists in a convenient manner (both video services do not support HTTP ranges, so it requires a bit of jumping) - and now have a few dozen of flv videos to watch through.
Mplayer is great at playing Flash Video, except for a few files which it plays at a wrong framerate (xine and vlc handle those for me), but the fun ends when you need to search halfway into an hour-long talk. The fastest way to do that in mplayer is probably setting playback speed to 10x and just waiting. But there's a better way - remultiplexing flv into avi without recoding.
mencoder could not to it correctly, even when mkvmerge was used for after-multiplexing. Ffmpeg could. It's almost as fast as cp(1), so it's really convenient - and I haven't experienced any audio-video sync problems yet.
Interleaving overhead
AVI interleaving appears to be quite wasteful. A 146Mb flv turned into a 231Mb avi. But there's a very efficient format named Matroska (MKV). You can easily encode an avi to an mkv with
mkvmerge(1), which is a part of
mkvtoolnix suite:
mkvmerge -o video.mkv video.avi
And the 231Mb avi turns back into a 144Mb mkv, which is fully supported by almost any video player - and perfectly seekable.
The dumb script - flv2mkv.sh
#!/bin/sh
while [ $# -ge 1 ];do
flvfile=$1
shift
base=${flvfile%.flv}
avifile=$base.avi
mkvfile=$base.mkv
if [ -s $mkvfile ];then
continue
fi
rm -f $avifile $mkvfile
ffmpeg -i $flvfile -vcodec copy -acodec copy -y $avifile
mkvmerge -o $mkvfile $avifile
rm $avifile
done