如何通过FFmpeg以30fps推流至Facebook RTMP服务器?
我来帮你分析下这个问题——你用h264_nvenc编码本地录制能稳30fps,但推流Facebook就掉帧到12-18,核心问题大概率不是编码能力,而是推流环节的参数配置或网络适配,咱们一步步来优化:
先看看你当前用的两个命令:
推流命令
-re -rtbufsize 256M -f dshow -i audio="Mikrofon (Realtek Audio)" -rtbufsize 256M -f dshow -i audio="virtual-audio-capturer" -rtbufsize 1024M -f dshow -i video=screen-capture-recorder -r 30 -filter:v scale=1280:720 -c:v h264_nvenc -pix_fmt yuv420p -preset fast -b:v 8M -maxrate:v 10M -c:a aac -b:a 128k -ar 44100 -f flv rtmp://live-api.facebook.com:80/rtmp/..............
本地录制命令
-re -rtbufsize 256M -f dshow -i audio="Mikrofon (Realtek Audio)" -rtbufsize 256M -f dshow -i audio="virtual-audio-capturer" -rtbufsize 1024M -f dshow -i video=screen-capture-recorder -r 30 -filter:v scale=1280:720 -c:v h264_nvenc -pix_fmt yuv420p -preset fast -b:v 8M -maxrate:v 10M -c:a aac -b:a 128k -ar 44100 D:\test.mp4 -y
本地录制时FFmpeg可以把编码好的数据写入本地磁盘,缓冲空间充足,即使短时间编码或捕获有波动也能平滑输出;但RTMP推流是实时传输,一旦网络传输跟不上、协议缓冲配置不合理,或者输入捕获的帧率没有强制锁定,FFmpeg就会丢帧来维持码率,导致帧率下降。
具体优化方案
1. 强制锁定视频捕获帧率
你当前用-r 30是设置输出帧率,但screen-capture-recorder的捕获帧率可能没被强制指定,导致实际捕获的帧率不稳定。把视频输入的参数改成:
-f dshow -framerate 30 -i video=screen-capture-recorder
这样让dshow直接以30fps捕获桌面,从源头保证输入帧率稳定,避免FFmpeg后期调整时丢帧。
2. 合并双音频流,减少处理开销
你同时捕获了两个音频输入,但当前命令没有明确合并它们,FFmpeg可能默认只处理其中一个,或者在音频同步上额外消耗资源。添加音频合并滤镜,优化音频处理:
-filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map "[a]" -map 2:v
把这个参数插入到滤镜链中,完整的优化后推流命令如下:
-re -rtbufsize 256M -f dshow -i audio="Mikrofon (Realtek Audio)" -rtbufsize 256M -f dshow -i audio="virtual-audio-capturer" -rtbufsize 1024M -f dshow -framerate 30 -i video=screen-capture-recorder -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -filter:v scale=1280:720 -map "[a]" -map 2:v -r 30 -c:v h264_nvenc -pix_fmt yuv420p -preset fast -b:v 8M -maxrate:v 10M -bufsize:v 16M -c:a aac -b:a 128k -ar 44100 -flush_packets 1 -f flv rtmp://live-api.facebook.com:80/rtmp/..............
3. 优化RTMP推流的码率与缓冲配置
推流时要让码率控制更适合实时传输:
- 添加
-bufsize:v 16M:设置视频缓冲大小为目标码率的2倍,帮助FFmpeg平滑码率波动,避免网络拥堵时丢帧 - 添加
-flush_packets 1:强制FFmpeg立即发送数据包,减少RTMP缓冲延迟,避免因缓冲堆积导致帧率被限制 - 可选添加
-rc cbr:给h264_nvenc设置恒定码率模式,比默认的VBR更适合RTMP推流,避免码率突增超出网络带宽
4. 排查网络带宽瓶颈
如果上面的参数调整后还是掉帧,要确认你的上传带宽是否能稳定支持8M码率(注意:网络带宽的单位通常是Mbps,8Mbps等于1MB/s的上传速度)。可以用以下命令测试推流的网络兼容性:
ffmpeg -f lavfi -i testsrc=size=1280x720:rate=30 -c:v h264_nvenc -b:v 8M -f flv rtmp://live-api.facebook.com:80/rtmp/..............
如果这个测试命令能稳定30fps,说明你的网络没问题,问题出在桌面捕获环节;如果还是掉帧,那就是网络带宽不足,需要降低-b:v到6M左右试试。
5. 升级FFmpeg版本(可选)
你的FFmpeg是3.3.3版本,比较老了,后续版本对nvenc和RTMP推流的兼容性有不少优化,比如更好的码率控制算法、更低的CPU开销,升级到最新稳定版可能会解决一些隐性的兼容性问题。
内容的提问来源于stack exchange,提问作者user6326558




