WHIP 协商分析研究
一、概述
本文分析 WHIP 的协商过程, 着重分析数据传输相关部分,回答了以下问题:
- RTC 使用何种格式进行传输? 强制规定使用 (S)RTP (作为背景补充, 不在本文范畴之内)
- 多路媒体轨 (音频轨 & 视频轨) 、RTP/RTCP 使用何种传输方式? 使用多路复用传输, 即所有传输共用同一端口.
- 媒体能力协商如何进行? 采用 SDP 的 offer/answer 机制, 进行编码协商.
- MSID 与 SSRC 的关系? MSID 与 SSRC 存在映射关系,MSID 主要服务于 JavaScript 语言.
除此之外, 本文还遗漏了部分内容有待深入研究:
- ICE 协商过程: ICE 分为 Lite 和 Full 两种, 其简单概率为能力不同; Lite 为简化实现, Full 为完整实现.
- ICE 建立过程: 见 【RFC 5245】(Interactive Connectivity Establishment (ICE))
- RTP 其他特性: 如 NACK 、FEC 等
二、多路复用
(1)RTCP/RTP 端口复用
RTP/RTCP 在设计之初与底层媒体传输分割开, 具体表现为:
- RTP/RTCP 既可以通过 TCP 传输, 亦可以通过 UDP 传输
- RTP/RTCP 可以分别用两个端口单独传输, 也可以使用一个端口共用传输; 甚至于可以与其他协议服用同端口, 如与 RTSP 复用 554 端口
WebRTC 规定 RTP/RTCP 必须使用多路复用, 具体表现为 SDP 一定存在 “a=rtcp-mux” 属性.
(2)媒体端口复用
在 RTP/RTCP 进行端口复用的情况下, 如果同时传输视频流和音频流的话, 仍需要两个端口;
WebRTC 规定媒体流也应当进行端口复用, 具体的实现机制使用 SDP Bundle 机制, 详细说明可见 【RFC 9143】(Negotiating Media - Multiplexing Using the Session Description Protocol (SDP)).
简单可以为, 可以预先定一个 Group, 并将每一条 MediaStream 都关联至此 Group 上, 通过 SDP 的 answer 可以直接观察到:
(3)考虑原因
为什么 WebRTC 在设计时会强制要求所有数据传输共用同一端口? 有不少原因, 但主要是考虑到以下场景:
- P2P 的数据传输往往需要打洞, 使用单一端口可以简化打洞流程和端口保活.
- 网络丢包可能只在其中某一路中出现, 如网络中继器如果队列已满, 可能会丢弃后来的包.
- 可以节约资源, 如服务器的端口消耗等.
但这需要在应用层能够根据包的内容进行分包, 加重了协议层的负担, 并在设计不当的情况下增加的协议的耦合程度.
三、媒体协商
SDP 分别两类:
- 通知型 : 服务端 SDP 中包含着需要传输的编码信息, 客户端不可修改
- 协商型: 服务端 SDP 中包含着可选的传输编码信息, 由客户端进行选择.
WHIP 使用的是协商型 SDP, 但与 JSEP (浏览器 WebRTC) 不同;
WHIP 的协商一般只能在握手进行, 不能 (或不建议) 在中途进行变更.
与传统的 SIP SDP offer/answer 的逻辑并无差异,
如客户端 Offer 时包含多个可选编码:
服务端选择其中一个并返回:
rtx 表示 RTP 重传机制, 实际上也可单独占用一个端口, 在 WebRTC 中也参与端口复用.
四、MSID 是什么?
在 WebRTC 中存在 MSID 的概念,这与 WebRTC 的历史存在一定关系.
WebRTC 的全称可以解释为 **W3C ** Web Real-Time Communication, 与 **W3C ** 存在着紧密联系.
进一步说, W3C 定义了一套 JavaScript 接口, 实现了 WebRTC.
然后就出现了一个问题, JavaScrip 如何索引 RTP 流? W3C 想出了一个折中的办法:
- RTP/RTCP 可以通过 SSRC 唯一索引流
- JavaScript 可以通过 DOM 的名称唯一索引
一种简单的方式就是做映射关系, 也是在 SDP 中进行描述, 详细可以见 【RFC 9429】(JavaScript Session Establishment Protocol (JSEP))
【RFC 8830】(WebRTC MediaStream Identification in the Session Description Protocol) 则描述如何进行这种映射关系, 以 SDP 为例: