跳到主要内容

L4-WHIP-WHEP低延迟直播

把 WebRTC 用作直播协议。WHIP 标准化推流(OBS → 服务端),WHEP 标准化拉流(服务端 → 浏览器播放器)。延迟可降到 500ms 以内,对 CDN 友好。

1. 为什么用 WHIP/WHEP

维度RTMP + HLSWHIP + WHEP
推流协议RTMP(已被浏览器淘汰)WebRTC over HTTP
拉流协议HLS(6~30s 延迟)WebRTC(< 1s)
浏览器原生❌ 拉流要播放器
CDN 兼容成熟还在演进
信令复杂度推流需 RTMP,拉流单 HTTP双侧单 HTTP
加密RTMPS / HTTPS强制 DTLS-SRTP

2. 学习目标

  • 理解 WHIP 推流流程(HTTP POST SDP Offer,回 Answer)。
  • 实现 WHEP 拉流端点。
  • 把信令简化成 1 个 HTTP 请求。
  • 用 OBS 31+ 直接 WHIP 推到自研服务端。

3. 架构

4. WHIP 协议交互

# 推流端(OBS / 浏览器)→ 服务端
POST /whip/{streamKey} HTTP/1.1
Host: ingest.example.com
Content-Type: application/sdp
Authorization: Bearer xxxxx

v=0
o=- 1 2 IN IP4 0.0.0.0
...(推流端的 Offer SDP)

# 服务端响应
HTTP/1.1 201 Created
Location: /whip/{streamKey}/resource/abc
Content-Type: application/sdp

v=0
...(服务端的 Answer SDP)

发起后用 PATCH 推 Trickle ICE 候选;DELETE 释放资源。

PATCH /whip/{streamKey}/resource/abc HTTP/1.1
Content-Type: application/trickle-ice-sdpfrag

a=candidate:1 1 UDP 2122252543 ...

5. 客户端代码(浏览器侧)

async function whipPublish(stream, endpoint, token) {
const pc = new RTCPeerConnection({iceServers});
for (const t of stream.getTracks()) pc.addTransceiver(t, {direction: 'sendonly'});

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

const res = await fetch(endpoint, {
method: 'POST',
headers: {'Content-Type': 'application/sdp', 'Authorization': `Bearer ${token}`},
body: offer.sdp,
});
const answer = await res.text();
const resourceUrl = res.headers.get('Location');

await pc.setRemoteDescription({type: 'answer', sdp: answer});

// Trickle ICE 走 PATCH(可选,多数实现也接受 SDP 一次给齐)
pc.onicecandidate = ({candidate}) => {
if (candidate) fetch(resourceUrl, {
method: 'PATCH',
headers: {'Content-Type': 'application/trickle-ice-sdpfrag'},
body: `a=${candidate.candidate}`,
});
};

return { pc, resourceUrl };
}

async function whipUnpublish(resourceUrl) {
await fetch(resourceUrl, {method: 'DELETE'});
}

WHEP 与 WHIP 对称,把 transceiver direction 改成 recvonly 即可。

6. 服务端选型

选型语言适合
Pion WHIP server 示例Go自研轻量服务
LiveKit IngressGo已用 LiveKit 的项目
GStreamer + webrtcsinkC/Rust视频后端栈
Janus VideoRoom + WHIP pluginC已用 Janus 的项目

7. 推流端

客户端WHIP 支持备注
OBS Studio 31+✅ 原生"服务"选 WHIP
ffmpeg ≥ 7.1-f whip
浏览器✅ 自己写上面那段 30 行 JS
移动端原生通过 libwebrtc 实现

8. 与 CDN / 大规模分发的边界

WHIP/WHEP 单实例上限大约同 SFU 一档。要做"百万直播 + 低延迟",仍需要边缘 SFU 集群 + CDN 智能路由。

经验值:单台 c7.2xlarge 跑 Pion WHEP 大概 1k 路同时观看,超过要做级联。

9. 验收 Checklist

  • OBS 推流端到端延迟 < 1s
  • 浏览器播放器单 HTTP 请求即开播
  • 关闭 OBS 后服务端在 5s 内回收资源
  • 弱网(200ms RTT)画面不抖动
  • 与 RTMP/HLS 主路并存(同源双协议)

10. 参考资料