Configure Select Maps in FFmpeg Tee Muxer

The FFmpeg tee muxer allows you to write the same network stream or file to multiple outputs simultaneously without re-encoding the content multiple times. By default, the tee muxer passes all mapped input streams to every defined output, which can cause failures if an output format does not support certain codecs or if you intend to split streams. You can control which streams are routed to which output by using the select slave option within the tee muxer string.

Understanding the select Option

When using the tee muxer, slave outputs are separated by a pipe (|) character, and per-output options are placed inside square brackets [...] before the output destination.

The select slave option filters the streams forwarded to that specific output. It takes a comma-separated list of stream specifiers or zero-based stream indices relative to the streams delivered to the muxer.

Escaping Rules

Because FFmpeg uses colons (:) and commas (,) as internal option delimiters, and shells (like Bash) treat characters like |, [, ], and ' specially, you must escape the select string properly:

  • Wrap the entire -f tee argument in double quotes.
  • Enclose the select parameter value in escaped single quotes: [select=\'...\'].

Basic Syntax and Examples

Example 1: Selecting by Stream Type and Index

Suppose you have an input with one video stream and two audio streams (such as English and Spanish), and you want to write:

  • Output 1: Video and Audio 0
  • Output 2: Video and Audio 1
ffmpeg -i input.mkv -map 0:v -map 0:a:0 -map 0:a:1 \
-c copy \
-f tee "[select=\'v:0,a:0\']output_en.mp4|[select=\'v:0,a:1\']output_es.mp4"

In this example:

  • -map 0:v -map 0:a:0 -map 0:a:1 feeds three streams to the tee muxer.
  • [select=\'v:0,a:0\'] forwards the video and the first audio stream to output_en.mp4.
  • [select=\'v:0,a:1\'] forwards the video and the second audio stream to output_es.mp4.

Example 2: Selecting by Global Stream Indices

Instead of type-based specifiers, you can reference the zero-based indices of the streams as mapped into the tee muxer:

ffmpeg -i input.mp4 \
-map 0:v:0 -map 0:a:0 -map 0:a:1 \
-c copy \
-f tee "[select=\'0,1\']main.mp4|[select=\'0,2\']secondary.mp4"

Here:

  • Index 0 refers to -map 0:v:0
  • Index 1 refers to -map 0:a:0
  • Index 2 refers to -map 0:a:1

Example 3: Applying Bitstream Filters Alongside select

Slave options can be chained together inside the brackets by separating them with colons. If an output requires a specific bitstream filter (such as h264_mp4toannexb for an MPEG-TS output), place it alongside the select option:

ffmpeg -i input.mp4 \
-c copy \
-f tee "[select=\'v,a\':bsfs/v=h264_mp4toannexb]stream.ts|[select=\'v,a\']local.mp4"

Common Pitfalls

  • Empty Streams: If a select query does not match any stream, the muxer may throw an error indicating that an output contains no streams.
  • Transcoding Configurations: The select option only routes streams that have already been generated and mapped by the main FFmpeg pipeline. All stream transformations (filtering, encoding) must be fully established with -map before reaching the tee muxer.