11

I'm trying to copy video/audio from an mkv container to mp4. When I run ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4 I'm given no video with polish audio. There's only one video stream, stream #0:0. Stream #0:1 is polish audio, #0:2 english, and #0:3 - #0:5 are subtitles.

I read FFmpeg Wiki: Map but don't understand it really. Why is -map 0:1 written twice in example 1? What does -c:s do? What would a command to copy #0:0 to video and #0:2 to audio look like?

5 Answers 5

13

-map <inputNo>:<streamNo> tells ffmpeg to take stream streamNo from the input inputNo and to add it to the output, where <inputNo> starts with 0.

Sometimes, you may want to take the same input stream twice (such as -map 0:1 -map 0:1 in the example) because you can encode each with different codecs/parameters. In the example, the output contains the same audio stream twice, one in MP3 and the other in AAC.

By default (i.e. with no -map command at all), one video, one audio, and one subtitle stream from the inputs are taken. If you want to map all the streams from one input, use -map <inputNo>.

That you don't get video with your command can only mean one thing : your video track is encoded with a codec that can be muxed in MKV, but not in MP4. So it is discarded automatically. Can you post a log of ffmpeg -i input.mkv so that we can check which codecs the tracks are encoded with ?

Finally, -c:s is used for subtitle codec (while -c:a is for audio and -c:v for video)

1
  • 4
    "By default (i.e. with no -map command at all), all the streams from all the inputs are taken once." — this is not true. ffmpeg will only take one audio, video, and subtitle stream. If you want all the streams mapped, you need -map 0.
    – slhck
    Commented Jul 18, 2015 at 8:20
6

This was the example that allowed me to understand. Imagine the following command:

ffmpeg -i tears_of_steel.mkv -map 0:0 -map 0:2 -map 0:1 -map 0:4 -map 0:3 -c copy tears_of_steel-v2.mkv 

And here is how ffmpeg does the mapping:

Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:2 -> #0:1 (copy)
Stream #0:1 -> #0:2 (copy)
Stream #0:4 -> #0:3 (copy)
Stream #0:3 -> #0:4 (copy)

What happened?

In the command, we have only one input: tears_of_steel.mkv. That's why all our maps start with #0:...

Then we write a first map option: -map 0:0, which refers to the first stream of our input (tears_of_steel.mkv), which might be a video stream, but that doesn't matter.

Because it's the first map option, it will be mapped to the first stream in our output file (tears_of_steel-v2.mkv).

Then we write a second map option: -map 0:2, which refers to the third stream of our input. Because it's the second map option, it is mapped to the second stream in our output.

And so on...

I wrote that on my github: https://github.com/lingtalfi/ffmpeg-notes/blob/master/ffmpeg-map.md

1

Here's how -c (select codecs) & -map (select streams) options work:

-c:a -> select first or best supported audio (transcoded)
-c:a copy -> best supported audio (copied)
-map 0:a -> all audio from 1st input file (transcoded)
-map 1:a:0 -> 1st audio stream from 2nd input file (transcoded)
-map 1:a:1 -c:a copy -> 2nd audio stream from 2nd input file (copied)

To copy all subtitle streams from 1st input file without transcoding:

-map 0:s -c:s copy 

Your outfile is mp4 and input file is mkv and you've elected to have video output without transcoding (-c:v copy) to a compatible format for mp4, so you end up with an mp4 file without (a playable) video.

Either specify video encoder compatible with mp4 eg. -c:v libx264 instead of -c:v copy or leave that blank (ie. don't mention an encoder & ffmpeg encoders chosen will be the default ones registered by each output format)

If you don't want to transcode video (because it can take a considerable time) , then copy the video stream to same container but select the audio you want eg. mkv. To get an mp4 file with transcoded video & selected audio:

ffmpeg -i input.mkv -map 0:0 -c:v libx264 -map 0:2 -c:a copy output.mp4
0

This should work, can't test on this machine:

ffmpeg -i input.mkv
-map 0:0 -map 0:2 \
-c:v copy \
-c:a aac \
-b:a 128k \
output.mp4

or

ffmpeg -i input.mkv -map 0:0 -map 0:2 -c:v copy -c:a aac -b:a 128k output.mp4

Explanations

c:s is an alias for -scodec codec, which specifies the subtitle codec.

-map 0:1 is there twice because the example has an aac and an mp3 output.

1
  • Won't work because -c:a aac needs -strict experimental too.
    – slhck
    Commented Jul 18, 2015 at 8:22
0

This is a simple answer for people like me, who like simple working explanations. This is a solution when you copy mkv to mp4 and want to choose audio streams:

You have to write -map 0:numberofstreamminusone in front of -c:a copy

Let's say the video has 3 streams (you can see that in mediainfo). The first stream is video, the second is default audio, and the third is non-default audio in the language you want. So you have to write -map 0:2 NOT -map 0:3

Also, you have to write -map 0:0 in front of -c:v copy because if you don't, ffmpeg will not copy the video stream and you get only the audio stream (If the video has two video streams and you want to copy the second one, you have to write -map 0:1)

So the final command line looks like this:

ffmpeg -i "inputpath\input.mkv" -map 0:0 -c:v copy -map 0:2 -c:a copy "outputpath\output.mp4"

In this case, you wil get the first video stream and the third audio stream

Another example:

ffmpeg -i "inputpath\input.mkv" -map 0:1 -c:v copy -map 0:6 -c:a copy "outputpath\output.mp4"

In this case you should get the second video stream and the seventh audio stream

I hope this helps

2
  • The examples seem inaccurate, or the wording is confusing. As I understand it, “0:2” refers to the third stream, regardless of its type, so most likely the second audio stream (if there is only one video stream and the streams are placed in “logical” order in the input); likewise, in the second example, “0:6” would be the sixth audio stream if stream 0 in input is a video stream and 1-6 are audio streams.
    – GabrielB
    Commented Nov 25, 2018 at 13:42
  • When you say "in front of -c:a copy", do you mean before or after "-c:a copy"?
    – Zimba
    Commented Feb 11, 2021 at 1:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .