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 Identifier)で低・中・高などの品質を識別します。これらの simulcast ストリームは、Cloudflare Realtime SFU に送る SDP に記述します。各サブスクライバーのネットワーク状況と端末性能に応じて適切な品質を届けるのは、Cloudflare Realtime SFU の役割です。
Cloudflare Realtime SFU は、パブリッシャーから受け取った SDP に基づいて simulcast の設定を自動で処理します。その後、サブスクライバーのネットワーク状況に応じて品質レベルを自動で切り替えます。品質は 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パブリッシャー側のエンドポイントがブラウザの場合は、トランシーバー作成時に 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 エンドポイントを呼び出し、別のブラウザや端末からリモートトラックの受信を開始します。手順 2 で得たリモートトラック ID とあわせて、
simulcast設定オブジェクトを指定します。
ほかの例は Realtime Examples GitHub リポジトリ ↗ を参照してください。