How to remove one track from video file using ffmpeg?
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?
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 be0: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 isstereo
. -
channels
lists the channels to be extracted as separate output streams. The default isall
which extracts each input channel as a separate, individual stream. -
See
ffmpeg -layouts
for a list of accepted channel layouts (forchannel_layout
option) and channel names (forchannels
option). -
See FFmpeg Wiki: Audio Channels for more examples.
More info
-map
option documentation- FFmpeg Wiki: Map
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:
- I did not copy
-map 0:1
- 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. - Sometimes the streams are not numbered in the way i've described, for example audio can come before video.
- 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.
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.
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