Tutorial · FFmpeg for live video

FFmpeg streaming tutorial from one command to a live channel

This FFmpeg streaming tutorial gets you live with a single command: FFmpeg reads your file, camera or screen, encodes it to H.264 video and AAC audio, and pushes it over RTMP to your Primcast channel.

You will find the command for each kind of source, the encoder settings that keep playback smooth for your viewers, and an SRT version for long or shaky connections.

ffmpeg · rtmp
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast \
  -b:v 2500k -maxrate 2500k -bufsize 5000k \
  -pix_fmt yuv420p \
  -force_key_frames "expr:gte(t,n_forced*2)" \
  -sc_threshold 0 \
  -c:a aac -b:a 128k -ar 44100 -ac 2 \
  -f flv "rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream"

Swap the highlighted words for your own values. Step 02 explains each flag.

01

Before you start: FFmpeg and four values from your panel

You need FFmpeg on the computer that sends the video, and the encoder settings of your channel. Both take a couple of minutes.

Install FFmpeg

Use your system's package manager, then check that it runs. Any current release works with the commands on this page.

install
# Windows
winget install Gyan.FFmpeg
# macOS (Homebrew)
brew install ffmpeg
# Debian or Ubuntu
sudo apt install ffmpeg
# check it
ffmpeg -version

Copy your encoder settings

Sign in, open your video account and find the Live streaming card. Its Encoder settings list everything FFmpeg needs:

Server
Looks like rtmp://HOST:1935/APP. Your host and application name.
Stream name
Usually livestream. It goes at the end of the address.
Username
Your publishing login.
Password
Click Show to see it, or New password to replace it.

If your panel also shows a Nearest server address, use that one as the server. Your encoder then connects to our closest location (New York, Miami, San Francisco, Amsterdam or Bucharest) and the stream travels on to your channel over our network. The stream name, username and password stay the same.

02

Your first FFmpeg RTMP stream, flag by flag

Put your username and password in front of the host, followed by an @, and add the stream name after the application. The rest of the command tells FFmpeg how to encode.

rtmp address
rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream

Keep the quotes around the address. If your password contains @, : or /, write them as %40, %3A and %2F, or click New password in the panel for one without them.

What each FFmpeg flag in the command does
FlagWhat it does
-reReads a file at its real playing speed. Without it, FFmpeg sends a file as fast as it can and the stream breaks up. Leave it out for cameras and capture devices, which already run in real time.
-i input.mp4Your input: a file, a device or another stream. Step 03 has one for each.
-c:v libx264Encodes video as H.264, which every player and browser can show.
-preset veryfastTrades a little quality for speed so the computer keeps up in real time. Try faster or medium if you have CPU to spare.
-b:v 2500k -maxrate 2500k -bufsize 5000kHolds the video near a steady 2,500 kbps, so the stream never asks for more upload than you have. Step 04 has values for each resolution.
-pix_fmt yuv420pThe colour format phones, TVs and browsers expect.
-force_key_frames "expr:gte(t,n_forced*2)"A keyframe every 2 seconds, whatever the frame rate. Playback is cut into segments on keyframes, so this one matters most.
-sc_threshold 0Stops extra keyframes on scene changes, so the 2-second rhythm stays fixed.
-c:a aac -b:a 128k -ar 44100 -ac 2AAC stereo audio at 128 kbps and 44.1 kHz. FFmpeg's built-in AAC encoder needs no extra flag.
-f flvWraps the stream in FLV, the format RTMP carries.

Older guides, including the first version of this page, add -strict experimental for AAC. FFmpeg dropped the experimental label from its AAC encoder in version 3.0, so you can leave it out.

03

Pick your source: file, webcam, screen or IP camera

Only the input part changes. In every example, [encoding] stands for the video and audio flags from step 02, and RTMP_ADDRESS for your quoted address.

Stream a video file with FFmpeg

Add -stream_loop -1 before the input to play it on repeat until you stop FFmpeg.

