Simulcast(联播)是 WebRTC 的一项功能,它允许发布者以不同的质量发送相同媒体的多个视频流。例如,这在您希望为桌面用户发送高质量流,并为移动用户发送低质量流的场景下非常有用。
graph LR
A[发布者] -->|低质量| B[Cloudflare Realtime SFU]
A -->|中等质量| B
A -->|高质量| B
B -->|低质量| C@{ shape: procs, label: "订阅者"}
B -->|中等质量| D@{ shape: procs, label: "订阅者"}
B -->|高质量| E@{ shape: procs, label: "订阅者"}
WebRTC 中的 Simulcast 允许对单个视频源(如摄像头或屏幕共享)以多个质量级别进行编码并同时发送,这有利于具有不同网络条件和设备能力的订阅者。该视频源被编码为多个流,每个流由表示不同质量级别(如低、中、高)的 RID(RTP Stream Identifiers)进行标识。这些 simulcast 流在您发送给 Cloudflare Realtime SFU 的 SDP 中进行描述。Cloudflare Realtime SFU 的职责是确保根据每个订阅者的网络条件和设备能力,将适当质量的流递送给他们。
Cloudflare Realtime SFU 会根据您从发布者发送给它的 SDP 自动处理 simulcast 配置。随后,SFU 将根据订阅者的网络条件在不同的质量级别之间自动切换,或者可以通过 API 手动控制质量级别。当您发送 API 调用以开始拉取远程轨道时,您可以使用 simulcast 配置对象来控制质量切换行为。
当您开始拉取远程轨道时,API 调用中的 simulcast 配置对象允许您指定:
-
preferredRid:视频流的首选质量级别(simulcast 流的 RID。RID 可以由发布者指定。 ↗) -
priorityOrdering:控制 SFU 如何处理带宽限制。none:即使带宽不足,也继续发送通过 preferredRid 设置的首选图层。asciibetical:使用字母顺序(a-z)来确定优先级,其中 'a' 是最期望的,'z' 是最不期望的。
-
ridNotAvailable:控制当首选 RID 不再可用时(例如发布者停止发送它)会发生什么。none:不执行任何操作。asciibetical:根据优先级顺序切换到下一个可用的 RID,其中 'a' 是最期望的,'z' 是最不期望的。
您可能希望根据您期望的指标(例如分辨率从高到低,或带宽从高到低)对 asciibetical RID 进行排序。
Cloudflare Realtime 在传输层对所有媒体轨道一视同仁。例如,如果您有多个视频轨道(摄像头、屏幕共享等),它们在带宽分配上都具有相同的优先级。这意味着:
- 每个轨道的 simulcast 配置是独立处理的
- SFU 独立为每个轨道根据网络条件执行自动带宽估计和图层切换
当通过 /tracks/update API 请求图层切换(通过更新 preferredRid)时:
- SFU 将自动生成一个 Full Intraframe Request (FIR)
- PLI 生成会被防抖处理,以防止过多的请求
对于发布者(本地轨道),您只需在您的 SDP 中包含 simulcast 属性。SFU 将根据 SDP 自动处理 simulcast 配置。例如,SDP 应包含类似如下的片段:
a=simulcast:send f;h;q
a=rid:f send
a=rid:h send
a=rid:q send如果发布端是浏览器,可在创建 transceiver 时通过指定 sendEncodings 来包含这些编码,例如:
const transceiver = peerConnection.addTransceiver(track, {
direction: "sendonly",
sendEncodings: [
{ scaleResolutionDownBy: 1, rid: "f" },
{ scaleResolutionDownBy: 2, rid: "h" },
{ scaleResolutionDownBy: 4, rid: "q" },
],
});以下是如何在 Cloudflare Realtime 中使用 simulcast 的示例:
- 创建一个具有 simulcast 配置的新本地轨道。SDP 中应有一个包含
a=simulcast:send的片段。 - 使用 Cloudflare Realtime API 调用 /tracks/new 端点以推送此本地轨道。
- 使用 Cloudflare Realtime API 调用 /tracks/new 端点,指定
simulcast配置对象以及从步骤 2 中获取的远程轨道 ID,从而开始拉取远程轨道(来自其他浏览器或设备)。
有关更多示例,请查看 Realtime 示例 GitHub 仓库 ↗。