7

I want to change the default audio track from Portuguese to English in the file input.mkv.

The video contains 4 Audio Tracks: Portuguese (Default), Spanish, English and Japanese. I would also like to keep the subtitles.

The information about the video is as follows:

Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    encoder         : libebml v1.3.10 + libmatroska v1.5.2
    creation_time   : 2021-01-24T22:56:10.000000Z
  Duration: 00:26:36.85, start: -0.007000, bitrate: 2157 kb/s
    
    Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)
    Metadata:
      BPS-eng         : 1880412
      DURATION-eng    : 00:24:21.134000000
      NUMBER_OF_FRAMES-eng: 35032
      NUMBER_OF_BYTES-eng: 343441847
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:1(por): Audio: opus, 48000 Hz, stereo, fltp (default)
    Metadata:
      ENCODER         : Lavc58.97.100 libopus
      BPS-eng         : 116334
      DURATION-eng    : 00:24:21.639000000
      NUMBER_OF_FRAMES-eng: 73082
      NUMBER_OF_BYTES-eng: 21254949
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:2(spa): Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      ENCODER         : Lavf55.33.100
      BPS-eng         : 121447
      DURATION-eng    : 00:26:36.843000000
      NUMBER_OF_FRAMES-eng: 79843
      NUMBER_OF_BYTES-eng: 24241492
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:3(eng): Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      BPS-eng         : 103565
      DURATION-eng    : 00:24:21.049000000
      NUMBER_OF_FRAMES-eng: 73053
      NUMBER_OF_BYTES-eng: 18914357
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:4(jpn): Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      BPS-eng         : 104161
      DURATION-eng    : 00:24:21.138000000
      NUMBER_OF_FRAMES-eng: 73057
      NUMBER_OF_BYTES-eng: 19024328
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:5(por): Subtitle: ass
    Metadata:
      BPS-eng         : 79
      DURATION-eng    : 00:23:59.360000000
      NUMBER_OF_FRAMES-eng: 245
      NUMBER_OF_BYTES-eng: 14246
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:6(spa): Subtitle: ass
    Metadata:
      BPS-eng         : 83
      DURATION-eng    : 00:23:59.360000000
      NUMBER_OF_FRAMES-eng: 242
      NUMBER_OF_BYTES-eng: 15096
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:7(eng): Subtitle: ass
    Metadata:
      title           : (Forced)
      BPS-eng         : 435
      DURATION-eng    : 00:23:05.930000000
      NUMBER_OF_FRAMES-eng: 523
      NUMBER_OF_BYTES-eng: 75467
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    Stream #0:8(eng): Subtitle: ass
    Metadata:
      BPS-eng         : 505
      DURATION-eng    : 00:23:59.390000000
      NUMBER_OF_FRAMES-eng: 775
      NUMBER_OF_BYTES-eng: 90904
      _STATISTICS_WRITING_APP-eng: mkvmerge v45.0.0 ('Heaven') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-24 22:56:10
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
1

2 Answers 2

13

The ordering of the audio streams can be accomplished using FFmpeg's map and disposition options. Best syntax for this is arguably:

ffmpeg -i input.mkv -map 0:v:0 \
       -map 0:a:2 -map 0:a:0 -map 0:a:1 -map 0:a:3 \
       -map 0:s -c copy \
       -disposition:a:0 default \
       reordered.mkv

To unpack this a little:

  • -map 0:v:0: The first (and only) video stream is selected
  • -map 0:a:1 -map 0:a:0 -map 0:a:2 -map 0:a:3: The audio streams are individually placed. The final digit of each 'set' selects from the 4 audio streams with '0' being the first stream and '3' being the final audio stream. English is of course specified first and is stream 2.
  • -map 0:s: Select all of the subtitle files
  • -c copy: Copy the video, audio and subtitle streams with no re-encoding.
  • -disposition:a:0 default: This sets our required audio stream (English) as the default. Useful if this has been set on another, input audio stream.

This worked well on a test file produced on my system and should work well on yours as well...

Notes...

1
  • 2
    If one of the streams is already the default and you're changing it, you're going to also want to add -disposition:a:N 0 where N is the old default. The way dispositions work is, you're not setting the default, you're just adding a "default" flag to an audio stream. So you'll also need to remove the "default" flag from the old stream. Otherwise you'll have two streams tagged as default and you might not get the results you want depending on your player.
    – Jason C
    Feb 15, 2022 at 1:57
3

I found this thread by asking Google a highly related but slightly different question - which I now have the answer to. So could be someone else with the same issue as mine will also end up here and this might help out someone else at some time.

Our 'Smart' TV has an integrated Mp4 player, and it will play MP3 or AAC sound tracks. I have a load (80 or so) of files which have an AAC soundtrack - but these play at painfully low audio volume (TV volume set at 100% is nowhere near loud enough to hear a lot of the dialog). With oldies in the house with hearing problems and no embedded subs, this makes said videos unwatchable.

So, I wanted a way to use ffmpeg to:

  1. Preserve the original AAC but also add an MP3 sound track, derived from the AAC, but with loudness processing so that it's suitable for TV watching.

  2. Demote the AAC sound track to be the second audio stream, while making the new MP3 audio the default. During the process of experimentation I found that this particular TV player (Panasonic) always defaults to the first audio stream - no matter which is flagged as the default.

  3. As the icing on this cake, I wanted to give each audio stream a proper metadata title.

I could have just demuxed the existing streams and then created the new processed audio and then muxed them all up again, but I was convinced that ffmpeg could do this as one command line - which makes for far neater and faster progress when you have 80 files to do. ffmpeg didn't let me down.

With help from the answers above and other stuff I found, this is the command line I ended up with - works a treat.

ffmpeg -i intest.mp4 -map 0 -disposition:a:0 0 -c:v copy -c:a:0 libmp3lame -metadata:s:a:0 title="MP3-LoudnessProcessed" -metadata:s:a:1 title="OriginalAAC" -filter:a loudnorm -disposition:a:0 default -map 0:a:0 -disposition:a:1 0 outtest.mp4 

In this command:

  • -map 0 means select all streams

  • -disposition:a:0 0 means, forget that the 1st audio stream is the default audio stream

  • -c:v copy – means transfer the video stream as-is

  • -c:a:0 libmp3lame -metadata:s:a:0 title="mp3-LoudnessProcessed" -filter:a loudnorm -disposition:a:0 default means make a new MP3 audio stream as stream 0 and title it “Mp3” also do a loudness normalisation on that stream and make it the default audio

  • -map 0:a:0 means map the first existing AAC audio stream from the input file. Because this happens last of all, it ends up as the 2nd audio stream (stream 1). Some players always default to the first audio stream (stream 0) – no matter which one is flagged as the default audio, so I needed to be sure the AAC stream was last.

  • -disposition:a:1 0 - means forget that the existing audio stream (now audio stream 1) was ever the default. This is likely not actually be needed(??) but does no harm.

ffmpeg never fails to impress - always a way to do what you want. HTH someone else sometime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.