Why is H.264 video so much faster in an FLV container than in an MP4 container

.mp4flash-playerflvstreamingvideo

I am developing a tube site, and currently having issues with H.264 format. I noticed that YouTube put their hi-def videos into an MP4 container, so logically I did the same.

Next, I installed mod_h264_streaming for lighttpd to make streaming and timeline-scrubbing work.

The problem is that large files (>500MB at somewhat high resolution) take forever to even start buffering (I read that Flowplayer and other Flash players need to download metadata first). I moved the xmov atom to the front of the file with MP4Box (I tried Qt QuickStart too), but that didn’t help.

Next, I read that I need to interleave audio tracks, so I did that too. This caused no change: the videos were still slow.

So I tried putting the exact same H.264 movie into an FLV container, and the playback buffering started almost instantly — no slowness.

So what am I missing here? Why would I choose MP4 container with the module mod_264_streaming, which seems super-slow, over a regular FLV container with lighttpd’s built-in mod_flv_streaming? Obviously, many websites pick the MP4 container, but I fail to understand why.

And as a side question, I tried using the HTML5 <video> tag to try the same H.264 MP4 movie, and the scrubbing was lightning fast! I looked into lighttpd’s log file, and I noticed that Flash players append video.mp4?start=234 each time the timeline is scrubbed, whereas browsers using the native HTML5 <video> tag do no such thing. Is this some sort of limitation of Flash? Why can’t Flash streaming be as fast as HTML5 streaming?

Best Answer

TL;DR: MP4 is used when the video site stores more metadata in the video than FLV supports, or uses an audio codec that FLV doesn't support. FLV's simplicity and for-streaming design makes it a good choice if you don't have a good reason to use MP4.

As for flash's timeline scrubbing, I have no idea why it does that since I never coded flash, but it's possible that it's a knob it uses, or something that works specifically with adobe's streaming server in order to seek in the file. It also works as a way to stop the pesky user from keeping the file on his disk.


Some stuff you already knew:

There are fundamental differences between the FLV and MP4 (aka isomedia) containers. FLV was devised by Adobe from the start as a streaming container, and it's really damn simple. All it does is send a video packet, then audio packet, then video packet... However, it only supports very few codecs, and no metadata other than timestamps in miliseconds. Unless you need MP4-specific features, you would do just fine with FLV.

ISO media, on the other hand, is based on Apple's MOV container. It's separated in atoms, and there is a particular atom, moov, that needs to be decoded before any other atoms can be read. The issue you're having with MP4 is because the moov atom is written at the end of file, which is a lot easier to do for encoding programs. There are tools, such as qtfaststart, which will do the necessary munging to put the moov atom at the beginning of the file. Thus, the file will start playback as soon as it has data, instead of needing to be fully downloaded before starting.