ffmpeg
ffmpeg recipes for a test pattern, a looped file and a camera, over SRT or RTMP, with the options that keep the delay low.
ffmpeg is the quickest way to put a stream on the air from a script or a terminal. It sends over SRT or RTMP, with the stream key from the API. ffmpeg's WHIP output is not supported (see WHIP).
The examples use ingest.nearglass.com and a key stk_...: take the whole
address from publish.srt or publish.rtmp in POST /v1/streams's answer.
Put the address in quotes, because of the ? in it.
The options that matter
| Option | Why |
|---|---|
-c:v libx264 -preset veryfast -tune zerolatency | H.264, with look-ahead and B-frames off |
-bf 0 | no B-frames, even if a preset adds them |
-force_key_frames "expr:gte(t,n_forced*1)" | a keyframe every second, whatever the frame rate |
-b:v 3M -maxrate 3M -bufsize 1M | close to constant bitrate |
-f mpegts -pes_payload_size 0 (SRT) | each audio packet goes out when it is encoded; without it ffmpeg gathers a fraction of a second of sound first |
-c:a libopus -b:a 128k -ar 48000 -application lowdelay -frame_duration 20 (SRT) | Opus, passed to viewers as it is |
-c:a aac -b:a 128k | AAC-LC: carried, and turned into Opus at the ingest. Use it for RTMP |
-re | for a file: read it at its own speed, as a live source |
The picture rules (keyframe interval, B-frames, bitrate) are in the table.
A test pattern
A moving picture and a tone, no camera or file needed. Good for checking that a stream plays before you point an encoder at it.
ffmpeg -re -f lavfi -i "testsrc2=size=1280x720:rate=30" \
-f lavfi -i "sine=frequency=440:sample_rate=48000" \
-c:v libx264 -preset veryfast -tune zerolatency -bf 0 -pix_fmt yuv420p \
-force_key_frames "expr:gte(t,n_forced*1)" -b:v 2M -maxrate 2M -bufsize 1M \
-c:a libopus -b:a 128k -ar 48000 -application lowdelay -frame_duration 20 \
-f mpegts -pes_payload_size 0 "srt://ingest.nearglass.com:9000?streamid=stk_..."A file, looped
ffmpeg -re -stream_loop -1 -i film.mp4 -c:v libx264 -preset veryfast -tune zerolatency \
-bf 0 -force_key_frames "expr:gte(t,n_forced*1)" -b:v 3M -maxrate 3M -bufsize 1M \
-c:a libopus -b:a 128k -ar 48000 -application lowdelay -frame_duration 20 \
-f mpegts -pes_payload_size 0 "srt://ingest.nearglass.com:9000?streamid=stk_..."A file that is already H.264 with a keyframe every second and no B-frames
can skip the encode with -c:v copy. Check first: a keyframe interval you
did not choose is a join time you did not choose. For a file with no sound,
or when you want no encoder at all, nearglass publish --file
replays an H.264 file straight to the relays.
RTMP
The same encode, as FLV, with AAC (ffmpeg's FLV output cannot carry Opus):
ffmpeg -re -stream_loop -1 -i film.mp4 -c:v libx264 -preset veryfast -tune zerolatency \
-bf 0 -force_key_frames "expr:gte(t,n_forced*1)" -b:v 3M -maxrate 3M -bufsize 1M \
-c:a aac -b:a 128k -f flv "rtmp://ingest.nearglass.com:1935/live/stk_..."For RTMPS, the same with an rtmps:// address (see RTMP).
A camera
The input changes with the system; the encode and the output are the same as above.
# Linux (Video4Linux)
ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 -i /dev/video0 \
-c:v libx264 -preset veryfast -tune zerolatency -bf 0 -pix_fmt yuv420p \
-force_key_frames "expr:gte(t,n_forced*1)" -b:v 2M -maxrate 2M -bufsize 1M \
-an -f mpegts "srt://ingest.nearglass.com:9000?streamid=stk_..."
# Windows (DirectShow): list names with ffmpeg -list_devices true -f dshow -i dummy
ffmpeg -f dshow -framerate 30 -video_size 1280x720 -i video="Your Camera" ...
# macOS (AVFoundation): list with ffmpeg -f avfoundation -list_devices true -i ""
ffmpeg -f avfoundation -framerate 30 -video_size 1280x720 -i "0" ...SRT options
Add them to the address with &: &latency=200000 sets ffmpeg's SRT latency
in microseconds (libsrt's option, in ffmpeg's URL). The session uses the
larger of the two sides' latency, and the ingest's side defaults to 120 ms.
See SRT latency.
When it does not work
| ffmpeg says | Likely cause |
|---|---|
Connection refused or a timeout on SRT | the host or port is wrong, or UDP is blocked |
Server error: ..., or an immediate close | the streamid is not a key of a stream that lists srt |
| Connects, but the player shows nothing | the video is not H.264, or the pixel format is not yuv420p |
| The picture is fine, no sound | AAC-LC and Opus are carried; check -c:a and that the input has an audio track (Audio) |