3. FFmpeg 推流核心参数:输入源选择、编码器、码率控制、GOP 与帧率

推流这件事,说白了就是把原始视频数据压缩打包,再通过 RTSP 协议扔给服务器。但怎么扔、扔多快、扔成什么样,全看参数怎么配。我见过不少新手,拿着 FFmpeg 默认参数直接推流,结果画面卡成幻灯片,或者延迟高得离谱。嗯,今天咱们就把这几个核心参数掰开揉碎讲清楚。

本章核心脉络:输入源 → 编码器 → 码率控制 → GOP → 帧率,每一步都直接影响推流质量与延迟。

FFmpeg 推流核心参数决策流程 FFmpeg 推流核心参数决策流程 输入源选择 摄像头 / 采集卡 本地文件 / 流 桌面 / 窗口 编码器选择:H.264 / H.265 码率控制:CBR / VBR / CRF GOP 大小 + 帧率控制 RTSP 推流输出 每个环节的参数选择都直接影响最终推流的延迟、画质与稳定性

3.1 输入源选择:摄像头、文件还是桌面?

不同的输入源,FFmpeg 的打开方式完全不同。我个人习惯先把输入源分三类:实时设备(摄像头/采集卡)、本地文件(MP4/TS 等)、桌面录制(Windows/macOS/Linux)。

3.1.1 摄像头与采集卡

在 Linux 上,摄像头通常映射为 /dev/video0。Windows 用 dshow 设备,macOS 用 avfoundation。举个例子:

# Linux 摄像头推流
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -f rtsp rtsp://server/live/stream

# Windows USB 摄像头
ffmpeg -f dshow -i video="USB Camera" -c:v libx264 -f rtsp rtsp://server/live/stream

# macOS 内置摄像头
ffmpeg -f avfoundation -i "0" -c:v libx264 -f rtsp rtsp://server/live/stream

小技巧:用 -list_devices true 参数可以列出所有可用设备名称。我在项目中经常先跑一遍这个命令,确认设备名再写推流脚本,避免踩坑。

3.1.2 本地文件推流

文件推流常用于点播转直播、循环播放等场景。关键参数是 -re,它让 FFmpeg 以原始帧率读取文件,而不是全速读取。我曾经遇到过不加 -re 导致文件瞬间读完、推流中断的情况。

# 本地 MP4 文件推流(循环播放)
ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -f rtsp rtsp://server/live/stream

3.1.3 桌面录制

桌面推流在直播、远程教学、游戏录制中很常见。不同平台命令差异较大:

平台 输入格式 示例命令
Windows gdigrab -f gdigrab -i desktop
macOS avfoundation -f avfoundation -i "1"
Linux (X11) x11grab -f x11grab -i :0.0

注意:桌面录制对 CPU 和内存消耗较大。如果推流时发现画面掉帧,可以尝试降低采集分辨率或帧率。我一般先用 -s 1280x720 缩放到 720p,再编码推流。

3.2 编码器选择:H.264 还是 H.265?

编码器是推流的核心。H.264 兼容性最好,几乎所有播放器都支持。H.265 压缩率更高,但解码要求也更高。怎么选?

  • H.264:通用场景首选。RTSP 推流默认用 libx264 软编,或者 h264_omx / h264_nvenc 硬编。
  • H.265:带宽有限或追求更高画质时使用。软编用 libx265,硬编用 hevc_nvenc / hevc_amf。

我个人习惯:局域网内推流用 H.264,延迟低、兼容好;公网推流用 H.265,省带宽。但要注意,很多老旧 RTSP 播放器不支持 H.265,推之前先确认客户端能力。

# H.264 软编推流
ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -f rtsp rtsp://server/live/stream

# H.265 硬编推流(NVIDIA GPU)
ffmpeg -i input.mp4 -c:v hevc_nvenc -preset p4 -f rtsp rtsp://server/live/stream

关键对比:H.264 编码速度更快,H.265 压缩率高出约 30-50%。在同等码率下,H.265 画质明显更好。

3.3 码率控制:CBR、VBR 与 CRF

码率控制决定了视频的压缩策略。三种模式各有适用场景:

模式 特点 适用场景 FFmpeg 参数示例
CBR 恒定码率,输出码率稳定 直播、RTSP 推流、带宽受限环境 -b:v 2M -minrate 2M -maxrate 2M -bufsize 4M
VBR 可变码率,复杂场景码率高 本地录制、点播文件 -b:v 2M -maxrate 4M -bufsize 4M
CRF 恒定质量,码率自动调整 本地存档、后期处理 -crf 23

嗯,这里有个坑。很多新手推流时直接用 CRF 模式,结果码率忽高忽低,RTSP 服务器扛不住。我建议:RTSP 推流优先用 CBR,码率稳定才能保证网络传输不抖动。

# RTSP 推流推荐:CBR 2Mbps
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -minrate 2M -maxrate 2M -bufsize 4M -f rtsp rtsp://server/live/stream

避坑指南:我曾经在公网推流时用了 VBR,结果网络波动时码率飙升到 8Mbps,直接把服务器打挂了。后来全部改成 CBR + 适当降低码率,再也没出过问题。

3.4 GOP 大小设置

GOP(Group of Pictures)是关键帧间隔。GOP 越小,延迟越低,但码率会升高。GOP 越大,压缩率越高,但 seek 和切换流时等待时间更长。

RTSP 推流中,GOP 大小直接影响延迟。我一般这样设置:

  • 低延迟场景(如安防监控):GOP = 帧率 × 1~2 秒,例如 25fps 时 -g 25 或 -g 50
  • 普通直播:GOP = 帧率 × 2~3 秒,例如 -g 75
  • 点播转直播:GOP 保持原文件设置,用 -c copy 避免重编码
# 设置 GOP 为 50 帧(约 2 秒,25fps 下)
ffmpeg -i input.mp4 -c:v libx264 -g 50 -f rtsp rtsp://server/live/stream

注意:GOP 设置过小会导致码率飙升。我曾经为了追求低延迟把 GOP 设为 10,结果码率直接翻倍,画面反而卡顿。找到平衡点很重要。

3.5 帧率控制

帧率控制用 -r 参数。推流时帧率必须与输入源匹配,否则会出现音画不同步。常见场景:

  • 摄像头:通常 25fps(PAL)或 30fps(NTSC)
  • 电影文件:23.976fps 或 24fps
  • 桌面录制:15~30fps,根据内容动态调整
# 强制输出 25fps
ffmpeg -i input.mp4 -c:v libx264 -r 25 -f rtsp rtsp://server/live/stream

如果输入源帧率不稳定(比如桌面录制时静止画面帧率低),可以用 -vsync 参数控制同步策略。我个人习惯用 -vsync 2,它会丢弃或复制帧以匹配目标帧率,效果比较稳定。

总结一下:输入源选对格式,编码器按场景选,码率控制用 CBR 保稳定,GOP 设 1~2 秒,帧率与源匹配。这套组合拳打下来,RTSP 推流基本不会出大问题。