-map flag in FFmpeg to explicitly select specific video and audio streams from an input file. By default, FFmpeg selects the first stream of each type, but you can override this by mapping the desired stream indices using the syntax -map 0:v:1 -map 0:a:2. This approach ensures that only the intended tracks are included in the output, avoiding unwanted audio or video layers.
Understanding Stream Indexing
Before selecting streams, it is crucial to understand how FFmpeg identifies them. Every media file contains a container format (like MP4, MKV, or M3U8) that holds multiple elementary streams. These streams are indexed starting from zero. The first video stream is 0:v:0, the second is 0:v:1, and so on. Similarly, audio streams are indexed as 0:a:0, 0:a:1, etc. If you do not specify which stream to use, FFmpeg automatically picks the first one it encounters for each type.
To see what streams are available in your file, run the following command:
ffmpeg -i input.mp4
Look for lines starting with Stream in the output. For example:
Stream #0:0(und): Video: h264...indicates the first video stream.Stream #0:1(eng): Audio: aac...indicates the first audio stream.Stream #0:2(fre): Audio: aac...indicates the second audio stream.
In this example, if you want the second audio track (French), you would target index 2 for audio.
Selecting Specific Streams with -map
The -map option tells FFmpeg which streams to include in the output. Without -map, FFmpeg may include all streams or just the first of each type depending on the version and settings. To be precise, you must map every stream you want to keep.
Suppose you have a file with two video tracks and three audio tracks. You want the second video track and the third audio track. The command would look like this:
ffmpeg -i input.mkv -map 0:v:1 -map 0:a:2 output.mp4
Here, 0:v:1 refers to the input file (0), video stream index 1 (the second video). 0:a:2 refers to the input file (0), audio stream index 2 (the third audio). Note that indices are zero-based, so the "second" item is index 1.
If you also want to ensure no other streams are accidentally copied, you can add -map 0:v:0 -map 0:a:0 to explicitly select the first ones, or simply omit others. However, best practice is to explicitly map only what you need.
Handling Multiple Inputs
When working with multiple input files, the numbering changes. Each input file gets its own index. For example, if you have two inputs:
ffmpeg -i video.mp4 -i audio.wav
The video file is 0 and the audio file is 1. To select the first video from the first file and the first audio from the second file:
ffmpeg -i video.mp4 -i audio.wav -map 0:v:0 -map 1:a:0 output.mp4
This is common when muxing separate audio and video files together. Always verify the stream indices for each input separately if unsure.
Common Pitfalls and Tips
One common mistake is assuming that stream order in the file matches the order you expect. Always check with ffprobe or ffmpeg -i before constructing your command. Another issue is codec compatibility. Selecting a specific stream does not guarantee it will play in the target container. For example, trying to put a high-efficiency HEVC video into an older MP4 container might fail unless you transcode it.
If you encounter errors about unsupported codecs, consider transcoding instead of copying. Replace -c copy with appropriate encoder flags. For instance, to convert the selected video to H.264:
ffmpeg -i input.mkv -map 0:v:1 -map 0:a:2 -c:v libx264 -c:a aac output.mp4
This ensures broad compatibility across devices and browsers. Remember that transcoding takes time and may reduce quality, so use -c copy whenever possible for lossless extraction.
For more advanced editing tasks, such as adding overlays or modifying timestamps, you might need additional filters. See Add Moving Logo to Long Video Using FFMPEG for examples of complex stream manipulation involving visual elements.
Frequently Asked Questions
How do I know which stream index to use?
Run ffmpeg -i yourfile.ext and look at the Stream lines. The number after the colon (e.g., 0:1) is the index. Count from zero, so the second video is index 1.
Can I select a stream by language instead of index?
FFmpeg does not directly support selecting by language in the -map command line easily. You typically identify the stream by its metadata (language tag) using ffprobe and then hardcode the corresponding index in your command.
Why does my output have no audio even though I mapped it?
Ensure you used -map for both video and audio. If you only map video, FFmpeg might ignore audio entirely. Also, verify that the source file actually contains the audio stream at that index.
What if I want to drop all subtitles?
Simply do not map subtitle streams. By default, FFmpeg copies the first subtitle stream. To prevent this, explicitly map only video and audio, e.g., -map 0:v:0 -map 0:a:0.
Is it faster to copy streams than to re-encode?
Yes, using -c copy is nearly instantaneous because it avoids CPU-intensive decoding and encoding. It only repackages the existing data into the new container format.