How to Avoid Dubs with FFmpeg

Once again I find myself reading ffmpeg(1) to ensure video player selects good audio and subtitles streams. Recently, I discovered a device called TV and that it can read things from for example NFS. I used PC for such things for the longest time and never realised there is a midpoint before a cinema.

it was some time since i last used mouse for this; last exile

For whatever reason video distributors decide to set default audio track to English or set no default track at all. They often also configure subtitles with this in mind, too. The only thing other than subtitles with original audio I'll tolerate is voice-over translation or "lektor filmowy" in Polish. (If you have never witnessed voice-over, while it takes some time to get used to, it is the most supreme way.)

After dumping CDs to NFS, I need to fix it...

Before tweaking anything, it's good to know what I'm dealing with, so I use ffprobe(1):

$ ffprobe example.mkv 2>&1 | grep -i stream
  Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn (default)
  Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
  Stream #0:2(jpn): Audio: aac (LC), 48000 Hz, stereo, fltp
  Stream #0:3(eng): Subtitle: ass (ssa)
  Stream #0:4: Attachment: ttf

Despite my extreme hostility towards dubs, I usually leave them intact within the container. We can inform what streams to use with dispositions:

$ ffmpeg -i example.mkv \
>   -c copy \
>   -map 0 \
>   -disposition:a:1 default+original \
>   -disposition:a:0 0 \
>   -disposition:s:0 default \
>   output.mkv

-c copy and -map 0 are there to copy everything as is from the original container. By default only default or first of each stream type would get copied. Then I specify dispositions:

Indices may, of course, vary. Letters v and t would work with, respectively, video streams and attachments, instead.

If you prefer to remove streams, you may used -map option:

$ ffmpeg -i example.mkv \
>   -c copy \
>   -map 0:v \
>   -map 0:a:1 \
>   -map 0:s \
>   -map 0:t \
>   output.mkv

Where prefixed 0: select source file and missing parts assume "everything". Previous it was -map 0 that selected all streams, now we have 0:v to select all video streams and 0:a:1 to select the audio stream at index 1.

The last step is to make it semi-automatic with script for a batch of files. Enjoy.