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.
- 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.