8

I have lots of files with multiple audio and subtitle languages, however the track numbers aren't consistent (the English audio stream isn't always the first) so using a command such as:

ffmpeg -i "input.mkv" -map 0 -map -0:a:1 -c:v copy -c:a copy "output.mkv"

doesn't yield expected results. After searching around I discovered it was possible to map streams based on language with this command:

ffmpeg -i "input.mkv" -map 0 -map -0:m:language:eng -c:v copy -c:a copy "output.mkv"

However -map -0:m:language:eng will remove all tracks with the English language flag. To keep the subtitle tracks you can use -map 0:s this is a good solution however, I want to know if it's possible to only map audio streams based on language. I.e.,

I want to remove English audio while retaining all other streams without using stream IDs.

xpt
  • 20,363
  • 37
  • 127
  • 216
ffmpeg123
  • 91
  • 1
  • 1
  • 5

5 Answers5

23

-0:m:language:eng will remove english audio tracks and keep all others.

to keep only english audio tracks and remove all others, remove the dash at the beginning: 0:m:language:eng the dash at the beginning creates a negative mapping, which tells ffmpeg "remove this and only things that match this"

i know this is 8 months later, but i thought it would be helpful for those who end up here off of google searches like i did.

Mahmoud Al-Qudsi
  • 28,357
  • 12
  • 85
  • 125
jeff
  • 231
  • 2
  • 2
  • One little caveat: if you use the opposite map (without the "-"), it can cause problems if there are multiple streams for the same language (for example, different types of subtitles for the same language). This could break a command that expects a single stream, like a command that extracts .srt subtitles. – nicbou Aug 22 '21 at 21:37
6

Edit: Ignore initial reply. Not possible at present. Use workaround on top.

ffmpeg -i "in.mkv" -map 0:a -map -0:m:language:eng -map 0:v -map 0:s -map 0:d? -map 0:t? -c copy "out.mkv"

This achieves the desired result because ffmpeg implements the map options in given order.


You need to suffix the metadata selectors to the stream type selector i.e.

ffmpeg.exe -i "%f" -map 0 -map -0:a:m:language:eng -c:v copy -c:a copy "../%f"
Gyan
  • 85,394
  • 9
  • 169
  • 201
  • This seemed to work at first but I'm experiencing some problems. My video has two audio tracks #0 English #1 Japanese the audio is ogg vorbis and they have to correct language flags. Running the command above outputs a file with the english audio only. Even if i try changing -0:a:m:language:eng to -0:a:m:language:jpn I get the same results. It seems like it's just removing the second track no matter what i do. – ffmpeg123 Dec 02 '16 at 22:12
  • This works but isn't very simple: ffmpeg -i "input,mkv" -map 0:v -map 0:s -map 0:a:m:language:jpn -c:v copy -c:a copy "output.mkv" I don't understand why "-map 0 -map -0:a:m:language:eng" doesn't work when "-map 0 -map -0:m:language:eng" does. – ffmpeg123 Dec 02 '16 at 23:10
  • 1
    Acutally, neither my answer nor your workaround works. Your workaround "works" because ffmpeg is evaluating `-map 0:a:m:language:jpn` as `-map 0:a:1`, which in your case happens to be the jpn audio. At present, this is not directly possible, but I've replaced my answer with a workaround. – Gyan Dec 03 '16 at 06:28
  • Hi Gyan, I don't quite understand what you meant by _"neither my answer nor your workaround works... Not possible at present. Use workaround on top"_. I.e., is your answer working or not? thx – xpt Oct 09 '21 at 14:56
  • My original command, at bottom, should work now. At time of writing, the parser couldn't actually evaluate `-map -0:a:m:language:eng`. – Gyan Oct 10 '21 at 04:05
1

Updated As far as I can tell this is the best way to remove English audio while retaining all other streams without using stream IDs which I find to be more inconsistent then language flags. Generally people use correct language flags however audio languages are less likely to keep the same ID.

ffmpeg -i "in.mkv" -map a -map -m:language:eng -map v -map s -map d? -map t -c:v copy -c:a copy "out.mkv"

The command will map every audio stream then remove audio with the English language flag. It will then map all video, subtitle and attachment streams. You can add -disposition:a:0 default to give the first audio stream the [default] flag if needed. Note: Only use when you are removing audio that has the default flag already. Change -disposition:a:0 to -disposition:a:1 and so on if you want to set a different audio track to default.

ffmpeg123
  • 91
  • 1
  • 1
  • 5
  • This command will duplicate the video stream* and non-English subtitle streams. *unless the video is tagged as English, which it is usually not. My workaround avoids this. – Gyan Dec 03 '16 at 13:19
  • Hmm your solution won't map attachments though how do you do that without using -map 0 or giving the ID of every single attachment stream? The first work-around you posted was making a temporary file which made the process take longer. Also if you don't use `-map 0:v` after removing the English streams won't the video get removed if it has the english flag? ? – ffmpeg123 Dec 04 '16 at 23:07
  • Modified workaround to retain data and attachment streams. Your original purpose, IIRC, was to remove only English language audio streams. My workaround does that and lets all else through. – Gyan Dec 05 '16 at 04:42
  • Your edited command still removes videos with the English flag shouldn't it be `ffmpeg -i "in.mkv" -map 0:a -map -0:m:language:eng -map 0:v -map 0:s -map 0:d? -map 0:t -c:v copy -c:a copy "out.mkv"` – ffmpeg123 Dec 08 '16 at 02:04
1

The following will copy the video and English only audio stream.

ffmpeg -i "G:\VIDEO_TS\VTS_01_1.VOB" -map i:0x1e0 -map i:0x80 "THE STRANGERS 1.mp4"

ForeverZer0
  • 2,379
  • 1
  • 24
  • 32
1

Ok, so years late here but this was top result for my search in 2023. So figured I'd add this here for anyone else. To be clear I want to KEEP English ONLY (so kinda the opposite of original post, but search is not perfect and this article is top result for googling FFMPEG KEEP ENGLISH ONLY.

FFMPEG - Keep only English audio AND convert audio to EAC3

ffmpeg -i "in.mkv" -map 0:v -map 0:a:m:language:eng -map 0:s -c:v copy -c:a eac3 -c:s copy "out.mkv"

I do batch files for .mkv so the actual code I use in .bat file is:

FOR %%f IN ("*.mkv") DO ffmpeg -i "%%f" -map 0:v -map
0:a:m:language:eng -map 0:s -c:v copy -c:a eac3 -c:s copy "%%~dpnf -
eAC3.mkv"
pause
Joe Ritze
  • 11
  • 2