Add Stereo Audio Tracks to MKV Files

Posted by gmendoza on September 26, 2009 under Tech Tips | 11 Comments to Read

If you have Matroska Video (MKV) files encoded with AC3 Dolby Digital 5.1 or DTS audio tracks, you may want to simply extract the audio, convert it to a 2-channel stereo format like WAV, MP3 OGG, etc, and then add it back into the MKV as a separate audio track. This is useful when your media player (e.g. Western Digital Media Player WDAVN00) will not downscale the audio from a digital format like AC3 or DTS to stereo when you don’t have a receiver or TV with a built in Dolby Digital decoder.  Now you’ll have the choice of either audio format depending on your technical requirements.

The great thing about the Matroska multimedia container is that you can easily manipulate these files without having to re-encode, saving lots of time. I’ll be using mkvextract to extract the AC3 audio, ffmpeg to convert ac3 to mp3, and finally mkvmerge to add and remux the new audio track to the MKV container. All of these are available to a number of platforms, but in my examples, I’m using Linux.  Check out the MKVToolnix and FFMpeg websites for more info on the software.

If using Ubuntu Linux, install the relevant mkvtoolnixmkvtoolnix-gui and ffmpeg packages.

sudo apt-get install mkvtoolnix mkvtoolnix-gui ffmpeg libavcodec-unstripped-52

To view the existing tracks of the MKV, use the mkvmerge -i option. In the following example, you see my “Cool.Video.mkv” file has an MPEG4 video in track 1, an AC3 Dolby Digital audio file in track 2, and subtitles in track 3.

mkvmerge -i Cool.Movie.mkv
File 'Cool.Movie.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_AC3)
Track ID 3: subtitles (S_TEXT/UTF8)

Using mkvextract, extract the AC3 Dolby Digital audio from track 2, saving it to a file called audio.ac3.

mkvextract tracks Cool.Movie.mkv 2:audio.ac3
Extracting track 2 with the CodecID 'A_AC3' to the file 'audio.ac3'. Container format: Dolby Digital (AC3)
Progress: 100%

ls -lh audio.ac3
-rw-r--r-- 1 gmendoza gmendoza 432M 2009-09-26 11:58 audio.ac3

Convert the 6-channel ac3 file to a 2-channel stereo MP3 using ffmpeg. If you prefer a higher audio bitrate, adjust the -ab value as desired. e.g. 256, 384, etc, and adjust the audio rate to your liking as well.

ffmpeg -i audio.ac3 -acodec libmp3lame -ab 160k -ac 2 audio.mp3
[output omitted for brevity]

ls -lh audio.*
-rw-r--r-- 1 gmendoza gmendoza 432M 2009-09-26 11:58 audio.ac3
-rw-r--r-- 1 gmendoza gmendoza 87M 2009-09-26 12:08 audio.mp3

To simplify things, you could actually skip the digital format extraction process by running ffmpeg against the MKV file directly.

ffmpeg -i Cool.Movie.mkv -acodec libmp3lame -ab 160k -ac 2 audio.mp3

If you prefer encoding with more advanced options, you could extract the audio as a 2-channel WAV file instead, and then process it with LAME, Oggenc, or some other encoder of your choosing. The following shows the extraction to WAV, and then conversion to various formats for fun, e.g. MP3, OGG, and FLAC.

ffmpeg -i Cool.Movie.mkv -acodec pcm_s16le -ac 2 audio.wav
lame -V0 -q0 --vbr-new audio.wav audio.mp3
oggenc -q6 audio.wav
flac audio.wav

Use mkvmerge to combine the original MKV with the MP3 audio track to create a new file called Cool.Movie.New.mkv. Make sure you have enough disk space for both the original and new MKV file.

mkvmerge -o Cool.Movie.New.mkv Cool.Movie.mkv audio.mp3
mkvmerge v2.4.1 ('Use Me') built on Dec 13 2008 21:03:46
'Cool.Movie.mkv': Using the Matroska demultiplexer.
'audio.mp3': Using the MP2/MP3 demultiplexer.
Warning: 'audio.mp3': Skipping 32 bytes at the beginning (no valid MP3 header found).
'Cool.Movie.mkv' track 1: Using the MPEG-4 part 10 (AVC) video output module.
'Cool.Movie.mkv' track 2: Using the AC3 output module.
'Cool.Movie.mkv' track 3: Using the text subtitle output module.
'audio.mp3' track 0: Using the MPEG audio output module.
The file 'Cool.Movie.New.mkv' has been opened for writing.
Progress: 100%
The cue entries (the index) are being written...
Muxing took 270 seconds.

Verify that the audio track has been added. You can see Track ID 4 has been successfully added.

