Agent skill

ffmpeg-streaming

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/ffmpeg-streaming

SKILL.md

CRITICAL GUIDELINES

Windows File Path Requirements

MANDATORY: Always Use Backslashes on Windows for File Paths

When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).


Quick Reference

Protocol Latency Output Format Best For
RTMP 2-5s -f flv rtmp://... Twitch, YouTube ingest
HLS 10-30s -f hls output.m3u8 Web playback, CDN
LL-HLS 2-5s -hls_flags low_latency Low-latency web
SRT <1s -f mpegts srt://... Reliable contribution
DASH 10-30s -f dash output.mpd ABR streaming
Platform Ingest URL
Twitch rtmp://live.twitch.tv/app/{key}
YouTube rtmp://a.rtmp.youtube.com/live2/{key}
Facebook rtmps://live-api-s.facebook.com:443/rtmp/{key}

When to Use This Skill

Use for live streaming workflows:

  • Broadcasting to Twitch, YouTube, Facebook
  • Setting up HLS/DASH servers for VOD
  • Building ABR encoding ladders
  • Low-latency streaming requirements
  • Multi-destination restreaming

FFmpeg Streaming Guide (2025)

Complete guide to live streaming with FFmpeg covering RTMP, HLS, DASH, SRT, and WebRTC protocols.

Current Latest: FFmpeg 8.0.1 (released 2025-11-20) - Check with ffmpeg -version

Streaming Protocols Overview

Protocol Comparison (2025)

Protocol Latency Compatibility Security Use Case
RTMP 1-5s Legacy, ingestion TLS (RTMPS) Stream ingestion
HLS 6-30s Universal AES-128 CDN delivery
DASH 6-30s Wide DRM-ready ABR streaming
LL-HLS 2-4s Apple/modern AES-128 Low-latency
LL-DASH 2-4s Modern browsers DRM-ready Low-latency
SRT <1s Growing AES-128/256 Contribution
WebRTC <0.5s Browsers DTLS/SRTP Real-time
WHIP <1s Emerging TLS WebRTC ingestion

2025 Trends

  • SRT replacing RTMP for contribution/ingest
  • LL-HLS becoming default for Apple ecosystem
  • WHIP standardizing WebRTC ingestion (FFmpeg 8.0+)
  • QUIC/HTTP3 emerging for lower latency delivery

RTMP Streaming

Basic RTMP Stream

bash
# Stream to RTMP server
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

Webcam/Screen to RTMP

bash
# Linux webcam
ffmpeg -f v4l2 -i /dev/video0 \
  -f alsa -i default \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 2500k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

# macOS webcam
ffmpeg -f avfoundation -framerate 30 -i "0:0" \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 2500k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

# Windows screen capture
ffmpeg -f gdigrab -framerate 30 -i desktop \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 3000k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

RTMP with GPU Encoding

bash
# NVIDIA NVENC
ffmpeg -re -i input.mp4 \
  -c:v h264_nvenc -preset p3 -tune ll -zerolatency 1 -b:v 6000k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

# Intel QSV
ffmpeg -re -init_hw_device qsv=hw -filter_hw_device hw \
  -i input.mp4 \
  -c:v h264_qsv -preset fast -b:v 6000k \
  -c:a aac -b:a 128k \
  -f flv rtmp://server/live/stream_key

RTMPS (Encrypted)

bash
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k \
  -c:a aac -b:a 128k \
  -f flv rtmps://secure-server/live/stream_key

Twitch/YouTube/Facebook

bash
# Twitch
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 6000k -maxrate 6000k -bufsize 12000k \
  -g 60 -keyint_min 60 \
  -c:a aac -b:a 160k -ar 44100 \
  -f flv rtmp://live.twitch.tv/app/YOUR_STREAM_KEY

# YouTube
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \
  -g 60 -keyint_min 60 \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY

