What You’ll Learn
- The basic RTMP push syntax in FFmpeg
- Streaming to YouTube Live and Twitch
- Encoding settings (bitrate, resolution, audio)
- Looping a video file for broadcast-style streaming
- Low-latency streaming configuration
- Common errors and fixes
Tested with: FFmpeg 7.0
Platform: Windows / macOS / Linux
What is RTMP?
RTMP (Real-Time Messaging Protocol) is a video streaming protocol originally developed by Adobe. YouTube Live, Twitch, Facebook Live, and virtually every major streaming platform accept RTMP input. FFmpeg acts as an RTMP client, encoding and pushing audio/video to the RTMP server.
Basic Syntax
ffmpeg [input] [encode options] -f flv rtmp://server-url/stream-key
Use -f flv as the output format — RTMP uses FLV as its container.
Streaming to YouTube Live
Find Your Stream Key
YouTube Studio → Go Live → Stream → Copy the stream key (e.g. xxxx-xxxx-xxxx-xxxx-xxxx)
Webcam + Microphone (Linux/macOS)
ffmpeg \
-f v4l2 -i /dev/video0 \
-f pulse -i default \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3500k -bufsize 6000k \
-pix_fmt yuv420p -g 60 -keyint_min 60 \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
Webcam + Microphone (Windows, DirectShow)
ffmpeg \
-f dshow -i video="Webcam Name":audio="Microphone Name" \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3500k -bufsize 6000k \
-pix_fmt yuv420p -g 60 -keyint_min 60 \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
Key Parameters
| Option | Description |
|---|---|
-preset veryfast | Encoding speed (use veryfast/ultrafast for real-time) |
-b:v 3000k | Video bitrate |
-maxrate 3500k | Maximum bitrate |
-bufsize 6000k | Buffer size (2× maxrate is a good rule of thumb) |
-g 60 | Keyframe interval (same as FPS = 1 keyframe per second) |
-pix_fmt yuv420p | YouTube-required pixel format |
YouTube Recommended Bitrates
| Resolution | FPS | Video Bitrate | Audio Bitrate |
|---|---|---|---|
| 720p | 30 | 2,500–4,000 kbps | 128 kbps |
| 1080p | 30 | 4,500–6,000 kbps | 192 kbps |
| 1080p | 60 | 7,500–9,000 kbps | 192 kbps |
| 4K | 30 | 15,000–30,000 kbps | 256 kbps |
Streaming to Twitch
Find Your Stream Key
Twitch Dashboard → Settings → Stream → Primary Stream key
ffmpeg \
-f v4l2 -i /dev/video0 \
-f pulse -i default \
-c:v libx264 -preset veryfast -b:v 4500k -maxrate 5000k -bufsize 9000k \
-pix_fmt yuv420p -g 60 -keyint_min 60 \
-c:a aac -b:a 160k -ar 44100 \
-f flv rtmp://live.twitch.tv/app/YOUR_STREAM_KEY
Twitch enforces a 6,000 kbps video bitrate cap. Do not exceed it.
Loop a Video File (Broadcast-Style)
Replay a pre-recorded file on loop:
ffmpeg \
-re -stream_loop -1 -i input.mp4 \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3500k -bufsize 6000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
| Option | Description |
|---|---|
-re | Read input at native framerate (required for real-time streaming) |
-stream_loop -1 | Loop forever (-1 = infinite, 0 = no loop) |
Simultaneous Multi-Platform Streaming
Use the tee muxer to push to multiple destinations with a single encode pass:
ffmpeg \
-f v4l2 -i /dev/video0 \
-f pulse -i default \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3500k -bufsize 6000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f tee -map 0:v -map 1:a \
"[f=flv]rtmp://a.rtmp.youtube.com/live2/YT_KEY|[f=flv]rtmp://live.twitch.tv/app/TWITCH_KEY"
Desktop Capture Streaming
Linux (X11)
ffmpeg \
-f x11grab -s 1920x1080 -r 30 -i :0.0+0,0 \
-f pulse -i default \
-c:v libx264 -preset veryfast -b:v 4000k -maxrate 4500k -bufsize 8000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
macOS (AVFoundation)
ffmpeg \
-f avfoundation -capture_cursor 1 -i "1:0" \
-c:v libx264 -preset veryfast -b:v 4000k -maxrate 4500k -bufsize 8000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
Low-Latency Settings
ffmpeg \
-f v4l2 -i /dev/video0 \
-f pulse -i default \
-c:v libx264 -preset ultrafast -tune zerolatency \
-b:v 2000k -maxrate 2000k -bufsize 2000k \
-pix_fmt yuv420p -g 30 -keyint_min 30 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
-tune zerolatency combined with -preset ultrafast minimizes encoding delay at the cost of some compression efficiency.
GPU Encoding (Reduce CPU Load)
NVIDIA (NVENC)
ffmpeg \
-f v4l2 -i /dev/video0 \
-f pulse -i default \
-c:v h264_nvenc -preset p4 -b:v 4000k -maxrate 4500k -bufsize 8000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
Apple VideoToolbox (macOS)
ffmpeg \
-f avfoundation -i "1:0" \
-c:v h264_videotoolbox -b:v 4000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k \
-f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
Troubleshooting
Connection refused / Server error
- Your stream key is wrong — re-copy it from the dashboard
- YouTube Live requires you to schedule or enable a stream before pushing
Video drops / choppy stream
Reduce bitrate or switch to a faster preset:
-preset ultrafast -b:v 2000k
Audio/video out of sync
-async 1
avformat_write_header: Connection timed out
Verify the RTMP URL. YouTube’s RTMP endpoint is rtmp://a.rtmp.youtube.com/live2/.
Frequently Asked Questions
What bitrate should I push to YouTube Live?
4500–6000 kbps for 1080p 30 fps; 9000 kbps for 1080p 60 fps. Audio at 128–192 kbps. YouTube’s Live Encoder Settings page lists current targets.
Why does my stream buffer at the viewer end?
Either upload bandwidth is insufficient (check with iperf3) or the keyframe interval is too long. Set keyframes every 2 s with -g 60 -keyint_min 60 at 30 fps.
RTMP vs RTMPS vs SRT — which should I use?
RTMPS (TLS-wrapped RTMP) is the modern default for YouTube and Twitch. SRT is better for unreliable networks but requires the receiver to support it.
How do I monitor stream health?
Watch the bitrate= and dup= fields in FFmpeg’s status line. Sustained dup > 0 means the encoder is dropping frames to keep up.
Can I stream the same input to two services?
Yes — use tee muxer: -map 0 -f tee "[f=flv]rtmp://a|[f=flv]rtmp://b". Both endpoints receive identical bytes.
Related Articles
- HLS Segmenting
- YouTube Encoding Settings
- Two-Pass Encoding
Tested with ffmpeg 7.0 / Ubuntu 24.04
Primary source: ffmpeg.org/ffmpeg-protocols.html#rtmp