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?").
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).





