FFmpeg Tee Muxer: Transcode and Copy Streams
This guide explains how to configure FFmpeg's tee muxer
to output a stream-copied feed to one target while simultaneously
transcoding it for another. Because the tee muxer operates
at the muxer level after encoding has already taken place, you cannot
transcode directly inside the tee slave definition.
Instead, you must map the source streams multiple times, set up both the
copy and transcode operations in the main FFmpeg pipeline, and then use
the tee muxer's select option to direct the
respective streams to each destination.
The Configuration Command
ffmpeg -i input.mp4 \
-map 0:v -c:v:0 copy \
-map 0:v -c:v:1 libx264 -preset veryfast -b:v:1 3000k \
-map 0:a -c:a copy \
-f tee "[select=\'v:0,a:0\']backup.mp4|[select=\'v:1,a:0\':f=flv]rtmp://live.example.com/app/stream"Breakdown of the Pipeline
1. Stream Mapping and Codec Setup
-map 0:v -c:v:0 copy: Takes the video stream from the first input (0:v) and assigns it to output video stream index0(v:0) without re-encoding (copy).-map 0:v -c:v:1 libx264 -preset veryfast -b:v:1 3000k: Maps the same input video stream a second time to output video stream index1(v:1) and transcodes it using thelibx264encoder.-map 0:a -c:a copy: Maps the input audio stream to be copied directly without re-encoding. If transcoding audio is also required for the second output, map0:atwice with distinct codec configurations in the same manner as the video.
2. The tee Muxer
Configuration
The -f tee argument accepts pipe-separated
(|) slave definitions wrapped in brackets:
- Destination 1 (Stream Copy):
[select=\'v:0,a:0\']backup.mp4selects the stream-copied video (v:0) and the copied audio (a:0) and packages them into a local file. The file container is inferred from the.mp4extension. - Destination 2 (Transcoded Stream):
[select=\'v:1,a:0\':f=flv]rtmp://live.example.com/app/streamselects the transcoded video (v:1) along with the copied audio (a:0). Since RTMP targets do not use file extensions to determine the format, the container format is explicitly specified using:f=flv.
Escaping and Options
- Quoting
selectvalues: Commas and colons insideteetarget parameters must be properly escaped. In standard Bash shells, wrap the entire slave block in quotes and escape the internal parameter quotes:[select=\'v:0,a:0\']. - Handling Connection Drops: For network
destinations, append
:onfail=ignoreto the bracketed options (for example,[select=\'v:1,a:0\':f=flv:onfail=ignore]). This ensures that network failure on the transcoded live stream does not terminate the local file recording.