mkvmerge -i New.Cool.Movie.mkv
File 'New.Cool.Movie.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_AC3)
Track ID 3: subtitles (S_TEXT/UTF8)
Track ID 4: audio (A_MPEG/L3)

That’s really all there is to it. There are quite a few options available when editing MKV container files. For example, I wanted nice descriptions for my tracks since various media players will read and display them for you during menu navigation. I recommend using the mkvmerge gui application as shown in this screenshot.

mkvmerge-gui

It’s really just a front-end application to mkvmerge, and the following text shows the commands that were used to specify the language for each tag, re-order the audio tracks, disable subtitles by default, and give useful descriptions to each Track ID.

mkvmerge -o "Cool.Movie.New.mkv" \
--language 1:eng \
--track-name "1:Cool Movie (MPEG4)" \
--default-track 1:yes \
--display-dimensions 1:40x17 \
--language 2:eng \
--track-name "2:Dolby Digital 5.1 (AC3)" \
--default-track 2:yes \
--language 3:eng \
--track-name "3:English Subtitles" \
--default-track 3:no \
-a 2 -d 1 -s 3 Cool.Movie.mkv \
--language 0:eng \
--track-name "0:2-Channel Stereo (MP3)" \
--default-track 0:no \
-a 0 -D -S audio.mp3 \
--track-order 0:1,0:2,1:0,0:3

mkvmerge -i Cool.Movie.New.mkv
File 'Cool.Movie.New.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_AC3)
Track ID 3: audio (A_MPEG/L3)
Track ID 4: subtitles (S_TEXT/UTF8)

Share and Enjoy:
  • Print
  • Facebook
  • Twitter
  • del.icio.us
  • RSS
  • Digg
  • email
  • LinkedIn
  • Identi.ca
  • Google Bookmarks
  • StumbleUpon

Related posts:

  1. Convert MKV to Xvid with Mencoder
  2. Extract Audio from Video Files to WAV using FFmpeg
  3. Extract AC3 Dolby Digital with FFMpeg
  4. Convert 3gp Videos to XviD AVI
  5. Convert Video Files to DVD
  6. Extract Audio from Video Files to WAV using Mplayer
  7. DVD to XviD Encoding with Mencoder
  8. Quickly Identify Video File Attributes
  9. Batch MP3 Encoding with Linux and LAME

