FFmpeg 直播推流怎么配?RTMP 推流和 HLS/DASH 流媒体生成实战
FFmpeg 是直播推流的核心工具——OBS 底层也是调用 FFmpeg 做编码和推流。直接用 FFmpeg 推流更轻量、更灵活,适合服务器端自动化场景。
RTMP 推流:最常用的直播协议
RTMP 是直播平台(B站、斗鱼、YouTube)的标准推流协议。核心命令:
bashffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key
关键参数:
-re:按原始帧率读取输入,不加这个 FFmpeg 会以最快速度把文件读完然后全推出去,直播就变成了快进-preset veryfast:实时编码必须用快 preset,slow 的话编码速度跟不上帧率,画面会卡顿-b:v 2500k:固定码率 2.5Mbps,直播平台通常有码率上限(B站 6000k,YouTube 5100k)-f flv:RTMP 推流必须用 FLV 容器格式
摄像头实时推流
bash# macOS 摄像头 + 麦克风推流 ffmpeg -f avfoundation -i "0:0" -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key # Linux 摄像头推流 ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://server/live/stream_key
摄像头推流比推文件更需要注意编码速度——如果 CPU 不够快,需要降低分辨率或码率:-vf "scale=1280:720" 降到 720p。
HLS:苹果系的流媒体方案
HLS 把视频切成小片段(.ts),通过 .m3u8 播放列表索引。延迟较高(通常 10-30 秒),但兼容性最好——所有浏览器和 iOS 设备都支持。
bashffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f hls -hls_time 6 -hls_list_size 0 -hls_segment_filename "seg_%03d.ts" stream.m3u8
关键参数:
-hls_time 6:每个切片 6 秒,越短延迟越低但碎片越多-hls_list_size 0:播放列表包含所有切片(0 = 不限制),直播场景可以设成 5-10 只保留最近几个-hls_segment_filename:切片文件命名模板
HLS 文件是纯静态文件,用 Nginx 或任何 HTTP 服务器托管就行,不需要专门的流媒体服务器。
DASH:开源的流媒体方案
DASH 和 HLS 类似,但基于 MPEG 标准,没有苹果的专利限制。浏览器支持不如 HLS(Safari 不原生支持 DASH),但功能更灵活。
bashffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f dash -seg_duration 6 -out output.mpd
实际上 DASH 在国内使用较少,大部分场景用 HLS 或 RTMP 就够了。
多码率自适应推流
给不同网速的用户提供不同清晰度——3G 用户看 480p,WiFi 用户看 1080p。用 -var_stream_map 生成多码率 HLS:
bashffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v:0 5000k -s:v:0 1920x1080 -b:v:1 2500k -s:v:1 1280x720 -b:v:2 1000k -s:v:2 854x480 -c:a aac -b:a 128k -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" -f hls -hls_time 6 -master_pl_name master.m3u8 "stream_%v.m3u8"
播放器会根据带宽自动切换码率,用户看到的效果就是网速慢时自动降清晰度。
常见问题
推流中断:网络波动导致 RTMP 连接断开。加 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 让 FFmpeg 自动重连,但不是所有版本都支持。
延迟太高:HLS 延迟 10-30 秒是正常的。要低延迟用 RTMP 直推或 WebRTC(FFmpeg 不直接支持 WebRTC,需要 mediamtx 等中间件)。
音视频不同步:通常是编码速度跟不上导致帧被丢弃。降低分辨率/码率,或者用更快的 preset。