22、WebRTC与直播:WHIP/WHEP协议、低延迟直播方案、LL-HLS对比
聊到WebRTC和直播的结合,很多人第一反应是“WebRTC不是做实时通信的吗?跟直播有什么关系?”
嗯,这个问题我几年前也困惑过。后来在做一个互动直播项目时,被延迟问题折磨得够呛,才真正开始研究WebRTC在直播场景下的落地。今天咱们就把这块掰开揉碎了讲清楚。
一、直播延迟的痛点:为什么传统直播不够用?
先说说传统直播的延迟情况。HLS(HTTP Live Streaming)和DASH是主流方案,但它们有个天然缺陷——切片机制。
HLS把视频切成一个个小片段,每个片段2-10秒。播放器下载完一个片段才能播,再加上缓冲区,延迟轻松到20-30秒。你想想看,直播间里观众刷“主播你好”,主播30秒后才看到,这互动体验能好吗?
我在做电商直播项目时,遇到过最夸张的情况:主播说“上链接”,观众看到时商品已经抢光了。延迟整整45秒。从那以后,低延迟就成了我重点关注的方向。
二、WHIP/WHEP协议:WebRTC进入直播的钥匙
WHIP(WebRTC HTTP Ingestion Protocol)和WHEP(WebRTC HTTP Egress Protocol)是IETF标准化的协议。说白了,它们解决了两个问题:
- WHIP:推流端怎么把视频流送进服务器
- WHEP:播放端怎么从服务器拉流播放
为什么需要这两个协议?因为WebRTC原本是P2P的,没有“服务器中转”的标准。你直接用WebRTC推流到CDN?不行,CDN不认识SDP和ICE。WHIP/WHEP就是那个“翻译官”。
WHIP推流流程
- 推流端创建PeerConnection,生成SDP Offer
- 通过HTTP POST发送SDP到WHIP端点
- 服务器返回SDP Answer,并分配一个资源URL
- ICE连接建立,开始推流
// WHIP推流示例(简化版)
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 发送到WHIP端点
const response = await fetch('https://whip-server.example.com/whip', {
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: pc.localDescription.sdp
});
const answerSdp = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });
WHEP拉流流程
WHEP和WHIP类似,只是方向相反。播放端向WHEP端点请求流,服务器返回SDP,然后建立WebRTC连接。
// WHEP拉流示例
const pc = new RTCPeerConnection();
pc.ontrack = event => {
videoElement.srcObject = event.streams[0];
};
const response = await fetch('https://whip-server.example.com/whep/stream-123');
const offerSdp = await response.text();
await pc.setRemoteDescription({ type: 'offer', sdp: offerSdp });
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
// 把Answer发回服务器
await fetch(`https://whip-server.example.com/whep/stream-123`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/sdp' },
body: pc.localDescription.sdp
});
三、低延迟直播方案:不止WebRTC一条路
说到低延迟直播,市面上主要有几个流派。我整理了一张对比表,方便你直观感受差异。
| 方案 | 延迟范围 | 协议基础 | 浏览器兼容性 | 适用场景 |
|---|---|---|---|---|
| WebRTC (WHIP/WHEP) | 200ms - 1s | UDP + SRTP | Chrome/Firefox/Edge原生支持 | 互动直播、在线教育、远程医疗 |
| LL-HLS | 3-6s | HTTP + TS/fMP4 | 所有浏览器(通过HLS.js) | 大规模直播、赛事转播 |
| SRT | 500ms - 2s | UDP + 自定义ARQ | 需插件或Native SDK | 广电级传输、跨国推流 |
| RTMP | 3-8s | TCP | 需Flash(已淘汰) | 老旧系统兼容 |
从表里能看出来,WebRTC在延迟上优势明显。但为什么不是所有场景都用WebRTC?因为成本高、服务器压力大。WebRTC是UDP + 加密传输,对CPU和带宽消耗都比HLS大。
四、LL-HLS:苹果的改良方案
LL-HLS(Low-Latency HLS)是苹果在2019年推出的。它改进了传统HLS的切片方式,把延迟从20-30秒降到了3-6秒。
怎么做到的?核心是两个技术:
- 部分片段(Partial Segments):不再等整个切片完成再发布,而是边录制边发布小片段
- 预加载提示(Preload Hints):播放器可以提前请求下一个片段,减少等待时间
但说实话,LL-HLS的3-6秒延迟在互动场景下还是不够。我做在线答题直播时,要求延迟在1秒以内,LL-HLS完全扛不住。最后只能上WebRTC。
五、核心逻辑:什么时候选什么方案?
下面这张图是我自己总结的选型逻辑,帮你快速决策。
六、实战避坑指南
最后分享几个我在项目中踩过的坑,希望能帮你少走弯路。
我曾经在某个教育项目中,发现20%的用户连不上WebRTC。排查后发现是Symmetric NAT导致的。解决方案是部署TURN服务器,但TURN成本高,建议只在必要时启用。
你以为LL-HLS能稳定在3秒?不一定。如果播放器缓冲区设置不当,或者网络抖动,延迟可能跳到10秒以上。我建议在播放器端做动态缓冲区调整,根据网络状况自动缩短或延长缓冲区。
这个前面提过,但值得再说一遍。WHIP是客户端发Offer,WHEP是服务器发Offer。如果你用同一个代码库处理推流和拉流,一定要区分逻辑。我当初就是偷懒没区分,结果推流正常、拉流全挂。
好了,关于WebRTC和直播的结合,今天就聊到这儿。WHIP/WHEP让WebRTC进入了直播领域,LL-HLS则在传统HLS基础上做了改良。选哪个,取决于你的场景是强互动还是弱互动。
记住一句话:没有最好的协议,只有最合适的方案。
公众号:蓝海资料掘金营,微信deep3321