27、项目实战:直播系统(一):直播场景与架构设计、基于WebRTC的推拉流方案、与CDN结合(WHIP/WHEP协议)
好,咱们终于到了实战环节。说实话,前面讲了那么多WebRTC的理论和API,大家可能早就手痒了。今天我们就来搞一个真正的直播系统——不是那种Demo级别的点对点通话,而是能支撑成千上万人同时观看的直播架构。
我个人习惯,做项目前先把场景想清楚。直播嘛,说白了就是「一个人推,无数人拉」。但这里面坑不少,我们一个一个来填。
直播场景与核心架构
先聊聊直播场景。你想想看,一个典型的直播系统,角色其实就三种:
- 主播:采集音视频,编码后推流到服务器
- 服务器:接收推流,转码、分发、录制……干一堆脏活累活
- 观众:从服务器拉流,解码播放
听起来简单?嗯,但这里有个关键问题——WebRTC原本是为点对点设计的,它不擅长一对多分发。如果一万个观众都直接连主播,主播的带宽和CPU瞬间就炸了。
所以我们需要一个中间层。我早期做的一个项目,就是没想清楚这点,结果主播那边上行带宽跑满,观众还卡得要死。后来痛定思痛,引入了媒体服务器做分发,问题才解决。
下面这张图,是我总结的直播系统核心架构:
你看,主播推流到媒体服务器,媒体服务器再转推给CDN,观众从CDN拉流。这样主播只需要推一路流,CDN负责大规模分发,各司其职。
基于WebRTC的推拉流方案
传统直播用RTMP推流、HLS拉流,延迟高得吓人。WebRTC的优势就是低延迟,能做到秒级甚至毫秒级。但WebRTC本身没有定义「推流」和「拉流」的标准接口,所以业界搞了两个协议:WHIP和WHEP。
WHIP(WebRTC HTTP Ingestion Protocol):WebRTC推流协议。主播通过HTTP请求,把媒体流推送到服务器。
WHEP(WebRTC HTTP Egress Protocol):WebRTC拉流协议。观众通过HTTP请求,从服务器拉取媒体流。
说白了,WHIP就是告诉服务器「我要推流了,给我个SDP Offer」,WHEP就是告诉服务器「我要看流了,给我个SDP Answer」。底层还是WebRTC那套ICE、DTLS、SRTP,但上层用HTTP来管理会话。
我记得第一次用WHIP的时候,觉得这东西真巧妙——把WebRTC的复杂信令封装成了简单的HTTP请求。你想想看,以前做WebRTC信令要自己搭WebSocket服务器,现在一个POST请求就搞定了。
WHIP推流流程
- 主播创建PeerConnection,生成SDP Offer
- 通过HTTP POST把Offer发给WHIP端点
- 服务器返回SDP Answer,同时返回一个资源URL
- 主播设置Answer,ICE连接建立,开始推流
- 推流过程中,通过PATCH请求更新ICE候选
- 推流结束,DELETE请求销毁会话
小技巧:WHIP的HTTP端点通常长这样:https://server/whip/endpoint。返回的资源URL可以用来控制会话生命周期,记得保存好。
WHEP拉流流程
- 观众创建PeerConnection,生成SDP Offer
- 通过HTTP POST把Offer发给WHEP端点
- 服务器返回SDP Answer,开始拉流
- 观众收到音视频数据,解码播放
流程几乎一样,区别在于WHEP是服务器往观众这边推数据。嗯,这里要注意,WHEP的Offer里要设置好接收音视频的编解码器参数,不然服务器不知道给你发什么格式。
与CDN结合:WHIP/WHEP协议
CDN(内容分发网络)是直播系统的关键。没有CDN,你的服务器扛不住大规模观众。WHIP/WHEP协议天然适合与CDN结合,因为它们是HTTP-based的,CDN可以直接处理。
具体怎么结合呢?我画个流程图你就明白了:
这里有个关键点:CDN边缘节点需要支持WebRTC的UDP传输。传统CDN主要做HTTP/HTTPS的TCP加速,但WebRTC用的是UDP。所以你要找支持WebRTC的CDN服务商,或者自己搭建UDP加速层。
注意:我曾经在一个项目中,直接拿传统CDN做WebRTC分发,结果发现UDP包被丢得一塌糊涂。后来换成了支持WebRTC的CDN,延迟从5秒降到了500毫秒。所以选CDN时一定要确认是否支持UDP/WebRTC。
推拉流方案对比
为了让你更清楚不同方案的优劣,我整理了一个对比表:
| 方案 | 延迟 | 复杂度 | CDN支持 | 适用场景 |
|---|---|---|---|---|
| RTMP + HLS | 5-30秒 | 低 | 成熟 | 传统直播、点播 |
| WebRTC + WHIP/WHEP | 0.5-2秒 | 中 | 新兴 | 互动直播、低延迟场景 |
| WebRTC + SFU | 0.1-0.5秒 | 高 | 有限 | 视频会议、小规模互动 |
| SRT + WebRTC | 1-3秒 | 高 | 一般 | 专业推流、广电级 |
你看,WHIP/WHEP方案在延迟和复杂度之间取得了不错的平衡。而且它基于HTTP,防火墙友好,部署起来也方便。
实战中的避坑指南
最后,分享几个我在实战中踩过的坑:
- ICE候选收集不全:WHIP推流时,如果主播在复杂的网络环境(比如公司内网),ICE候选可能收集不全。我建议在推流前先做连通性检测,或者配置TURN服务器兜底。
- SDP协商失败:不同浏览器对编解码器的支持不一样。Chrome和Firefox的SDP格式有差异,最好在服务端做SDP归一化处理。
- CDN缓存策略:WHEP拉流时,CDN可能会缓存SDP信息。如果主播切换了编码参数,观众拿到的还是旧SDP,就会黑屏。解决办法是在WHEP请求中加时间戳或随机参数,防止缓存。
- 带宽预估不准:WebRTC的带宽预估算法(GCC)在直播场景下可能过于保守。我习惯手动调整码率上限,或者使用Simulcast(分层编码)让观众根据自身带宽选择合适的分辨率。
好了,这一章的内容就到这里。WHIP/WHEP协议是WebRTC直播的核心,理解了它,你就掌握了低延迟直播的钥匙。下一章我们会动手搭建一个真正的直播系统,从推流到拉流,全部跑通。
公众号:蓝海资料掘金营,微信deep3321