I have a bunch of photography tutorials in the Flash video .flv format which I want to watch on my iPad. As you may be aware, everything with the name Flash in it doesn’t play too well on Apple’s iOS devices. VLC Media Player for iOS is able to play the .flv format but Apple doesn’t allow 3rd party software devs to use the built-in H.264 hardware acceleration for video playback. As as result, .flv videos usually don’t play very well on iOS devices. Besides, I prefer to manage my video collection in iTunes instead of dragging every clip onto an app icon.
A software called MPEG StreamClip is a good starting point to convert all kinds of video files to something that plays on iOS devices like the iPad. The software needs Perian to be able to handle the Flash video format. Perian itself uses ffmpeg to play Flash videos and plugs in nicely into Mac OS X so you can play Flash videos with Quicktime Player as well.
The .flv Flash video format is a container for different video and audio formats. A while back, On2 VP6 was the standard video codec for Flash video. With hardware video accelerators becoming more popular in mobile devices, many .flv videos are encoded with H.264/MPEG-4 AVC today.
For some reason, quite a few of my Flash videos don’t play very well with Perian. There’s stutter, there are those typical compression artifacts and video/audio is off-sync at times. It may very well be that there’s something odd with my Flash videos but with VLC for Mac and on my Windows XP virtual machine, those videos play back with no visible or audible problems. Since MPEG StreamClip uses Perian, the converted .mp4 videos show the same problems. But wait a second. If both, .flv and .mp4 make use of the same video format (H.264/MPEG-4 AVC) shouldn’t it be dead simple to extract the H.264 video stream and the audio stream and remux them to an iTunes-compatible .mp4 container, without transcoding the entire video?
The good news is: yes, it actually is! And it’s free as well. The bad news is (well, for some): it’s only for the command line savvy. All you need is ffmpeg. You may want to build your own ffmpeg binary but if you’re too lazy, just download my ffmpeg binary. The source for this binary is taken straight from the latest SVN trunk so don’t expect it to work for anything other than explained in this post. I also had to apply a small fix in utils.c so ffmpeg doesn’t abort with “error, non monotone timestamps n >= n” while remuxing slightly out-of-sync Flash videos. I linked all dependent libraries (like x264) statically so it’s just one large binary.
FFmpeg version SVN-r25783, Copyright (c) 2000-2010 the FFmpeg developers built on Nov 22 2010 20:50:32 with gcc 4.2.1 (Apple Inc. build 5664) configuration: --enable-libfaac --enable-libx264 --enable-nonfree --disable-shared --enable-libmp3lame --enable-gpl --enable-postproc --arch=x86_64 libavutil 50.33. 0 / 50.33. 0 libavcore 0.13. 0 / 0.13. 0 libavcodec 52.97. 0 / 52.97. 0 libavformat 52.85. 0 / 52.85. 0 libavdevice 52. 2. 2 / 52. 2. 2 libavfilter 1.62. 0 / 1.62. 0 libswscale 0.12. 0 / 0.12. 0 libpostproc 51. 2. 0 / 51. 2. 0 Hyper fast Audio and Video encoder
Remuxing .flv to an .mp4 container
Let’s say you want to convert in.flv to out.mp4. Your in.flv has an embedded H.264 video stream and an AAC audio stream. Your target format is an iTunes-compatible .mp4 container with an embedded H.264 stream. Use this command to remux the .flv to .mp4:
ffmpeg -vcodec copy -acodec copy -i in.flv out.mp4
That’s it! Ain’t that simple? And because there’s no transcoding involved, this process is super fast!
Transcode .flv to an .mp4 container
Let’s say you want to convert a Flash video that contains an On2 VP6 video stream. You can’t simply remux the streams into an .mp4 container in this situation. The video stream needs to be transcoded from VP6 to MPEG-4 in order to be iTunes-compatible. Use this command to transcode .flv to .mp4:
ffmpeg -sameq -i in.flv out.mp4
Obviously, transcoding from one video format into another will take a whole lot more time than remuxing.
Using ffmpeg for remuxing or transcoding Flash videos seems to deliver better results compared to all other video converters I was able to find for the Mac (not that there are many).
Let’s say you want to remux all .flv (containing a H.264 stream) video files in a directory to .mp4. Here’s a simple shell script to do this:
#!/bin/sh find . -name '*.flv' -print0 | while read -d $'\0' file ; do echo "remuxing: $file" ffmpeg -vcodec copy -acodec copy -i "$file" "$file.mp4" < /dev/null done
Want to transcode older (VP6) .flv video files to .mp4? There’s a script for that:
#!/bin/sh find . -name '*.flv' -print0 | while read -d $'\0' file ; do echo "transcoding: $file" ffmpeg -sameq -i "$file" "$file.mp4" < /dev/null done
MediaInfo Mac is an extremely useful tool if you want to have a look at the metadata of a video container. I use it a lot to decide whether I need to remux or transcode video files.