Flexion.Org
Bad grammar and typos for total strangers
Wiki › Converting MKV
Wiki Index All Recent Edit Bottom

Converting MKV

1.   Introduction
2.   PS3 MPEG-4 Limits
3.   Installing the tools
4.   Splitting the .MKV
5.   Getting .MKV info
6.   Extract the Video
6.1   Check Video Profile
7.   Convert the Audio
7.1   Down mixing to Stero is simple and compatible?
7.2   Understanding Channel Arrangements for 5.1 Audio Formats
7.3   Using mplayer with NeroAacEnc or faac to make AAC 5.1
8.   Creating the MPEG-4
9.   Scripting it all
9.1   MKV-Ripper.sh
10.   Old Stuff

Introduction

This is based on the following blog post adding to effort of my own to correctly map channel assignments for AAC 5.1

Like the blog post above, I want to keep re-encoding to a minimum.

PS3 MPEG-4 Limits

During the process of figuring out the conversion of MKV to MP4 I have discovered there are some limits to what the PS3 will play.

  • .MP4 files must be less than 4GB, that is a FAT32 limit too.
  • Some people have mentioned that AAC must be encoded at less than 160kbps to be compatible with the PS3. That is a myth.
    • I have downloaded movie trailers from the PS Store which are 224kbps and now also created MPEG-4 using ~300kbps 5.1 AAC which works fine.

Installing the tools

This install the tools for GPAC, mkvtoolnix, mpeg4ip and ffmpeg.

 sudo aptitude install a52dec faac ffmpeg gpac hexedit mkvtoolnix-gui mpeg4ip-utils mpeg4ip-server 

