最近一直在学习低延迟直播系统的开发,从协议选型到具体实现,踩过不少坑,也积累了很多经验。分享一下这段旅程中的思考和收获~
一、直播核心协议选型:从认知到决策
开发的第一步,是理清主流直播协议的特性,找到适配场景的技术方向。以下是我对核心协议的整理与分析:
1. HTTP-FLV:兼容性之王
核心特点:基于 HTTP 分块编码传输 FLV 容器格式,轻量化、易部署。
-
封装与传输:FLV 仅支持 H.264/H.265(视频)、AAC/MP3(音频),封装简单(头部 + 音视频 Tag),解码延迟低;借助 HTTP 分块编码实现 "边传边播",默认 80/443 端口可穿透防火墙。
-
传输流程:
- 播放端发送
GET /live/stream.flv请求,携带Accept: */*; - 服务端响应
Transfer-Encoding: chunked,按 1-8KB 拆分 FLV 流并实时推送。
- 播放端发送
-
延迟构成:
- 编码延迟(50ms-300ms):依赖推流端低延迟配置(无 B 帧、短 GOP);
- 服务端延迟(300ms-2s):GOP 缓存 / 转码是主因(优化后可压至 300ms 内);
- 传输 + 播放端延迟(400ms-1.9s):HTTP 封装开销 + 播放器缓冲(优化后可至 0.3-1s)。
-
优缺点:✅ 兼容性极强(浏览器 / APP / 机顶盒)、配置简单、支持 HTTPS;❌ 协议开销略高、依赖 GOP 缓存、Web 端需 FLV.js 解析。
2. RTMP:低延迟直播老将
核心特点:基于 TCP 的实时消息传输协议,专为音视频设计。
- 传输机制:分层结构(应用层 / 消息层 / 协议层),Chunk 分块传输大帧,滑动窗口控流。
- 延迟优势:优化后全链路延迟 0.8-2s,比 HTTP-FLV 低 20%-30%,服务端无转码时延迟可忽略。
- 优缺点:✅ 延迟低、配置直接、兼容性广;❌ 弱网 TCP 重传易卡顿、无默认加密、Web 端需 Flash 替代方案。
3. HLS/LL-HLS:跨平台兼容首选
核心特点:切片传输 + 自适应码率,原生支持全平台。
- 原生痛点:切片机制导致延迟 10-30s(切片生成 + 缓存 + 播放缓冲);
- LL-HLS 优化:缩短切片至 0.5-2s、分片传输 Chunk、实时更新 m3u8,延迟降至 3-5s。
- 优缺点:✅ 极致兼容、自适应码率、易部署;❌ 原生延迟高、切片开销大、实时性差。
4. WebRTC:实时互动利器
核心特点:浏览器原生实时通信,毫秒级延迟(50-300ms)。
- 技术栈:集成采集 / 编码 / 传输 / 渲染,UDP 传输 + P2P 直连,内置回声消除等互动功能。
- 延迟构成:采集编码(30-80ms)+ 传输(20-150ms)+ 解码渲染(10-30ms)。
- 优缺点:✅ 延迟最低、互动性强、无插件依赖;❌ 部署复杂(需 STUN/TURN/SFU)、带宽占用高。
5. SRT:专业级低延迟传输
核心特点:UDP 可靠传输 + 加密,延迟 10-150ms,抗丢包(10% 丢包仍稳定)。
- 技术优势:ARQ 重传 + FEC 纠错,原生 AES 加密,适配 4K/8K 高码率传输。
- 优缺点:✅ 延迟极低、可靠性强、加密安全;❌ Web 端兼容性差、CDN 支持有限、配置精细。
协议特性对比表
| 特性 | SRT | WebRTC | HTTP-FLV(优化后) | RTMP(优化后) |
|---|---|---|---|---|
| 原生延迟 | 10-150ms | 50-300ms | 1-2.5s | 0.8-2s |
| 传输协议 | UDP(可靠传输) | UDP(为主) | TCP(HTTP/HTTP3) | TCP |
| 丢包容忍性 | 强(10% 丢包) | 中(5% 丢包) | 强(TCP 重传) | 中(TCP 重传阻塞) |
| 加密支持 | 原生 AES | 需 DTLS | 依赖 HTTPS | 需 RTMPS |
| 高并发支持 | 中(需媒体服务器) | 低(P2P 带宽受限) | 高(CDN 分发) | 中(CDN 支持) |
| 部署复杂度 | 中 | 高 | 低 | 中 |
二、开发实践:从选型到落地的坎坷
1. 初期选型:WebRTC 的尝试与碰壁
最开始选择 WebRTC 作为核心协议(一是初期对 SRT 认知不足,二是看中其浏览器原生兼容性):
- 手动封装信令服务器 + WebRTC 推拉流组件,实现基础功能后发现并发极低;
- 转向 MediaSoup(SFU 框架)优化并发,但全英文文档 + 拓展复杂度高,最终放弃。
这段经历虽未落地,但吃透了 WebRTC 的信令交互、NAT 穿透、媒体流处理逻辑。
2. 最终选型:SRS 的救赎
SRS(Simple Real-Time Server)是开源实时视频服务器,支持多协议转换,成为我的最终选择:
- 支持 RTMP/WebRTC/HTTP-FLV/SRT 等协议,开箱即用;
- 解决了 WebRTC 并发问题,且支持协议转换(如 RTMP 转 WebRTC)。
SRS 配置(6.0 版本)
ini
# main config for srs.
listen 1935; # RTMP端口
max_connections 1000; # 最大连接数
daemon on; # 守护进程模式
# HTTP API:用于控制和查询SRS状态
http_api {
enabled on;
listen 1985;
}
# HTTP服务器:提供HLS/HTTP-FLV访问
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html; # 静态文件目录
}
# WebRTC配置:UDP端口+公网候选地址
rtc_server {
enabled on;
listen 8000; # WebRTC的UDP端口
candidate 0.0.0.0; # 公网服务器需替换为实际IP
}
vhost __defaultVhost__ {
# HLS配置:低延迟切片
hls {
enabled on;
hls_path ./objs/nginx/html/hls;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
hls_fragment 1; # 1秒切片,降低延迟
}
# HTTP-FLV挂载
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
# WebRTC与RTMP互转
rtc {
enabled on;
rtmp_to_rtc on; # RTMP推流转WebRTC播放
rtc_to_rtmp on; # WebRTC推流转RTMP播放
}
# 播放优化:GOP缓存+队列控制
play {
gop_cache_max_frames 2500;
gop_cache on; # 缓存GOP实现秒开
queue_length 10; # 播放队列长度(缓存10帧)
}
}
踩坑与解决
- AI 提供的配置常出现语法错误(如路径格式、参数冲突),需结合官方文档逐行校验;
- WebRTC 推流需确保
candidate配置正确(公网 IP / 端口映射),否则无法建立连接; - 低延迟优化需关闭 GOP 缓存、缩短 HLS 切片、减小播放器缓冲。
三、收获与总结
-
协议选型无优劣,适配场景是关键: 互动场景选 WebRTC,低延迟直播选 SRT/RTMP,跨平台兼容选 LL-HLS;
-
开源工具的力量:SRS 这类成熟框架节省了底层开发成本,聚焦业务逻辑即可快速落地;
-
实践出真知:从手动封装组件到踩坑 SRS 配置,每一步试错都加深了对直播技术栈的理解。
目前已实现 OBS(WebRTC)推流、前端 / VLC 拉流的低延迟直播,后续计划探索 SRT 协议集成、高并发优化。万事开头难,技术沉淀在于持续踩坑与复盘~