RTMP 推流与拉流
本教程共 32 篇 · 第 29 篇 · 更新于 2026-08-09 · 约 5 分钟阅读
本节目标:会用 FFmpeg 向 RTMP 服务器推直播流、从 RTMP 拉流保存;理解关键帧和 GOP 对直播的影响;知道 RTMP 与 HLS 怎么配合。
HLS 适合给观众分发,但在直播采集端,行业里长期使用 RTMP(Real-Time Messaging Protocol)。它延迟低、连接稳定,是 OBS、FFmpeg 向 YouTube/Twitch/B 站推流的通用语言。
一、RTMP 是什么
RTMP 是 Adobe 当年为 Flash 设计的协议,基于 TCP,把音视频数据切成小消息持续传输。典型工作流:
采集端(FFmpeg/OBS) --RTMP推流--> 流媒体服务器 --HLS/FLV--> 观众
虽然 Flash 已死,RTMP 作为推流(ingest)协议依然是主流。它负责把画面从编码器送到服务器,服务器再转成 HLS/DASH/HTTP-FLV 分发给观众。
二、推流:把视频送到 RTMP 服务器
最基本的推流命令:
ffmpeg -re -i input.mp4 -c:v libx264 -c:a aac -f flv rtmp://live.example.com/app/streamkey
逐个参数看:
-re:按原生帧率读取输入。推本地文件必须加这个,否则 FFmpeg 会用最快速度把文件瞬间推完,直播就”爆”了。推摄像头/采集设备时不需要-re,因为设备本身就是实时的。-c:v libx264:RTMP 视频几乎都用 H.264(也支持 H.265,但兼容性不如 H.264 广)。-c:a aac:音频用 AAC,采样率建议 44100 或 48000。-f flv:RTMP 承载的容器格式是 FLV,必须显式指定。- 最后是 RTMP 地址,格式通常是
rtmp://服务器/应用名/流名(密钥)。
直播编码参数
直播讲究稳定和低延迟,编码参数和本地压片不同:
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset veryfast -tune zerolatency \
-b:v 4000k -maxrate 4000k -bufsize 2000k \
-g 60 -keyint_min 60 \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://live.example.com/app/streamkey
关键点:
- preset 要快:
veryfast或faster,保证实时编码不掉帧。-tune zerolatency关闭缓冲,降低延迟。 - CBR 恒定码率:
-b:v配-maxrate+-bufsize,让码率稳定,避免卡顿。bufsize 设成码率的 0.5–2 倍。 - 固定 GOP(关键帧间隔):
-g 60 -keyint_min 60。30fps 下每 60 帧(2 秒)一个关键帧。GOP 太长会导致观众加入慢、切片不准;太短会降低压缩率。直播常用 2 秒。 - 音频稳定:AAC 128k、44.1/48kHz。
Note推流不是越清晰越好。码率要匹配上行带宽:你家宽带上行只有 2 Mbps,就别推 4 Mbps。留 30% 余量,比如上行 6 Mbps 推 4 Mbps 比较稳。
三、拉流:把 RTMP 流保存下来
服务器上或本地想把直播录下来:
ffmpeg -i rtmp://live.example.com/app/streamkey -c copy output.mp4
用 -c copy 直接复制流,不重编码,省 CPU,保存下来的就是原始推流内容。也可以直接播:
ffplay rtmp://live.example.com/app/streamkey
拉流转协议
把 RTMP 流转成 HLS:
ffmpeg -i rtmp://localhost/live/stream \
-c:v libx264 -c:a aac -f hls \
-hls_time 4 -hls_list_size 10 -hls_flags delete_segments \
/var/www/html/hls/stream.m3u8
这就是一个简易的 RTMP→HLS 网关:接收推流,实时切片成 HLS,交给 HTTP 服务器分发。生产环境通常用 NGINX-RTMP、SRS、Wowza 等服务器做这件事,而不是纯 FFmpeg,但理解这条命令能帮你掌握原理。
四、关键帧(GOP)为什么重要
视频不是每帧都完整记录,而是分成:
- I 帧(关键帧):完整画面,可独立解码。
- P/B 帧:只记录和相邻帧的差异,必须依赖关键帧才能还原。
两个关键帧之间叫一个 GOP(Group of Pictures)。直播中:
- 观众中途加入,必须等到下一个关键帧才能开始看。
- HLS 切片必须在关键帧处切开,否则切片无法独立播放。
-g 60让关键帧间隔固定,切片才整齐。
Tip如果推流后发现 HLS 切片时长忽长忽短、播放器花屏,十有八九是关键帧没对齐。加上
-g 60 -keyint_min 60并启用-hls_flags independent_segments通常能解决。
五、协议对比与选择
| 协议 | 延迟 | 用途 | 浏览器直接播放 |
|---|---|---|---|
| RTMP | 1–5 秒 | 推流到服务器 | 否(Flash 已死) |
| HLS | 6–30 秒(LL-HLS 约 2–3 秒) | 给观众分发 | Safari 原生,其他需 hls.js |
| DASH | 类似 HLS | 给观众分发 | 需 dash.js |
| SRT | <2 秒 | 跨网高质量传输 | 否(需专用播放器) |
| WebRTC | <1 秒 | 视频通话、连麦 | 浏览器原生 |
记住一个分工:RTMP/SRT 负责把流送进服务器,HLS/DASH 负责把流送给观众。低延迟互动(直播连麦、会议)才用 WebRTC。
六、常见推流目标
各大平台的推流地址形式类似:
YouTube : rtmp://a.rtmp.youtube.com/live2/你的密钥
Twitch : rtmp://live.twitch.tv/app/你的密钥
B 站 : rtmp://live-push.bilivideo.com/live-bvc/?streamname=...
在平台后台拿到”服务器地址 + 推流密钥”,拼到 -f flv 后面即可。各平台会推荐码率和分辨率(比如 Twitch 建议 4500–6000 kbps、1080p60),按推荐值设置即可。
NoteRTMP 本身不加密,公网传输推流密钥有泄露风险。现在很多平台支持 RTMPS(RTMP over TLS),把地址写成
rtmps://...即可,用法完全一样。