FFmpeg Tee Muxer: Transcode One Output Copy Another

Using the FFmpeg tee muxer allows you to split an input stream into multiple outputs simultaneously. This guide explains how to configure the tee muxer to transcode one of those outputs (such as changing the bitrate or codec) while performing a direct stream copy (without re-encoding) on another, optimizing your system’s resources and stream delivery.


The Challenge with Tee and Transcoding

The tee muxer operates at the muxer level, meaning it receives already-encoded packets and writes them to multiple destinations. Because it does not encode data itself, you cannot transcode “inside” the tee muxer.

To transcode one output and copy another, you must configure FFmpeg to generate two sets of streams in the encoder pipeline first: one copied stream and one transcoded stream. You then use the tee muxer’s select option to route each stream to its designated destination.

The FFmpeg Command Syntax

Here is the template command to achieve this:

ffmpeg -i input.mp4 \
  -map 0:v -map 0:a \
  -map 0:v -map 0:a \
  -c:v:0 copy -c:a:0 copy \
  -c:v:1 libx264 -b:v 2500k -c:a:1 aac -b:a 128k \
  -f tee "[select=\'v:0,a:0\']output_copy.mp4|[select=\'v:1,a:1\':f=flv]rtmp://live.twitch.tv/app/stream_key"

Command Breakdown

1. Mapping the Inputs

To create two independent output streams from a single input, you must map the input streams twice: * -map 0:v -map 0:a maps the video and audio to the first output stream group index (0). * -map 0:v -map 0:a maps them again to the second output stream group index (1).

2. Defining Stream Specs (Copy vs. Transcode)

Next, assign different encoder settings to each mapped stream using stream specifiers (:0 and :1): * For the Copy Output (Index 0): -c:v:0 copy -c:a:0 copy tells FFmpeg to copy the original video and audio packets directly without re-encoding. * For the Transcoded Output (Index 1): -c:v:1 libx264 -b:v 2500k -c:a:1 aac -b:a 128k transcodes the second stream into H.264 video at 2500k and AAC audio at 128k.

3. Routing Streams with the Tee Muxer

The -f tee flag initiates the muxer. Inside the tee arguments, outputs are separated by a pipe (|), and the select option filters which streams go where: * [select=\'v:0,a:0\']output_copy.mp4 routes the copied streams (index 0) to a local MP4 file. * [select=\'v:1,a:1\':f=flv]rtmp://... routes the transcoded streams (index 1) to an RTMP server, forcing the FLV format with the :f=flv flag.

Escaping Special Characters

Note the backslashes before the single quotes (\'v:0,a:0\'). Depending on your operating system’s terminal (Bash, Zsh, or Windows Command Prompt), you must escape single quotes and colons so the shell passes the string to FFmpeg correctly. If you are using Windows CMD, you may use double quotes instead of single quotes and omit the backslashes.