72

How to remove only one track (not all) from video file container (.vob or .mkv) using ffmpeg?

I know I can just copy video (-c:v copy -an) and specific audio track from container into two separated files and then join them.

But is there an easier way? Can I just remove specific audio track from container? ffmpeg command?

user25
  • 2,873
  • 2
  • 30
  • 66

4 Answers4

180

The most efficient method is to use negative mapping in the -map option to exclude specific stream(s) ("tracks") while keeping all other streams.

Remove a specific audio stream / track

ffmpeg -i input -map 0 -map -0:a:2 -c copy output
  • -map 0 selects all streams from the input.
  • -map -0:a:2 then deselects audio stream 3. The stream index starts counting from 0, so audio stream 10 would be 0:a:9.

Remove all audio streams / tracks

ffmpeg -i input -map 0 -map -0:a -c copy output
  • -map 0 selects all streams from the input.
  • -map -0:a then deselects all audio streams from the input.

Remove specific audio streams / tracks

Keep everything except audio streams #4 (at offset 3) and #7 (at offset 6):

ffmpeg -i input -map 0 -map -0:a:3 -map -0:a:6 -c copy output

Remove all subtitles and data

ffmpeg -i input -map 0 -map -0:s -map -0:d -c copy output

Only include video and audio

This example does not need to use any negative mapping.

ffmpeg -i input -map 0:v -map 0:a -c copy output

Removing other stream / track types

If you want to remove other stream types you can use the appropriate stream specifier.

  • v - video, such as -map -0:v
  • a - audio, such as -map -0:a (as shown above)
  • s - subtitles, such as -map -0:s
  • d - data, such as -map -0:d
  • t - attachments, such as -map -0:t

Extract or remove a specific audio channel

Using a stereo input and channelsplit filter. Example to get the right channel only and output a mono audio file:

ffmpeg -i stereo.wav -filter_complex "[0:a]channelsplit=channel_layout=stereo:channels=FR[right]" -map "[right]" front_right.wav
  • channel_layout is the channel layout of the input stream. The default is stereo.

  • channels lists the channels to be extracted as separate output streams. The default is all which extracts each input channel as a separate, individual stream.

  • See ffmpeg -layouts for a list of accepted channel layouts (for channel_layout option) and channel names (for channels option).

  • See FFmpeg Wiki: Audio Channels for more examples.

More info

Mitch McMabers
  • 3,634
  • 28
  • 27
llogan
  • 121,796
  • 28
  • 232
  • 243
  • Wow, i didn't know about the negative mapping functionality, awesome! – v010dya Jul 02 '16 at 16:58
  • 2
    Instead of -0:a:1 , to delte the other audio can use -0:a:0 – Astor Florida Feb 14 '18 at 17:40
  • 2
    To delete all audio (and keep video, data, etc.): `ffmpeg -i input -map 0 -map -0:a -c copy output` Similarly, to delete all video: `ffmpeg -i input -map 0 -map -0:v -c copy output` – verbamour Mar 29 '19 at 14:46
  • Can you do me a favor and while this is a great explanation, could you possibly show an example video file info layout? ffmpeg -i that shows a video stream, an audio stream, a data stream, and a subtitles stream? And then use that example to explain how to correctly deselect a stream? – julesverne Apr 14 '20 at 23:33
  • A problem I had with this approach is that it doesn't change the format of the audio stream. In my case removing 3 of 4 audio channels still resulted in ffmpeg reporting that the stream was "quad". I solved it by using `ffmpeg -i 'in.mov' -c:v copy -map_channel 0.1.0 'out.mov'` instead, which resulted in a proper "mono" audio stream. – Synchro Jul 27 '20 at 19:01
  • 1
    @Synchro I'll add a "remove channel" section. I didn't consider users would want to do that when finding this answer. – llogan Jul 27 '20 at 19:04
  • How do you combine the streams to be removed? Say, I want to remove all subtitle and data streams. Or I want to remove first and third subtitle streams. Also, is the stream index based on type or global? E.g. if there are two audio streams, will the first subtitle stream have index of 0 or 3 (0=video, 1=audio1, 2=audio2, 3=subtitle1)? – Alek Davis Oct 26 '20 at 02:25
  • 1
    @AlekDavis See updated answer for more examples. Stream index can be either global or type based, depending on the syntax you want to use, but all of these examples use type based indexing. See [FFmpeg Wiki: Map](https://trac.ffmpeg.org/wiki/Map) for an illustrated example showing the differences. – llogan Oct 26 '20 at 03:32
  • Just wanted to say thanks for providing the section on the available stream/track types. I've been looking for that but I wasn't able to find it on the ffmpeg documentation pages. I guess I was looking at the wrong places but that link clarified it. Is there any shorthand notations like "-sn" which removes subtitles? – 97WaterPolo Jan 04 '23 at 19:25
7

You are looking for -map.

I have changed to using avconv, but it should be about the same.

Let's say you have a file called "input.vob" with one video and two audio tracks; and you want to have "output.vob" with the video and the last audio.

You would do:

avconv -i input.vob -map 0:0 -c:v copy -map 0:2 -c:a copy output.vob

You should notice that:

  1. I did not copy -map 0:1
  2. I did not need to do -an, because there are audio tracks. However, if there are no audio tracks at all, you may need to use such an attribute.
  3. Sometimes the streams are not numbered in the way i've described, for example audio can come before video.
  4. If there are subtitle streams there, you need to figure out how to deal with them as well.

You cannot work on files "in place", you need to save into a different file.

P.S. You may want to ask such questions on video.stackexchange.com next time.

Community
  • 1
  • 1
v010dya
  • 5,296
  • 7
  • 28
  • 48
4

llogan's answer at https://stackoverflow.com/a/38162168/2238126 probably mostly answers it. However if his answer didn't work for you (as was the case with me), use -map_chapters -1. For me, -map_chapters -1 removed a Data stream that I was having trouble removing.

Use the following:
ffmpeg -i in.mp4 -c:v copy -c:a copy -map_chapters -1 out.mp4 -y

(-map -0:d might also work)

Thanks hamidi at Discard data stream from container using ffmpeg

Rublacava
  • 414
  • 1
  • 4
  • 16
2

You just solved my av1 muxing issue, which requires -map 0 to include the subtitle font from original-video.mkv.

ffmpeg.exe -i original-video.mkv -i svt-av1.ivf -map 0 -map -0:v:0 -map 1:v:0 -c copy output.mkv

-map 0 selects everything, including the subtitle font which is, erroneously, in the wrong stream of the input file. -map -0:v:0 remove all video. -map 1:v:0 re-adds video from second input, which is the re-encoded AV1 of original-video.mkv.

rainer
  • 3,295
  • 5
  • 34
  • 50
Joachim Otahal
  • 272
  • 2
  • 9