Harmonizing the order of audio streams in your video files can be done by using the free open source tool FFmpeg in the ‘Terminal’.
In order to use FFmpeg in the ‘Terminal’ of an Apple macOS computer you have to install it. Installation instructions can be found in my blog post ‘Fixing corrupted AVI indexes‘.
First run the command ‘ffprobe <your file name>’ in your ‘Terminal’. At the end of the Terminal output you will get something like the following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
ffprobe input.mkv Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x798 [SAR 1:1 DAR 320:133], 23.98 fps, 23.98 tbr, 1k tbn, 2k tbc (default) Metadata: BPS : 4512900 BPS-eng : 4512900 DURATION : 01:55:00.000000 DURATION-eng : 01:55:00.000000 NUMBER_OF_FRAMES: 165040 NUMBER_OF_FRAMES-eng: 165040 NUMBER_OF_BYTES : 3938855162 NUMBER_OF_BYTES-eng: 3938855162 _STATISTICS_WRITING_APP: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_APP-eng: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_DATE_UTC: 2018-01-01 10:00:00 _STATISTICS_WRITING_DATE_UTC-eng: 2018-01-01 10:00:00 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:1(ger): Audio: ac3, 48000 Hz, stereo, fltp, 224 kb/s (default) (forced) Metadata: BPS : 224000 BPS-eng : 224000 DURATION : 01:55:00.0000000 DURATION-eng : 01:55:00.0000000 NUMBER_OF_FRAMES: 217721 NUMBER_OF_FRAMES-eng: 217721 NUMBER_OF_BYTES : 195078016 NUMBER_OF_BYTES-eng: 195078016 _STATISTICS_WRITING_APP: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_APP-eng: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_DATE_UTC: 2018-01-01 10:00:00 _STATISTICS_WRITING_DATE_UTC-eng: 2018-01-01 10:00:00 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:2(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s Metadata: BPS : 343000 BPS-eng : 343000 DURATION : 01:55:00.0000000 DURATION-eng : 01:55:00.0000000 NUMBER_OF_FRAMES: 214519 NUMBER_OF_FRAMES-eng: 214519 NUMBER_OF_BYTES : 336716380 NUMBER_OF_BYTES-eng: 336716380 _STATISTICS_WRITING_APP: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_APP-eng: mkvmerge v8.0.0 64bit _STATISTICS_WRITING_DATE_UTC: 2018-01-01 10:00:00 _STATISTICS_WRITING_DATE_UTC-eng: 2018-01-01 10:00:00 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES |
In this example you can see the following. The multimedia file contains three streams (see highlighted lines in yellow):
- Stream 0: video stream
- Stream 1: audio stream, German language, set as default audio stream, forced audio stream
- Stream 2: audio stream, English language
A forced audio stream will override the settings in your video player. If you defined English as your preferred audio language in your video player, with this example file the player would play the German language nevertheless.
Note on the enumartion ‘#x:y’: Counting starts with 0. The first number x represents the number of the input file. So, 0 means the first input file. The second number y represents the stream within the input file. So, 0 means the first stream. In the above example file we only have one input file, and therefore the first number will always be 0.
Now, we want to achieve the following:
- no time-consuming re-encoding
- Stream 0: video stream
- Stream 1: audio stream, English language, default stream
- Stream 2: audio stream, German language
- no forced language stream
To do that we can use the following command:
1 2 3 4 5 |
ffmpeg -i input.mkv -c copy -map 0:m:language:eng -map 0:m:language:ger -disposition:a:0 default -disposition:a:1 0 output.mkv alternative command ffmpeg -i input.mkv -c copy -map 0:v:0 -map 0:a:1 -map 0:a:0 <....> output.mkv |
Explanation of the parameters:
- -c copy – will just copy the streams without re-encoding
- -map 0:m:language:eng – will put the English stream as first audio stream
- -map 0:m:language:ger – will put the German stream as second audio stream
- -disposition:a:0 default – will define the first audio stream as default
- -disposition:a:0 0 – will erase any previous disposition settings (in this example removing default and forced setting)
If you have a more complex stream situation in your input file you can also use the alternative syntax to achieve the same. The ‘map’ parameters will have to be used as following:
- -map 0:v:0 – will put the first video stream of the first input file as first video stream
- -map 0:a:1 – will put the second audio stream of the first input file as first audio stream
- -map 0:a:0 – will put the first audio stream of the first input file as second audio stream
Note: the ordering of the ‘map’ parameters defines the ordering of the streams in the output file. And you can also use the S-parameter, e.g. -map 0:s:0, in order to move subtitle streams.