# Facebook
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 4000k -maxrate 4000k -bufsize 8000k \
  -g 60 \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv rtmps://live-api-s.facebook.com:443/rtmp/YOUR_STREAM_KEY

HLS Streaming

Basic HLS Output

bash
# Create HLS stream
ffmpeg -i input.mp4 \
  -c:v libx264 -c:a aac \
  -hls_time 6 \
  -hls_list_size 0 \
  -hls_segment_filename "segment_%03d.ts" \
  playlist.m3u8

Live HLS Streaming

bash
# Live HLS with rolling window
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k \
  -c:a aac -b:a 128k \
  -hls_time 4 \
  -hls_list_size 10 \
  -hls_flags delete_segments \
  -hls_segment_filename "live_%03d.ts" \
  live.m3u8

Adaptive Bitrate HLS (ABR)

bash
# Multi-bitrate HLS
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]split=3[v1][v2][v3]; \
    [v1]scale=1920:1080[v1out]; \
    [v2]scale=1280:720[v2out]; \
    [v3]scale=854:480[v3out]" \
  -map "[v1out]" -c:v:0 libx264 -b:v:0 5000k -maxrate:v:0 5350k -bufsize:v:0 7500k \
  -map "[v2out]" -c:v:1 libx264 -b:v:1 2800k -maxrate:v:1 2996k -bufsize:v:1 4200k \
  -map "[v3out]" -c:v:2 libx264 -b:v:2 1400k -maxrate:v:2 1498k -bufsize:v:2 2100k \
  -map a:0 -c:a:0 aac -b:a:0 192k \
  -map a:0 -c:a:1 aac -b:a:1 128k \
  -map a:0 -c:a:2 aac -b:a:2 96k \
  -f hls \
  -hls_time 6 \
  -hls_list_size 0 \
  -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
  -master_pl_name master.m3u8 \
  -hls_segment_filename "stream_%v/segment_%03d.ts" \
  stream_%v/playlist.m3u8

HLS with AES Encryption

bash
# Generate encryption key
openssl rand 16 > enc.key
echo "http://example.com/enc.key" > enc.keyinfo
echo "enc.key" >> enc.keyinfo
openssl rand -hex 16 >> enc.keyinfo

# Encrypted HLS
ffmpeg -i input.mp4 \
  -c:v libx264 -c:a aac \
  -hls_time 6 \
  -hls_key_info_file enc.keyinfo \
  -hls_segment_filename "encrypted_%03d.ts" \
  encrypted.m3u8

Low-Latency HLS (LL-HLS)

bash
# LL-HLS with partial segments
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -tune zerolatency \
  -c:a aac \
  -hls_time 4 \
  -hls_list_size 6 \
  -hls_flags independent_segments+delete_segments \
  -hls_segment_type fmp4 \
  -hls_fmp4_init_filename init.mp4 \
  -hls_segment_filename "ll_%03d.m4s" \
  ll_playlist.m3u8

DASH Streaming

Basic DASH Output

bash
ffmpeg -i input.mp4 \
  -c:v libx264 -c:a aac \
  -f dash \
  -seg_duration 4 \
  -use_timeline 1 \
  -use_template 1 \
  output.mpd

Adaptive DASH

bash
ffmpeg -i input.mp4 \
  -map 0:v -map 0:v -map 0:v -map 0:a \
  -c:v libx264 -c:a aac \
  -b:v:0 5M -s:v:0 1920x1080 \
  -b:v:1 3M -s:v:1 1280x720 \
  -b:v:2 1M -s:v:2 640x360 \
  -b:a 128k \
  -f dash \
  -seg_duration 4 \
  -adaptation_sets "id=0,streams=v id=1,streams=a" \
  manifest.mpd

Low-Latency DASH (LL-DASH)

