本节摘要:流媒体协议按「延迟 vs 兼容性」分成几派。本节讲清 RTMP、HLS、SRT、WebRTC 四类的出身、延迟量级与适用场景,给出一套「按场景选协议」的判断框架,并指出各协议在 FFmpeg 里的写法。
本节目标:阅读完本节,你应当能够:
流媒体协议不是设计竞赛,而是「网络条件 + 终端生态」逼出来的产物:
| 协议 | 传输 | 典型延迟 | 强项 | 弱点 | 典型场景 |
|---|---|---|---|---|---|
| RTMP | TCP 长连接 | 1–3 秒 | 推流成熟,生态完善 | 播放端浏览器不原生支持 | 直播推流入站 |
| HLS | HTTP(TCP) | 10–30 秒 | 兼容所有浏览器,天然 CDN 友好 | 延迟高 | 点播、大直播 |
| SRT | UDP + 重传 | 亚秒到 2 秒 | 抗丢包,穿越公网稳定 | 终端支持少 | 公网直播、传输 |
| WebRTC | UDP | <500ms | 极低延迟,浏览器原生 | 架构复杂 | 会议、连麦、低延迟直播 |
HLS 的播放流程是「索引 → 拉片 → 缓冲 → 播」。服务端要等一个切片写完才能发布,播放器要攒够几个片才开始播,每层都是延迟。降低延迟的办法是缩短切片(如 2 秒)并用 LL-HLS(低延迟 HLS),但依然降不到 RTMP 的量级。要低延迟,就得换协议。
RTMP 在「播放端」已经失势(浏览器不认),但「推流端」几乎还是它:直播平台普遍用 RTMP 接收入站流,再由服务器转成 HLS 或其他格式分发。所以 FFmpeg 里推流写 rtmp://,拉流播放反而少见直接用 RTMP。
# 推流到 RTMP 服务器 ffmpeg -re -i input.mp4 -c copy -f flv rtmp://server/live/stream_key # 拉取 HLS 流 ffmpeg -i https://example.com/live/index.m3u8 -c copy output.mp4 # 拉取 RTSP(监控常用) ffmpeg -i rtsp://user:pass@camera_ip/stream -c copy output.mp4
注意:RTMP 在 FFmpeg 里封装器写 flv(因为 RTMP 承载的是 FLV 封装),地址才是 rtmp://。
问三个问题:
用一张图把「延迟 vs 兼容」的坐标画出来:

图上 RTMP 偏左(兼容性窄,但延迟不高)、HLS 靠右(兼容性无敌、延迟高)、SRT 在左上(低延迟抗丢包但终端支持有限)、WebRTC 在中上(延迟最低但架构复杂)。看需求落在哪个象限,协议就清楚了。
常见坑:浏览器里直接播 RTMP 是不行的;HLS 的分片大小决定延迟与启动速度的平衡,别为了「低延迟」把切片切得太碎,反而增加服务器压力;SRT 需要双方都支持,公网传输前先确认对端能不能接。
💡 关键直觉:协议是「延迟、兼容、成本」三者的交换。没有全能的协议,选型第一步永远是把需求量化——延迟容忍几秒、终端有哪些、网络靠不靠谱。
协议标称的延迟是一个范围,因为端到端延迟由四段组成:采集延迟(摄像头/采集卡的处理时间)、编码延迟(编码器攒帧和 B 帧引入的延迟)、传输延迟(网络 RTT 加上缓冲)、播放缓冲延迟(播放器为了平滑故意攒的数据)。我们常说的「RTMP 延迟 1–3 秒」,其实大部分花在编码和播放缓冲上,而不是网络上。
# 用 ffmpeg 压测一下自己环境的基础延迟构成:编码端用 zerolatency ffmpeg -re -i input.mp4 -c:v libx264 -tune zerolatency -f flv rtmp://127.0.0.1:1935/live/t
-tune zerolatency 砍掉了 B 帧和编码缓冲,编码延迟立刻降下来。实测你会发现延迟改善明显——这证明编码延迟占比不小。同理,播放端 -fflags nobuffer 砍掉播放缓冲,又是一段延迟的消失。想优化延迟,先分清是「哪一段在拖后腿」,比盲目换协议高效得多。
-f flv下一节把协议落地成命令——推流与拉流的完整实操。