I also use the Nero AAC encoder as it produces better results than faac, for more details see the URL below...

 wget http://ftp6.nero.com/tools/NeroDigitalAudio.zip
 wget ftp://ftp6.nero.com/tutorials/nerodigital/audio_encoder/NeroDigitalAudio_tut_eng.pdf
 unzip NeroDigitalAudio.zip
 chmod 755 linux/*
 sudo mv linux/* /usr/local/bin/

Splitting the .MKV

If the .mkv file is large than 4GB we need to split it. This is because, that although MP4Box support splitting MPEG-4 files, the PS3 will only play the first part and any subsequent parts refuse to play.

Therefore if the .mkv file is greater than 4GB we will split it then and convert those parts.

 mkvmerge -o movie_split.mkv --split 4G movie.mkv

Getting .MKV info

In order to extract the video, audio and/or subtitles from the .mkv we first need to know what is in the container.

 mkvmerge -i movie.mkv

Should return something like the following...

 File ’movie.mkv’: container: Matroska
 Track ID 1: video (V_MPEG4/ISO/AVC)
 Track ID 2: audio (A_AC3)

Check the video is encoded in the proper format, look for "V_MPEG4/ISO/AVC" and make a note of which tracks hold the video and audio you are after. Now we need to get the framerate using the following...

 mkvinfo movie.mkv | grep fps

...which should return something like...

 |  + Default duration: 41.708ms (23.976 fps for a video track)

Extract the Video

Use a command similar to the one below, simply replacing the video and audio track numbers are required.

 mkvextract tracks movie.mkv 1:movie.h264

Check Video Profile

Some video comes in profile 5.1 which the PS3 doesn't support, the PS3 only supports profile 4.1. So first check the profile level...

 file movie.h264

The output will look something like this.

 movie.h264: JVT NAL sequence, H.264 video @ L 51

If the number after the @ is 41 you have 4.1 profile which is great and you can skip ahead to the Convert the Audio section.

If you have 51 after the @ then you need to change the profile level which is easy to do and takes less than a second using the following bit of Python.

 python -c "f=open('movie.h264','r+b'); f.seek(7); f.write('\x29'); f.close()" 

You can open movie.h264 in hex editor, such as 'hexedit' and manually patch the file.

 hexedit movie.h264

Look for the following on the first line:

 67 4D 40 33

Which we change to:

 67 4D 40 29

NOTE! Different number combinations than the above do exist, the good news is that the 33 remains the same and is the one that you want to change to 29. What you're looking for in the hex editor, is the 2nd distinct column grouping of numbers. The 33 will be on the top line and is the right most number in that 2nd grouping.

  • To save and exit 'hexedit' use Ctrl+x
  • To exit 'hexedit' use Ctrl+c

After changing the profile level check it is now 4.1

 file movie.h264

Which should return something like...

 movie.h264: JVT NAL sequence, H.264 video @ L 41

Convert the Audio

Whilst is it technically possible to include Dolby Digital and DTS audio in an MPEG-4 container, there are not currently any MPEG-4 container tools (other than Handbrake) which support that configuration and I have yet to get my PS3 to see, let alone play, an AC3 audio track embedded in an MPEG-4 container. Therefore, we do need to re-encode the AC3/DTS to AAC.

Down mixing to Stero is simple and compatible?

We can convert AC3/DTS in the .mkv to either Stereo or 5.1 multi channel AAC, but there are some considerations when choosing 5.1 AAC.

  • Multi-channel 5.1 AAC is supported on the PS3 but not other devices, so if you also want to watch your MPEG-4 on Xbox 360 or other devices then you'll not have any audio if you use 5.1 AAC.
  • The various 5.1 format channel arrangements are different, meaning that you will need to know how to map up the channels correctly. If you do not use the correct channel mappings then the centre channel is typically misplaced which sounds really odd.
  • At the time of writing VLC 0.8.6e and Xine 0.99.5 do not correctly place the channels in AAC 5.1 audio, even if you get the channel arrangement right!
  • To play 5.1 AAC you will need an amplifier that can decode AAC (few can) or one that can play the multichannel LPCM that the PS3 decodes.
  • Depending on the method used, converting 5.1 AC3/DTS to 5.1 AAC can more time consuming than converting to Stereo AAC.

So, a lot of good reasons to not bother with AAC 5.1 and just down mix to stereo. If you need Stereo then use the method below.

ffmpeg : Downmix to Stereo AAC

This method works well for down mixing 5.1 audio to stereo and it works well with both AC3 and DTS. 'ffmpeg' has multi channel options but they garble DTS and have no channel re-mapping capability.

 ffmpeg -i movie.mkv -vn -acodec mpeg4aac -ac 2 -ar 48000 -ab 160k movie_2ch.aac

Understanding Channel Arrangements for 5.1 Audio Formats

Now, I could have stopped with the simple down mix method above, but that just doesn't sit well with me because I want multi channel damn it! ;-)

Wouldn't it be great if all the 5.1 audio formats had the same channel arrangement? Fact, is they are nearly all different.

Channel Arrangement for Multi Channel 5.1 Audio Formats

FormatChan 0Chan 1Chan 2Chan 3Chan 4Chan 5
5.1 WAVFLFRFCLFESLSR
5.1 AC3FLFCFRSLSRLFE
5.1 DTSFCFLFRSLSRLFE
5.1 AACFCFLFRSLSRLFE
5.1 AIFFFLSLFCFRSRLFE
  • FL : Front Left
  • FC : Front Center
  • FR : Front Right
  • SL : Surround Left
  • SR : Surround Right
  • LFE : Low Frequency Effects (Sub)

Using mplayer with NeroAacEnc or faac to make AAC 5.1

This is the only method I have found which can create 5.1 Multi-Channel AAC with the correct channel assignments. That last point needs driving home, with the correct channel assignments. I have found numerous methods which claim they convert AC3 5.1 or DTS 5.1 to AAC 5.1, and certainly the resultant AAC files do have 6 channels. It is just a shame the channels are in the wrong places which sounds extremely funky when you playback through a 5.1 capable home cinema sound system. Grrr.

The problem is this, the .wav that 'mplayer' outputs will have the channel arrangement of the source audio (i.e AC3 or DTS) and 'NeroAacEnc' and 'faac' expect different channel arrangements (different from each other and different from AC3 and DTS) for their input.

After some extensive testing I have figured out several channel mappings to correctly created AAC 5.1 from AC3 5.1, DTS 5.1 and WAV 5.1.

NOTE! some of following has been validated and some hasn't. For example, AC3 5.1 to AAC 5.1 is confirmed working when using 'NeroAacEnc' and I'm fairly sure the DTS 5.1 to AAC 5.1 using 'NeroAacEnc' works too. So, apart from possible typos, I think my tables are correct.

  • 'NeroAacEnc' expects the .wav input file to have a WAV 5.1 channel arrangement as shown below.
    • FL, FR, C, LFE, SL, SR
  • I am fairly sure 'faac' expects the .wav input file to have the following channel arrangement.
    • SL, SR, FL, FR, C, LFE
  • mplayer and Totem (with GStreamer) playback the AAC 5.1 multi-channel stuff correctly on my laptop.
  • Xine 0.95 and VLC 0.8.6.e do not playback the AAC 5.1 multi-channel stuff correctly on my laptop.
  • When I play AAC 5.1 with mplayer and Totem (GStreamer) the channel arrangement match what my PS3 produces through my home cinena system.

Channel Arrangement for NeroAacEnc and faac 5.1 WAV input

FormatChan 0Chan 1Chan 2Chan 3Chan 4Chan 5
NeroAacEncFLFRFCLFESLSR
faacSLSRFLFRCLFE

Multi Channel 5.1 Channel Maps for encoding AAC 5.1

Therefore, based on the assumptions above, here are the mplayer channel mappings that should correctly present AC3 5.1, DTS 5.1 and WAV 5.1 to 'NeroAacEnc' and 'faac'

AC3 5.1 -> AAC 5.1 Encoder Input

mplayer Channel Map - AC3 5.1 to NeroAacEnc and faac

Channel NameSource AC3 5.1 Chan No.Input NeroAacEnc Chan No.mplayer Map
FL000:0
C121:2
FR212:1
SL343:4
SR454:5
LFE535:3
  • NeroAacEnc : channels=6:6:0:0:1:2:2:1:3:4:4:5:5:3
Channel NameSource AC3 5.1 Chan No.Input faac Chan No.mplayer Map
FL020:2
C141:4
FR232:3
SL303:0
SR414:1
LFE555:5
  • faac : channels=6:6:0:2:1:4:2:3:3:0:4:1:5:5

DTS 5.1 -> AAC 5.1 Encoder Input

mplayer Channel Map - DTS 5.1 to NeroAacEnc and faac

Channel NameSource DTS 5.1 Chan No.Input NeroAacEnc Chan No.mplayer Map
C020:2
FL101:0
FR212:1
SL343:4
SR454:5
SR535:3
  • NeroAacEnc : channels=6:6:0:2:1:0:2:1:3:4:4:5:5:3
Channel NameSource DTS 5.1 Chan No.Input faac Chan No.mplayer Map
C040:4
FL121:2
FR232:3
SL303:0
SR414:1
SR555:5
  • faac : channels=6:6:0:4:1:2:2:3:3:0:4:1:5:5

WAV 5.1 -> AAC 5.1 Encoder Input

mplayer Channel Map - WAV 5.1 to NeroAacEnc and faac

Channel NameSource WAV 5.1 Chan No.Input NeroAacEnc Chan No.mplayer Map
FL000:0
FR111:1
C222:2
LFE333:3
SL444:4
SR555:5
  • NeroAacEnc : channels=6:6:0:0:1:1:2:2:3:3:4:4:5:5
Channel NameSource WAV 5.1 Chan No.Input faac Chan No.mplayer Map
FL020:2
FR131:3
C242:4
LFE353:5
SL404:0
SR515:1
  • faac : channels=6:6:0:2:1:3:2:4:3:5:4:0:5:1

The mplayer Methods

Here are the methods using 'mplayer' with 'faac' and 'NeroAacEnc'. I use 'NeroAacEnc' since it is a better quality encoder, but I've include details for use 'faac' if you can't (or won't) use 'NeroAacEnc'.

AC3 5.1 to AAC 5.1 using mplayer and NeroAacEnc

 mkfifo audiodump.wav
 neroAacEnc -ignorelength -q 0.30 -if audiodump.wav -of movie_6ch.aac &  mplayer movie.mkv -ac ffac3 -channels 6 -af format=s16le,channels=6:6:0:0:1:2:2:1:3:4:4:5:5:3 -vo null -vc null -ao pcm:fast:waveheader:file=audiodump.wav -novideo -quiet -nolirc
 rm audiodump.wav

AC3 5.1 to AAC 5.1 using mplayer and faac

 mkfifo audiodump.wav
 faac -q 234 -o movie_6ch.aac -P -C 6 -X --mpeg-vers 4 audiodump.wav & mplayer movie.mkv -ac ffac3 -channels 6 -af format=s16le,channels=6:6:0:2:1:4:2:3:3:0:4:1:5:5 -vo null -vc null -ao pcm:fast:waveheader:file=audiodump.wav -novideo -quiet -nolirc
 rm audiodump.wav

DTS 5.1 to AAC 5.1 using mplayer and NeroAacEnc

 mkfifo audiodump.wav
 neroAacEnc -ignorelength -q 0.30 -if audiodump.wav -of movie_6ch.aac &  mplayer movie.mkv -ac ffdca -channels 6 -af format=s16le,channels=6:6:0:2:1:0:2:1:3:4:4:5:5:3 -vo null -vc null -ao pcm:fast:waveheader:file=audiodump.wav -novideo -quiet -nolirc
 rm audiodump.wav

DTS 5.1 to AAC 5.1 using mplayer and faac

 mkfifo audiodump.wav
 faac -q 234 -o movie_6ch.aac -P -C 6 -X --mpeg-vers 4 audiodump.wav & mplayer movie.mkv -ac ffdca -channels 6 -af format=s16le,channels=6:6:0:4:1:2:2:3:3:0:4:1:5:5 -vo null -vc null -ao pcm:fast:waveheader:file=audiodump.wav -novideo -quiet -nolirc
 rm audiodump.wav

Creating the MPEG-4

Now we need to make a MPEG-4 file with the video and audio we extracted/converted, specifying the video's frame rate that we noted earlier.

 MP4Box -add movie.h264 -add movie_2ch.aac -fps 23.976 movie_2ch.mp4

Sadly, if MP4Box is used the split the .mp4 the PS3 will only play the first part, any subsequent parts refuse to play. This is why we split the .mkv, if it is large than 4GB, and then convert those .mkv parts. It ensures compatibility.

Scripting it all

After working out the various steps above, I have put it all together in an automated shell script.

MKV-Ripper.sh

Features

  • Does work on Ubuntu Linux, should work on any other Linux/Unix flavour and possibly MacOSX providing you have the required tools installed.
  • Checks that the required tools are available and tells you what is missing.
  • Automated conversion of .mkv to PS3 compatible .mp4
    • Also compatible with Xbox360 if '-2ch' override is used.
  • Splits the .mkv, if it is greater than 4GB, to maintain PS3 and FAT32 compatibility for the resulting MPEG-4 files.
  • Does not re-encode the H264 video
    • Will detect profile 5.1 H264 and patch it to 4.1 in under a second
  • Creates AAC 5.1 from AC3 5.1 and DTS 5.1 with the correct channel assignments
    • Will use NeroAacEnc if available but fails over to faac.
  • Any subtitles in the .mkv are extracted and converted to 3GPP Timed Text.
    • 3GPP Timed Text is not (currently) accessible from the PS3, but does work with some software players.

Requirements

  • file, stat, grep, cut, sed, rm, python, mktemp, mkfifo, mkvmerge, mkvinfo, mkvextract, mplayer, MP4Box, faac and optionally neroAacEnc.

Download

You can get the current version of my script from my SVN repository.

Screenshot

As if ;-)

Old Stuff

Err, this is older stuff, not being worked on right now.

References

$Id: ConvertingMKV,v 1.79 2008/08/19 07:01:38 martin Exp $

Wiki Index All Recent Edit Top
 
Valid XHTML Valid CSS Hacker