ffmpeg over SRT, without the guesswork
ffmpeg speaks SRT natively, but the documentation is a list of options rather than a set of working commands. Here are the ones you need, with the reasoning behind each flag.
Check your build has it:
ffmpeg -protocols 2>/dev/null | grep srt
No output means your build was compiled without libsrt — on Debian and Ubuntu install ffmpeg from the distribution rather than a minimal static build.
Receive and watch
ffplay -fflags nobuffer -flags low_delay \
"srt://de.inoutsrt.com:6999?streamid=read:beacon&latency=200"
nobuffer and low_delay stop ffplay adding its own second of delay on top of SRT's buffer. Drop them when you care about smoothness rather than latency.
Receive and record, without re-encoding
ffmpeg -i "srt://host:port?latency=300" -c copy -f mpegts recording.ts
Record to MPEG-TS, not MP4: if the machine dies mid-recording, a TS file is still playable and an MP4 is a broken container. Remux afterwards:
ffmpeg -i recording.ts -c copy -movflags +faststart recording.mp4
Send a file as if it were live
ffmpeg -re -stream_loop -1 -i source.mp4 \
-c:v libx264 -preset veryfast -tune zerolatency -profile:v main -pix_fmt yuv420p \
-b:v 4000k -maxrate 4000k -bufsize 4000k -g 50 -keyint_min 50 -sc_threshold 0 \
-c:a aac -b:a 128k -ar 48000 -ac 2 \
-f mpegts "srt://host:port?latency=300&pkt_size=1316"
What matters here:
-replays at real time; without it ffmpeg blasts the whole file at once and the receiver drowns-tune zerolatencydisables lookahead and B-frame delay-g 50 -keyint_min 50 -sc_threshold 0gives a keyframe every 2 seconds at 25 fps, which is how fast a receiver can join or recover-maxrateequal to-b:vwith a matchingbufsizeis as close to CBR as x264 gets withoutnal-hrd-f mpegtsis mandatory: SRT carries transport streams, not MP4
Send a camera
Linux, V4L2:
ffmpeg -f v4l2 -framerate 25 -video_size 1280x720 -i /dev/video0 \
-f alsa -i default \
-c:v libx264 -preset veryfast -tune zerolatency -b:v 3000k -maxrate 3000k -bufsize 3000k \
-g 50 -c:a aac -b:a 128k -ar 48000 \
-f mpegts "srt://host:port?latency=400&pkt_size=1316"
macOS, AVFoundation — list devices first with ffmpeg -f avfoundation -list_devices true -i "":
ffmpeg -f avfoundation -framerate 30 -i "0:0" \
-c:v libx264 -preset veryfast -tune zerolatency -b:v 3000k -maxrate 3000k -bufsize 3000k \
-g 60 -c:a aac -b:a 128k -ar 48000 \
-f mpegts "srt://host:port?latency=400&pkt_size=1316"
Listener mode: wait for someone to connect
ffmpeg -i "srt://0.0.0.0:5000?mode=listener&latency=300" -c copy -f mpegts out.ts
ffmpeg's SRT listener accepts one connection. For several receivers you need a relay or a media server — this is exactly the gap a hosted relay fills.
Encryption
srt://host:port?passphrase=YourLongPassphrase&pbkeylen=24&latency=300
The passphrase is 10–79 characters, and pbkeylen must match on both ends — 16, 24 or 32. A mismatch reports as "1011 Password required", which reads like a missing password even when you sent one. Quote the whole URL in your shell: & would otherwise background the process, and ? may glob.
Stream IDs
srt://host:port?streamid=read:beacon # application-specific syntax
srt://host:port?streamid=#!::r=beacon,m=request # standard SRT Alliance syntax
Send whichever your server documents. In a shell, # starts a comment — the standard syntax must be inside quotes, or written as %23.
Restream one input to two destinations
ffmpeg -i "srt://host:4000?latency=300" -c copy -f mpegts "srt://host:6000?latency=300" \
-c copy -f mpegts "srt://host:6001?latency=300"
Both outputs share one decode and one input connection. If they need different bitrates, you are re-encoding, and a second ffmpeg process is easier to reason about than a filter graph.
Useful URL parameters
| Parameter | What it does | Sensible value |
|---|---|---|
latency | Receiver buffer in ms — the room SRT has to recover losses | calculate it |
pkt_size | Payload size; 1316 = 7 × 188-byte TS packets, fits a 1500-byte MTU | 1316 |
mode | caller, listener or rendezvous | caller |
passphrase / pbkeylen | AES encryption | match both ends |
maxbw | Bandwidth cap in bytes per second, −1 for unlimited | usually leave alone |
streamid | Which stream you want, and sometimes credentials | as documented |
maxbw deserves a warning: it is bytes per second, not bits, and setting it too low throttles your own stream into stuttering. Leave it at the default unless you are deliberately capping a link.
Diagnosing
Print what is actually arriving:
ffprobe -v error -show_streams -show_format -of flat "srt://host:port?latency=300"
Watch SRT's own statistics while running — add -loglevel debug and look for rtt, pktRcvLoss and pktRetrans. Rising retransmissions with stable RTT means a lossy link; rising RTT means congestion, and more buffer will not fix the cause.
No stream to test against? Point any of these commands at the free test signal — it is a known-good source, so anything that fails against it is on your side.
Need a tunnel that carries your own video?
IN/OUT-SRT is a hosted SRT relay in Germany and the USA. Your encoder connects in, your receiver connects out — no static IP, no port forwarding, nothing installed. Three free 30-minute sessions every day; a full production day is $5.