bash
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset ultrafast -tune zerolatency \
  -c:a aac \
  -f dash \
  -seg_duration 1 \
  -frag_duration 0.1 \
  -streaming 1 \
  -ldash 1 \
  -use_timeline 0 \
  -use_template 1 \
  -remove_at_exit 1 \
  -window_size 5 \
  ll_manifest.mpd

SRT Streaming (FFmpeg 4.0+)

SRT Listener (Server Mode)

bash
# FFmpeg as SRT server
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k \
  -c:a aac -b:a 128k \
  -f mpegts "srt://0.0.0.0:9000?mode=listener"

SRT Caller (Client Mode)

bash
# Send to SRT server
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 3000k \
  -c:a aac -b:a 128k \
  -f mpegts "srt://server:9000?mode=caller"

SRT with Encryption

bash
# AES-128 encrypted SRT
ffmpeg -re -i input.mp4 \
  -c:v libx264 -c:a aac \
  -f mpegts "srt://server:9000?passphrase=mySecretKey123&pbkeylen=16"

Receive SRT Stream

bash
# Receive and save
ffmpeg -i "srt://0.0.0.0:9000?mode=listener" \
  -c copy output.mp4

# Receive and transcode
ffmpeg -i "srt://server:9000?mode=caller" \
  -c:v libx264 -c:a aac \
  output.mp4

WebRTC/WHIP (FFmpeg 8.0+)

Overview

FFmpeg 8.0 introduces the WHIP (WebRTC-HTTP Ingestion Protocol) muxer, enabling sub-second latency streaming to WebRTC endpoints. WHIP is becoming the standard for WebRTC ingestion, replacing proprietary solutions.

WHIP Output

bash
# Stream to WHIP endpoint
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset ultrafast -tune zerolatency \
  -c:a libopus \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

# Low-latency webcam to WHIP (Linux)
ffmpeg -f v4l2 -i /dev/video0 \
  -f pulse -i default \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 2500k \
  -c:a libopus -b:a 64k \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

# Low-latency webcam to WHIP (macOS)
ffmpeg -f avfoundation -framerate 30 -i "0:0" \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 2500k \
  -c:a libopus -b:a 64k \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

# Low-latency screen capture to WHIP (Windows)
ffmpeg -f gdigrab -framerate 30 -i desktop \
  -c:v libx264 -preset ultrafast -tune zerolatency -b:v 3000k \
  -c:a libopus -b:a 64k \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

WHIP with Hardware Encoding

bash
# NVIDIA NVENC WHIP streaming
ffmpeg -hwaccel cuda -hwaccel_output_format cuda \
  -i input.mp4 \
  -c:v h264_nvenc -preset p3 -tune ll -zerolatency 1 -b:v 3000k \
  -c:a libopus -b:a 64k \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

# Intel QSV WHIP streaming
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw \
  -i input.mp4 \
  -c:v h264_qsv -preset fast -b:v 3000k \
  -c:a libopus -b:a 64k \
  -f whip \
  "https://whip-server.example.com/publish/stream_id"

WHIP Authentication

bash
# With bearer token authentication
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset ultrafast -tune zerolatency \
  -c:a libopus \
  -f whip \
  -headers "Authorization: Bearer YOUR_TOKEN" \
  "https://whip-server.example.com/publish/stream_id"

WHIP Servers/Platforms

  • Cloudflare Stream - WebRTC ingest via WHIP
  • Dolby.io - Interactive streaming
  • Janus - Open-source WebRTC gateway
  • mediasoup - Open-source SFU with WHIP support
  • LiveKit - WebRTC platform with WHIP ingestion

Multicast Streaming

UDP Multicast

bash
# Send multicast
ffmpeg -re -i input.mp4 \
  -c:v libx264 -c:a aac \
  -f mpegts "udp://239.0.0.1:1234?pkt_size=1316"

# Receive multicast
ffmpeg -i "udp://239.0.0.1:1234" -c copy output.mp4

Re-streaming (Protocol Conversion)

RTMP to HLS

