Parsing MP4 Atoms

metadata

At home I maintain a Mediatomb DLNA media server (although this should probably be replaced with gerbera or MiniDLNA) so that I can watch videos on my TV over my LAN. It turns out that my TV is quite strict about the MP4s that it plays - it wants the “moov” “atom” to be at the beginning of the file.

A MP4 file contains many parts, which are called “atom”s. These parts contain things like: the metadata; the actual data; and some information about the data. When a MP4 is going to be streamed the information about the stream has to be sent first so that the player knows what it is going to receive before it actually receives the stream. Normally, when a MP4 is played locally this doesn’t matter because a computer can just skip around the file on the hard drive to find the stream information first and then it can play the stream. Over a network connection this is not always possible as often the player cannot suddenly request different parts of the file.

The name of the atom that contains the stream information is “moov” and it is usually located at the end of a MP4 file. This is because the software making the MP4 doesn’t know any of the stream information because it is making it on-the-fly. The software will keep a tally of what has happened so that once it has finished writing the stream it can then write the little atom that contains the information that describes what was written. Some software (such as ffmpeg) have options (such as -movflags +faststart) to make the MP4 be re-written so that the moov atom is moved to the beginning of the file to facilitate the MP4 being streamed.

It was clear that I needed to use the -movflags +faststart option of ffmpeg to make sure that all of the MP4s in my collection were ready for streaming over my network to my TV. I knew this would take an awfully long time so it did not want to run this command on every single MP4 - I only wanted to run it on the MP4s that needed correcting.

Now we get to the crux of this post: I needed some quick software to tell me if a MP4 needed remaking before I went ahead and remade it. After a bit of searching on the internet, and reading two excellent articles (see below), I decided to just do it myself.

The Python function struct.unpack makes it easy to parse big-endian binary data and the MP4 file format itself is fairly simple. I ended up writing two function:

The latter function can be used in a BASH script as a simple check before a MP4 is actually corrected using ffmpeg. Using this Python function I was able to save myself a lot of time correcting my MP4s. Now I can conveniently watch my entire collection on my TV.