Adventures in Matroksa

I’ve recently re-encoded a whole load of MPEG2 video I’ve got into MPEG4 (using H.264). I thought that I’d put it all in MKV containers. Sadly, this turns out not to be the case: HandBrake’s presets explicitly set the output container — mostly to MP4. So I’m now left with a large number of videos in a format that I didn’t intend. What’s worse, I can’t easily flip forward and back in the files I do have, using either my Popcorn Hour or any of the video players I have on my Linux desktop. Here’s what I did to fix this sorry state of affairs.

First thing: what’s going on with not being able to skip around in the videos? Even if I encode a DVD with the “chapter markers” option set in HandBrake, I can’t use the “Next Chapter” and “Previous Chapter” buttons in the Popcorn Hour.

It seems that the Matroska container format doesn’t require the writing of a position index. So HandBrake simply doesn’t bother. So, even though it writes the chapter markers, the metadata needed to find those places doesn’t exist. Fortunately, this seems to be a well-known issue, and is mentioned in several places on the HandBrake forums. Unfortunately, the answers are somewhat lacking in detail: “run it through mkvmerge”. Gee, thanks. What command line options do I use?

After reading through the (clear and well-written) docs for mkvmerge, I decided that actually I didn’t need any options:

Takes about 30 seconds to process, and I get all my chapter markers back. Success!

Now, what about my other, larger problem? All these MP4 containers that should be Matroska…

Well, as it turns out, mkvmerge will in theory handle that, too. Exactly the same command line. Just feed it an MP4 file, and it spits out the MKV for you. Sadly, for me that doesn’t quite work. I get a playable file, but the quality is unwatchable. There’s a lot of dropped frames in it. Back to the drawing board.

There’s a pair of packages called mpeg4ip-utils and mpeg4ip-server, which contain tools for manipulating MP4 containers. You can list the Elementary Streams in an MP4 file:

You can also extract individual ESes from it:

At this point, mkvmerge comes back in:

That seems to work properly.

But hang on… These videos I recorded off the TV don’t have any kind of chapter markers. I’d like to be able to skip back and forward in them sometimes, too. Can I automate the process of adding chapter markers every, say, 5 minutes?

mkvmerge, again, has a –chapters option that will take either an XML input file, or a simple input listing chapter times and names. Let’s try that:

Well, it’s kind of a success. I can skip around the chapters all right, but from mplayer I get bitter complaints about B-frames not having reference frames, and when I do skip, I get several seconds of unwatchable delta mush before the next I-frame appears and it all clears up. What I need to do is find out where all the I-frames are.

Fortunately, mpeg4ip has most of the solution to that, too:

The figures in brackets just before “IDR-I” on each line are the time offsets in milliseconds for that I-frame. We can use that to make a list of the next I-frame after each 5-minute interval of the file, and construct a chapter list from that:

All done.