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 -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.
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.
# 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.
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://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.
| Flag | What it does |
|---|---|
-re | Reads 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.mp4 | Your input: a file, a device or another stream. Step 03 has one for each. |
-c:v libx264 | Encodes video as H.264, which every player and browser can show. |
-preset veryfast | Trades 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 5000k | Holds 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 yuv420p | The 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 0 | Stops extra keyframes on scene changes, so the 2-second rhythm stays fixed. |
-c:a aac -b:a 128k -ar 44100 -ac 2 | AAC stereo audio at 128 kbps and 44.1 kHz. FFmpeg's built-in AAC encoder needs no extra flag. |
-f flv | Wraps 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.
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.
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.
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.
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.
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.
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.
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.
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.
| Picture | Add to the command | Video | Audio | Upload you need |
|---|---|---|---|---|
| 1080p, 30 fps | -vf scale=-2:1080 -r 30 | 4500k | 128k | 7 Mbps |
| 720p, 30 fps | -vf scale=-2:720 -r 30 | 2500k | 128k | 4 Mbps |
| 480p, 30 fps | -vf scale=-2:480 -r 30 | 1200k | 96k | 2 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
- 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.
- Keep the bitrate steady with
-maxrateand-bufsize, so a busy scene cannot spike past your upload. - 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.
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 -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.
Check you are live, and fix what is not
- Start FFmpeg and leave the window open. A status line that keeps counting
frame=andtime=means it is sending. - Open the Live streaming card. Within 15 seconds it should say live and show what your encoder is sending, close to your bitrate.
- 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.
| What you see | What to do |
|---|---|
| FFmpeg stops at once with a connection or I/O error | Check 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 stream | Username 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 file | You left out -re. Add it before -i. |
speed= stays below 1x | Use a faster preset (superfast), a lower row from step 04, or your GPU's encoder. |
| FFmpeg looks fine but viewers buffer | Check the keyframe flags, then lower the bitrate. Your upload may be slower than you think at that hour. |
| The stream ends when the file ends | Add -stream_loop -1 before -i. |
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.
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.