bash
# Receive RTMP, output HLS
ffmpeg -i rtmp://source/live/stream \
  -c:v libx264 -preset veryfast \
  -c:a aac \
  -hls_time 4 \
  -hls_list_size 10 \
  -hls_flags delete_segments \
  /var/www/html/hls/stream.m3u8

SRT to RTMP

bash
ffmpeg -i "srt://0.0.0.0:9000?mode=listener" \
  -c copy \
  -f flv rtmp://destination/live/stream

RTMP to Multiple Destinations

bash
ffmpeg -i rtmp://source/live/stream \
  -c copy -f flv rtmp://youtube/live/key1 \
  -c copy -f flv rtmp://twitch/app/key2 \
  -c copy -f flv rtmp://facebook/rtmp/key3

Production Patterns

nginx-rtmp Integration

nginx
# nginx.conf
rtmp {
    server {
        listen 1935;
        application live {
            live on;
            exec_push ffmpeg -i rtmp://localhost/live/$name
                -c:v libx264 -preset veryfast -b:v 3000k
                -c:a aac -b:a 128k
                -hls_time 4
                -hls_list_size 10
                -hls_flags delete_segments
                /var/www/html/hls/$name.m3u8;
        }
    }
}

Docker Streaming Setup

yaml
# docker-compose.yml
version: '3.8'

services:
  rtmp:
    image: tiangolo/nginx-rtmp
    ports:
      - "1935:1935"
      - "8080:8080"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf

  transcoder:
    image: jrottenberg/ffmpeg:7.1-ubuntu2404
    depends_on:
      - rtmp
    command: >
      -i rtmp://rtmp:1935/live/stream
      -c:v libx264 -preset veryfast
      -c:a aac
      -hls_time 4
      -f hls /output/stream.m3u8
    volumes:
      - ./output:/output

Monitoring & Logging

bash
# Enable detailed logging
ffmpeg -report -i input.mp4 -f flv rtmp://server/live/stream

# Real-time stats
ffmpeg -re -i input.mp4 \
  -progress pipe:1 \
  -c:v libx264 -c:a aac \
  -f flv rtmp://server/live/stream

# Write stats to file
ffmpeg -re -i input.mp4 \
  -progress stats.txt \
  -c:v libx264 -c:a aac \
  -f flv rtmp://server/live/stream

Troubleshooting

Common Issues

"Connection refused"

bash
# Check server is reachable
nc -zv server 1935

# Test with simple stream
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
  -f flv rtmp://server/live/test

Buffer underrun/overrun

bash
# Increase buffer size
ffmpeg -re -i input.mp4 \
  -b:v 3000k -maxrate 3000k -bufsize 6000k \
  -f flv rtmp://server/live/stream

High latency

bash
# Reduce latency settings
ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset ultrafast -tune zerolatency \
  -g 30 -keyint_min 30 \
  -f flv rtmp://server/live/stream

Packet drops

bash
# Increase receive buffer (SRT)
ffmpeg -i "srt://server:9000?rcvbuf=8192000" -c copy output.mp4

# Increase buffer for UDP
ffmpeg -buffer_size 8192000 -i udp://239.0.0.1:1234 -c copy output.mp4

Best Practices

  1. Use appropriate keyframe interval - 2 seconds for live streaming
  2. Match bitrate to bandwidth - Leave 20% headroom
  3. Use CBR for streaming - Consistent bandwidth
  4. Enable faststart for VOD - -movflags +faststart
  5. Monitor stream health - Check for drops/errors
  6. Use hardware encoding - NVENC/QSV for GPU offload
  7. Implement ABR - Multiple quality levels
  8. Secure your streams - Use RTMPS/encryption
  9. Test failover - Backup ingest points
  10. Log everything - Use -report for debugging

This guide covers FFmpeg streaming fundamentals. For hardware acceleration, see the hardware acceleration skill.

Didn't find tool you were looking for?

Be as detailed as possible for better results