Comments

  • aaf said,

    Ac3 to Mp3…Blah! Just make it into a 2 CH 128kb/s Ac3.:)
    The Holy Trinity of Linux Video…ffmpeg,mkvtoolnix and HandBrake[!].

  • gmendoza said,

    Hey thanks for the tip on HandBrake! This is exactly what I’ve been looking for to help convert and manipulate various video formats!

    Regarding AC3, the whole point in the mentioned scenario was that certain media players won’t decode the AC3 DD audio for you. So unless you have a receiver in between the player and the TV, you can’t hear anything. Unless I’m missing something about 2-Channel AC3, wouldn’t that still hold true? Sounds like a test is in order. I’ll add it to the post if so.

    Thanks again!

  • Yachika Verma said,

    Thanks for great info. I will visit your blog for more interesting posts like this.

  • Saran said,

    Here’s a simple script to automate the AC3->WAV->MP3->MVK process:

    #!/bin/bash
    echo
    echo $1
    echo
    mkvmerge -i $1

    echo
    echo “####### STARTING AUDIO EXTRACTION #######”
    echo
    ffmpeg -i $1 -acodec pcm_s16le -ac 2 audio.wav

    echo
    echo “####### COMPRESSING AUDIO #######”
    echo
    lame -V0 -q0 –vbr-new audio.wav audio.mp3

    echo
    echo “####### APPENDING AUDIO TO CONTAINER #######”
    echo
    mkvmerge -o new.$1 \
    $1 \
    –language 0:eng \
    –track-name “0:2-Channel Stereo (MP3)” \
    –default-track 0:yes \
    -a 0 -D -S audio.mp3 \

    echo
    echo new.$1
    echo
    mkvmerge -i new.$1

    Just call it from (unix) command line with mkv filename as argument.

  • gmendoza said,

    Very nice Saran. I too ended up creating an automation script, but did not publish it for the simple reason that it would get complicated trying to make it versatile enough for just about any source MKV file I come across.

    For example, many of my MKV’s have multiple audio tracks, and the default isn’t always English. So simply running ffmpeg without specifying which to use, might cause ffmpeg to pull the wrong source audio track. Also, many foreign movies end up needing subtitle tracks, and excluding them all by default can suck. :-) Again, choosing the right one when there are multiple subtitle tracks is also important.

    It will take some work, but you’ve inspired me to get a public version going. Thanks again!

  • Saran said,

    Thanks, gmendoza :)

    I was, too, aware that such simple script can’t cover all aspects, but for me it does cover 90% of mkvs :)

    As you surely know, this line does ripping of audio:

    ffmpeg -i $1 -acodec pcm_s16le -ac 2 audio.wav

    and (as you also surely know) with this command you can inspect the streams:

    ffmpeg -i

    Example result:

    Stream #0.0(eng): Video: h264, yuv420p, 1280×720, PAR 1:1 DAR 16:9, 24 tbr, 1k tbn, 47.95 tbc
    Stream #0.1(eng): Audio: ac3, 48000 Hz, 5.1, s16
    Stream #0.2(eng): Audio: dca, 48000 Hz, 5.1, s16

    So, you just need to add this to choose a different (in this case, the 3rd, dts) stream:

    -map 0.2

    Solution: add another input parameter for script specifying the audio stream mapping (tho you have to check the file beforehand with ffmpeg -i ).

    It just depends on the number of files you are working on so it can turn out that u spent more time on script than you would on converting each file manually (via e.g. gui) :)
    But at least we polish our scripting skillz ;)

  • gmendoza said,

    Saran, yes indeed. Have a look at the script I’ve been using. Keep in mind that it can be improved a great deal by adding some input validation, subtitle prompts, and post processing cleanup of temp wav and mp3 files. And of course, the dialogue makes sense to me, but for new users, it can probably be a little complicated. :-)

    I call it mkmkv.sh, but feel free to call it whatever you like. It relies only on a single argument (the video file name), and just make sure to invoke the script from the same directory as the video file.

    cd /path/to/mkv-dir/
    mkmkv.sh filename.mkv

    #!/bin/bash
    MP3="${1}.mp3"
    WAV="${1}.wav"
     
    echo ""
    echo "Identifying Video File: \"$1\""
    echo ""
     
    ffmpeg -i "$1" 2>&1 | grep "Audio"
     
    echo ""
    echo "Which audio track do you wish to convert to Stereo MP3?"
    read -p "Enter desired FFmpeg audio stream ID in X:Y format: " STREAM
    echo ""
    echo "Identifying MKV Track ID's..."
    echo ""
     
    mkvmerge -i "$1"
     
    echo ""
    read -p "Enter Video ID to be Included: " VID
    read -p "Enter Video ID $VID Description: " VDESC
    echo ""
    read -p "Enter Audio ID to be Included: " AID
    read -p "Enter Audio ID $AID Description: " ADESC
    echo ""
    read -p "Enter name for your NEW MKV file (e.g. movie.mkv): " OUTPUT
    echo ""
    echo ""
    echo "Verify proposed mkvmerge command..."
    echo ""
    echo "\"mkvmerge\" -o \"$OUTPUT\" --language $VID:eng --track-name \"$VID:$VDESC\" --default-track $VID:yes --language $AID:eng --track-name \"$AID:$ADESC\" --default-track $AID:yes -a $AID -d $VID -S \"$1\" --language 0:eng --track-name \"0:English Stereo MP3\" --default-track 0:no -a 0 -D -S \"$MP3\" --track-order 0:$VID,0:$AID,1:0"
     
    echo ""
    read -p "Ctrl+C to cancel, or ENTER to continue."
     
    echo ""
    echo "Running command: ffmpeg -i \"$1\" -map $STREAM -acodec pcm_s16le -ac 2 \"$WAV\""
    ffmpeg -i "$1" -map $STREAM -acodec pcm_s16le -ac 2 "$WAV"
     
    echo ""
    echo "Running command: lame -V0 -q0 --vbr-new \"$WAV\" \"$MP3\""
    lame -V0 -q0 --vbr-new "$WAV" "$MP3"
     
    echo ""
    echo "Running mkvmerge..."
    echo ""
    "mkvmerge" -o "$OUTPUT" \
    --language $VID:eng \
    --track-name "$VID:$VDESC" \
    --default-track $VID:yes \
    --language $AID:eng \
    --track-name "$AID:$ADESC" \
    --default-track $AID:yes \
    -a $AID -d $VID -S "$1" \
    --language 0:eng \
    --track-name "0:English Stereo MP3" \
    --default-track 0:no \
    -a 0 -D -S "$MP3" \
    --track-order 0:$VID,0:$AID,1:0
  • Saran said,

    The script looks fine, gmendoza :)

    Why I started fiddling with script is to actually automate the process as much as possible and as many movies as possible, so this way that requires much user interaction is no good (for me). I’m sure I’ll try/use it for single file conversions :)

  • construction games said,

    Great stuff as usual.

  • Bruce said,

    Great stuff as usual.

  • mkvsmoothie - free your mkv said,

    Mkv smoothie 0.6.6…

    I found your entry interesting thus I’ve added a Trackback to it on my weblog :)…

Add A Comment