Skip to main content

FFmpeg tee builder

Paste your RTMP or RTMPS destinations and get the -f tee argument, or a whole FFmpeg command, that streams to all of them at once. If one platform refuses the connection or stops reading, the others keep going. It runs entirely in your browser. It is also a free MIT-licensed command-line tool and Python library.

Destinations

Built in this page: nothing you type here is sent anywhere, and the page does not save it.

Output
Video and audio

Sets rw_timeout. Without a timeout, the other destinations keep streaming, but a server that accepts the connection and never answers can stop FFmpeg from exiting when the stream ends.

Result

Quoted for bash, zsh or sh: paste it as it is. Do not pass it through zsh's echo, which turns the two backslashes into one.

ffmpeg -hide_banner -re -i input.mp4 -map 0:v:0 -map 0:a:0 -c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k -g 60 -pix_fmt yuv420p -c:a aac -b:a 160k -ar 44100 -f tee '[f=flv:flvflags=+no_duration_filesize:onfail=ignore:use_fifo=1:fifo_options=queue_size=600\\:drop_pkts_on_overflow=1]rtmp://a.rtmp.youtube.com/live2/YOUR-YOUTUBE-KEY|[f=flv:flvflags=+no_duration_filesize:onfail=ignore:use_fifo=1:fifo_options=queue_size=600\\:drop_pkts_on_overflow=1]rtmp://live.twitch.tv/app/YOUR-TWITCH-KEY'
2 destinations.

What each option is for

FFmpeg's tee muxer encodes once and writes the same packets to every destination, so a stream to three platforms costs barely more CPU than a stream to one. All of its configuration goes into one argument, and three parts of that argument fail without an error message.

OptionWhat happens without it
onfail=ignoreThe documented default is abort. If one destination refuses the connection, for example because its key was reset or its event was ended, the whole process stops and every other platform goes off air with it.
use_fifo=1tee writes to all destinations from a single thread. A server that keeps the socket open but stops reading eventually blocks that write for every destination. No error is reported, and every destination still looks connected.
drop_pkts_on_overflow=1A queue on its own only delays the same freeze. When the queue is allowed to drop packets, the stalled destination loses them and the others continue in real time.
queue_size=600\\:drop_pkts_on_overflow=1tee removes one level of escaping from the destination options, and the nested fifo_options removes another. With a single backslash, drop_pkts_on_overflow reaches the flv muxer, which rejects it with Unknown option, and every output fails.

The URLs are checked too. In a tee argument, | separates destinations, [ and ] mark option blocks and the backslash escapes characters. A stream key containing any of them silently changes the command. Those characters and any whitespace are refused, and the error names the line but never shows the key.

These defaults are what our own multi-destination 24/7 streams have used in production since August 2026. The project's test suite checks each claim above against a real FFmpeg and local RTMP servers. One test reproduces the freeze without the queue, and another shows that a single backslash takes every output down.

The same thing from a terminal or from Python

The command-line version reads URLs from a file or standard input, so stream keys stay out of your shell history.

pip install git+https://github.com/YouPanel/ffmpeg-tee-builder

ffmpeg-tee-builder --command -i show.mp4 --timeout 10 --file destinations.txt > stream.sh
sh stream.sh

As a library, it returns an argument list ready for subprocess, with no shell quoting to get wrong:

from ffmpeg_tee_builder import build_command
import subprocess

urls = ["rtmp://a.rtmp.youtube.com/live2/KEY1", "rtmp://live.twitch.tv/app/KEY2"]
subprocess.run(build_command(urls, input="show.mp4", timeout=10), check=True)

Source, tests and the full write-up: ffmpeg-tee-builder on GitHub (MIT) · One stalled RTMP destination froze all the others

Or skip running FFmpeg yourself

TheLoops runs this fan-out in the cloud around the clock: upload your videos once and stream them as a 24/7 broadcast to several platforms, with your computer switched off.

Start Free Trial

Questions

No, it encodes once. The encoder runs a single time, and tee copies the resulting packets to each output. That is why every destination gets the same bitrate and resolution: a platform with a lower limit sets the limit for all of them, unless you run separate outputs.

The tee muxer does not choose streams by itself the way an ordinary output does, so without -map it can end up with no audio or no video. The generated command maps the first video and the first audio stream of the input.

With onfail=ignore, FFmpeg logs that the slave muxer failed and continues with the rest, for example continuing with 1/2 slaves. That destination stays off until FFmpeg is restarted. tee does not reconnect a failed destination on its own, so a long-running stream needs a supervisor that restarts it.

Yes. rtmps:// addresses are accepted, including ones with an explicit port such as Facebook's rtmps://live-api-s.facebook.com:443/rtmp/. The colon before the port is safe inside a tee argument, because options are read only inside the square brackets.

No. The builder on this page runs in your browser and makes no requests with what you type. The command-line version runs on your machine and can read keys from a file instead of from arguments.