file
ffmpeg -re -stream_loop -1 -i video.mp4 \
  [encoding] -f flv "RTMP_ADDRESS"

Webcam on Windows

List your devices first, then use the exact names it prints.

windows · dshow
ffmpeg -list_devices true -f dshow -i dummy

ffmpeg -f dshow -rtbufsize 256M ^
  -i video="Your Camera":audio="Your Microphone" ^
  [encoding] -f flv "RTMP_ADDRESS"

Webcam on macOS

The list shows each camera and microphone with a number. "0:0" means camera 0 and microphone 0.

macos · avfoundation
ffmpeg -f avfoundation -list_devices true -i ""

ffmpeg -f avfoundation -framerate 30 \
  -video_size 1280x720 -i "0:0" \
  [encoding] -f flv "RTMP_ADDRESS"

Webcam on Linux

Video from the camera device, sound from your desktop's default input.

linux · v4l2
ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 \
  -i /dev/video0 -f pulse -i default \
  [encoding] -f flv "RTMP_ADDRESS"

Your screen on Windows

Captures the whole desktop at 30 frames per second. Add a microphone with a second dshow input if you want sound.

windows · gdigrab
ffmpeg -f gdigrab -framerate 30 -i desktop ^
  [encoding] -f flv "RTMP_ADDRESS"

IP camera over RTSP

If the camera already sends H.264 with a 2-second keyframe interval (set in its own menu), copy the video as it is and only encode the sound. Otherwise use the full encoding flags.

rtsp camera
ffmpeg -rtsp_transport tcp \
  -i "rtsp://CAM_USER:CAM_PASS@192.168.1.64:554/stream1" \
  -c:v copy -c:a aac -b:a 128k \
  -f flv "RTMP_ADDRESS"

No microphone on the camera? Replace the audio flags with -an.

The examples end lines with \ (macOS and Linux) or ^ (Windows Command Prompt). In PowerShell, or if in doubt, put the whole command on one line.

04

FFmpeg encoder settings that hold up live

Pick a row that fits your upload speed. Leave a third of your upload free: if a speed test shows 6 Mbps, send no more than about 4.

Suggested FFmpeg video and audio bitrates by resolution
PictureAdd to the commandVideoAudioUpload you need
1080p, 30 fps-vf scale=-2:1080 -r 304500k128k7 Mbps
720p, 30 fps-vf scale=-2:720 -r 302500k128k4 Mbps
480p, 30 fps-vf scale=-2:480 -r 301200k96k2 Mbps

Set -b:v and -maxrate to the video figure and -bufsize to twice that. The command in step 02 is the 720p row. The paid live video plans take up to 5 Mbps in, enough for the 1080p row.

Three rules that prevent most buffering

  1. Keep keyframes at a fixed 2 seconds. A long or drifting interval shows up as stalling for your viewers, and from your side it looks like a server fault.
  2. Keep the bitrate steady with -maxrate and -bufsize, so a busy scene cannot spike past your upload.
  3. Watch the speed= figure in FFmpeg's status line. It should sit at 1x. Below that, your computer cannot encode in real time.

Let your GPU do the encoding

If speed= drops under 1x, swap -c:v libx264 -preset veryfast for the hardware encoder your computer has. The CPU is then free for everything else.

NVIDIA GPU
-c:v h264_nvenc -preset p4
Intel graphics
-c:v h264_qsv
Mac
-c:v h264_videotoolbox

Run ffmpeg -encoders to see which ones your build includes.

05

Send an FFmpeg SRT stream instead

SRT keeps a stream steady over long or lossy links, such as a venue Wi-Fi, a mobile uplink or a feed from another continent, where RTMP tends to stall. It comes with the Pro and Platinum plans of our video CDN.

Your Live streaming card then has an SRT ingest section with your own port and passphrase. Copy its One-line URL and use it as the output, with MPEG-TS in place of FLV. The encoding flags stay the same.

