I'm trying to re-encode video streams from a Matroska file to save space, while keeping all the subtitles as-is, using ffmpeg. I want to write a generic command that works without me having to specify exact stream numbers. Now I can't figure out how to let ffmpeg pick its default video stream and default audio stream and then all subtitles.

The current input file I'm working with has these streams, but other files will have different streams.

    [lavf] stream 0: video (mpeg2video), -vid 0
    [lavf] stream 1: audio (ac3), -aid 0, -alang eng, Surround 5.1
    [lavf] stream 2: audio (ac3), -aid 1, -alang fre, Surround 5.1
    [lavf] stream 3: audio (ac3), -aid 2, -alang ita, Surround 5.1
    [lavf] stream 4: audio (ac3), -aid 3, -alang spa, Surround 5.1
    [lavf] stream 5: audio (ac3), -aid 4, -alang eng, Stereo
    [lavf] stream 6: subtitle (dvdsub), -sid 0, -slang eng
    [lavf] stream 7: subtitle (dvdsub), -sid 1, -slang fre
    [lavf] stream 8: subtitle (dvdsub), -sid 2, -slang ita
    [lavf] stream 9: subtitle (dvdsub), -sid 3, -slang spa
    [lavf] stream 10: subtitle (dvdsub), -sid 4, -slang ara
    [lavf] stream 11: subtitle (dvdsub), -sid 5, -slang dan
    [lavf] stream 12: subtitle (dvdsub), -sid 6, -slang dut
    [lavf] stream 13: subtitle (dvdsub), -sid 7, -slang fin
    [lavf] stream 14: subtitle (dvdsub), -sid 8, -slang ice
    [lavf] stream 15: subtitle (dvdsub), -sid 9, -slang nor
    [lavf] stream 16: subtitle (dvdsub), -sid 10, -slang por
    [lavf] stream 17: subtitle (dvdsub), -sid 11, -slang swe
    [lavf] stream 18: subtitle (dvdsub), -sid 12, -slang fre
    [lavf] stream 19: subtitle (dvdsub), -sid 13, -slang ita
    [lavf] stream 20: subtitle (dvdsub), -sid 14, -slang spa

Commands I have tried:

ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska OUT.mkv

Result: One video stream, one audio stream, no subtitle streams.

ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -c:s copy OUT.mkv

Result: One video stream, one audio stream, one subtitle stream.

ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -map 0 OUT.mkv

Result: All video, all audio, all subtitles.

ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -c:s copy -map 0:s OUT.mkv

Result: No video, no audio, all subtitles.

As far as I can tell from the manual, -c:s copy is supposed to copy all the streams, not just the default one, but it won't. Perhaps it's a bug?

To clarify, what I'm after is the result: one video, one audio and all subtitles.


The stream selection default behavior only selects one stream per type of stream, so inputs with multiple audio streams will create an output with one audio stream. To disable this behavior and manually choose desired streams use the -map option.

These examples use -c copy to stream copy (re-mux) from the input to to the output. No re-encoding occurs.

Stream copy all streams

ffmpeg -i input -map 0 -c copy output

1st video stream, 2nd audio stream, all subtitles

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

3rd video stream, all audio streams, no subtitles

This example uses negative mapping to exclude the subtitles.

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

Choosing streams from multiple inputs

All video from input 0, all audio from input 1:

ffmpeg -i input0 -i input1 -map 0:v -map 1:a -c copy output
  • I give +1 for answer, but it would be very helpful to amend it with: To select all video and the third audio stream from an input file: ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT Same is fo all audio streams, which could be noted as 0:a – Arunas Bartisius Jan 29 '18 at 15:29
  • @ArunasBartisius: You can edit and improve the answer while the original author is sleeping so he can approve when he wakes up... +1 – Fabby Nov 20 '18 at 18:08
  • I added some more examples. – llogan Nov 20 '18 at 18:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.