Nearglass
Publish

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

OptionWhy
-c:v libx264 -preset veryfast -tune zerolatencyH.264, with look-ahead and B-frames off
-bf 0no 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 1Mclose 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 128kAAC-LC: carried, and turned into Opus at the ingest. Use it for RTMP
-refor 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 saysLikely cause
Connection refused or a timeout on SRTthe host or port is wrong, or UDP is blocked
Server error: ..., or an immediate closethe streamid is not a key of a stream that lists srt
Connects, but the player shows nothingthe video is not H.264, or the pixel format is not yuv420p
The picture is fine, no soundAAC-LC and Opus are carried; check -c:a and that the input has an audio track (Audio)

On this page