Dynamic FFmpeg Subtitle Stream Mapping via Language

This post shows how you can dynamically map streams based upon the language as the criteria/condition.

  • Map English subs only by using the parameter -map 0:s:m:language:eng
  • Map Spanish subs only by using the parameter -map 0:s:m:language:spa
  • Map Chinese subs only by using the parameter -map 0:s:m:language:chi
  • You get the hint...

This method works great using script loops (for/while etc) in case some streams within media containers differ.
Since this is a conditional mapping, it is similar to using the question mark which allows the execution to continue in the case that the subtitle stream you're attempting to map is absent (-map "0:s?").

⚠️
If you don't already know the 3-letter language code you want to map, go to https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes.
TIP: Click here if you're interested in viewing my large collection of ffmpeg example commands with comments.
For learning how to shell script batch audio transcoding, check out my ffmpeg-batch-transcode-audio blog post.

This is the syntax:

<stream #>:<video/audio/subtitle>:<metadata>:<property>:<value>

Map all subtitle streams where language is English:

0:s:m:language:eng

# full cli example:
for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a:1 -map 0:s:m:language:eng -dn -map_chapters -1 -c:v copy -c:a aac -c:s copy "${f/DDP/AAC}"; done

Map all audio streams where language is English:

0:a:m:language:eng

# full cli example:
for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a:1 -map 0:a:m:language:eng -dn -map_chapters -1 -c:v copy -c:a aac -c:s copy "${f/DDP/AAC}"; done

You get the idea. For the video stream it would be 0:v:m:language:eng. You may also use any other stream attribute in replacement of language, such as title. It’s basically an IF statement without saying IF.

Equivalent of the above scripts in cmd/batch for use on Wintel systems:

FYI: in Windows you need double percent-sign variables (%%A) for running within a batch/cmd script file. If you are running directly on the CLI then you only need single percent-sign variables (%A).

for %%A IN ("*.mkv") Do ffmpeg -y -i "%%A"  -default_mode infer_no_subs -map 0:v:0 -map 0:a:1 -map 0:a:m:language:eng -dn -map_chapters -1 -c:v copy -c:a aac -c:s copy "./%%~nA_New.mkv"

Sources:
https://trac.ffmpeg.org/ticket/7356

If you have any questions/comments regarding this article, click here or scroll down below (login isn't required to post comments and there's no waiting period).

FFmpeg + sed: How to insert clean metadata based on input file name
This post shows you how to extract the movie/show name from the file name and insert it into the title metadata field of MKV & MP4 containers.
Supported MP4 Metadata Keys with FFmpeg
The following table lists the supported MP4 container metadata key names in FFmpeg.
FFmpeg Batch Transcode Audio
Recently I have been dealing with transcoding media files for my streaming site travisflix and performing ad-hoc media conversions is no longer realistic. I strongly recommend checking out my FFmpeg Examples to give you a head start if you’re not familiar with deep diving in FFmpeg details. Before you