Creating a valid and working MP4 video Published August 5th, 2010

That task doesn't sound to difficult, does it? Well, I though so to until I encoded an event recording as an MP4 file. I did this in the usual way using mencoder and ffmpeg . Nothing special, no fancy stuff. However, the first response was: the video doesn't play on MacOS X (using Quicktime). Next response: It doesn't work on Windows (using Windows Media Player 12). Hm… both officially supported MP4 with H264 video and AAC audio, but it just didn't work. I tested VLC, Totem and Mplayer on Ubuntu Linux and VLC and Media Player Classic on Windows 7. Everything worked there without any problems.

Maybe I should have answered: Just install Ubuntu Linux, because everything works there, out of the box. Because this is the usual answer I get if some fancy Windows or Mac stuff doesn't work on Linux at once.

However here is the full technical story on how to create an MP4 video that plays on Windows Media Player and Apple Quicktime. If you encode a Video you usually get something with an H264 video track and an AAC audio track. Now this isn't the whole truth since H264 isn't always H264 and AAC isn't always AAC. Both formats have different profiles where the "low" profile only allows simple features for clients that can't afford to spend to much time decoding the data (like mobile devices where every long calculation drains the battery). Then there usually is a "main" profile with a normal feature set and a "high" profile with the most complex features.

In my case after encoding the video I got an H264 high profile (read: complex) video stream and an AAC main profile audio stream. The iPhone can't handle the H264 high profile but since I wanted to create a video for desktop computers it sounded suitable. However after a day of searching around I finally found some other limitations:

Windows Media Player and Apple Quicktime can't handle the AAC "main" profile. They can only play the "low" profile, called AAC- LC . If you pack in an audio stream with the "main" profile there simply is no sound at all in these players. Thanks to Marc Seeger for the hint about this.

. If you pack in an audio stream with the "main" profile there simply is no sound at all in these players. Thanks to Marc Seeger for the hint about this. Apple Quicktime only plays the entire file if the audio stream is marked as MPEG4 AAC. I know, sounds strange, but AAC is also part of the MPEG2 standard, and therefore an MPEG2 AAC also exists. In fact this is what mencoder and ffmpeg (using the FAAC encoder) usually output.

If you are aware of the profiles and these limitations it's not a big deal to build an MP4 video that works in Quicktime and Windows Media Player. In this example I encode a small 10 seconds test clip recorded during one of my projects.

First encode the video and audio stream, here with mencoder :

$ mencoder -vf pp=linblenddeint,hqdn3d \ -ovc x264 -x264encopts crf=25 \ -oac faac -faacopts quality=25: object=2 : mpeg=4 \ -o test.avi test.dv

For clarity I've split the command over multiple lines, that's what the \ at the end of the lines is for.

The -vf parameter in the first line just filters the test.dv input video (deinterlace and filter out noise) and is of no importance here.

The second line says x264 (an H264 encoder) to encode the video with a quality of 25 and the default settings. This will create an H264 High profile video stream that will be stored in the test.avi output file. Be sure to tweak the x264 options for your situation but here this would have only added a bunch of confusing parameters.

The third line now is the interesting one. Here FAAC (and AAC encoder) gets the job to encode the audio stream with a quality of 25. The object=2 parameter makes sure that we get an AAC-LC stream which allows Windows Media Player and Quicktime to play the audio. mpeg=4 on the other hand sets the output to MPEG4 AAC (otherwise MPEG2 AAC) would be the result. I found these options in the mencoder man page (just search for -faacopts ).

With this we made sure that our video and audio streams would play properly. Now we only have to pack these streams into an MP4 container:

$ mplayer test.avi -dumpvideo -dumpfile test.h264 $ mplayer test.avi -dumpaudio -dumpfile test.aac $ mp4creator -create=test.h264 -rate 25 test.mp4 $ mp4creator -create=test.aac test.mp4 $ mp4creator -optimize test.mp4

The details of this procedure are described in the mplayer documentation (also look there if you want to pseudo-stream the file). I got some error messages on the way (about the H264 stream) but I don't think they are relevant for this topic.

If we now take a look at the MP4 file with mp4info we get the following:

$ mp4info test.mp4 mp4info version 1.6 test.mp4: Track Type Info 1 video H264 High@3, 10.080 secs, 204 kbps, 720x576 @ 25.000000 fps 2 audio MPEG-4 AAC LC , 8.554 secs, 95 kbps, 48000 Hz Tool: mp4creator 1.6

The important part is that we got an MPEG-4 and AAC-LC audio stream. With this the file should play in Windows Media Player and Apple Quicktime. In case you want to try it out feel free to download the encoded test clip.