An SRT stream plays under its own name, so use the playback link shown next to it, under Plays at.

ffmpeg · srt
ffmpeg -re -i input.mp4 \
  [encoding] \
  -f mpegts \
  "srt://HOST:PORT?passphrase=PASSPHRASE&pbkeylen=16"

Your FFmpeg build needs SRT support. Check with ffmpeg -protocols and look for srt in the output list.

06

Check you are live, and fix what is not

  1. Start FFmpeg and leave the window open. A status line that keeps counting frame= and time= means it is sending.
  2. Open the Live streaming card. Within 15 seconds it should say live and show what your encoder is sending, close to your bitrate.
  3. Copy the playback link from the same panel and open it in VLC (Media, Open Network Stream) or run ffplay "PLAYBACK_LINK". The panel also gives you an embed code for your own website.
Common FFmpeg streaming problems and their fixes
What you seeWhat to do
FFmpeg stops at once with a connection or I/O errorCheck the host and application name letter by letter. Some office and hotel networks block port 1935: try another connection.
It connects, then the server refuses the streamUsername or password is wrong, or the password has a character that needs encoding. Click New password, update the command and try again.
speed= stays well above 1x on a fileYou left out -re. Add it before -i.
speed= stays below 1xUse a faster preset (superfast), a lower row from step 04, or your GPU's encoder.
FFmpeg looks fine but viewers bufferCheck the keyframe flags, then lower the bitrate. Your upload may be slower than you think at that hour.
The stream ends when the file endsAdd -stream_loop -1 before -i.
07

FFmpeg streaming questions

How do I stream to an RTMP server with FFmpeg?

Encode to H.264 and AAC, wrap the output in FLV with -f flv, and give FFmpeg the RTMP address as the last argument. For a Primcast channel the address is your server, application and stream name, with your username and password in front of the host: rtmp://USERNAME:PASSWORD@HOST:1935/APP/livestream.

Where do I find my server address, username and password?

In your account, on the Live streaming card of your video account, under Encoder settings. The password stays hidden until you click Show, and New password gives you a fresh one. The stream that is live keeps running, and the new password applies to the next connection.

Do I still need -strict experimental for AAC audio?

No. FFmpeg's own AAC encoder lost its experimental label in FFmpeg 3.0, released in 2016. Plain -c:a aac works on every current build, so you can drop the flag from older commands.

What keyframe interval should FFmpeg use for live streaming?

A fixed 2 seconds. We cut playback segments on keyframes, so a longer or drifting interval turns into stalls for your viewers. Use -force_key_frames "expr:gte(t,n_forced*2)" with -sc_threshold 0, or -g set to twice your frame rate.

What bitrate should I stream at?

About 2,500 kbps for 720p and 4,500 kbps for 1080p at 30 frames per second, plus 128 kbps of audio. Keep the total to two thirds of your measured upload speed so a slow moment on your line does not stop the stream.

How do I loop a video file around the clock with FFmpeg?

Put -re -stream_loop -1 before -i and FFmpeg replays the file until you stop it. That keeps a computer busy all day, though. The paid video CDN plans include 24/7 TV station channels that play your videos from our side instead.

Can FFmpeg encode the stream on my GPU?

Yes. Use h264_nvenc on an NVIDIA GPU, h264_qsv on Intel graphics or h264_videotoolbox on a Mac, in place of libx264. The keyframe and bitrate flags stay the same.

Can I send SRT instead of RTMP?

Yes, on the Pro and Platinum video CDN plans. Your panel gives you an SRT port and passphrase. Use -f mpegts and the one-line srt:// URL from the panel as the output.

08

Prefer a window to a command line?

The same channel works with any encoder that speaks RTMP. These tutorials take the same four values.

Need a channel to stream to?

Open a video channel, paste your values into the command and judge the picture yourself. Stuck on a flag? Our chat replies in seconds and can look at your channel while you wait, and a person takes over whenever you ask.