サイマルキャスト機能

概要

サイマルキャスト (Simulcast) は、配信時に 1 つの RTCPeerConnection から複数種類のエンコードした映像を配信する技術です。

映像を配信する際、 Sora に対して、 1 つの RTCPeerConnection で複数種類のエンコードした映像を送信することにより、 受信者がどの映像を受信するかを選択できるようになります。

注意

現時点でのサイマルキャストの仕様

2025 年 12 月 時点で libwebrtc を利用したサイマルキャストで出力されるストリームの本数は解像度とビットレートに依存しています。

VP8 / H264

解像度とビットレートとストリーム数の関係

解像度

ビットレート

ストリーム数

1920x1080

5000 kbps

3

1280x720

2500 kbps

3

960x540

1200 kbps

3

640x360

700 kbps

2

480x270

450 kbps

2

320x180

200 kbps

1

VP9 / AV1 / H265

解像度とビットレートとストリーム数の関係

解像度

ビットレート

ストリーム数

1920x1080

3367 kbps

3

1280x720

1524 kbps

3

960x540

879 kbps

3

640x360

420 kbps

2

480x270

257 kbps

1

320x180

142 kbps

1

240x135

101 kbps

1

libwebrtc の仕様

この値は libwebrtc にハードコードされています。 VP8 (AV1/H264) と VP9(H265) で異なります。

// These tables describe from which resolution we can use how many
// simulcast layers at what bitrates (maximum, target, and minimum).
// Important!! Keep this table from high resolution to low resolution.
constexpr const SimulcastFormat kSimulcastFormatsVP8[] = {
    {.width = 1920,
     .height = 1080,
     .max_layers = 3,
     .max_bitrate = DataRate::KilobitsPerSec(5000),
     .target_bitrate = DataRate::KilobitsPerSec(4000),
     .min_bitrate = DataRate::KilobitsPerSec(800)},
    {.width = 1280,
     .height = 720,
     .max_layers = 3,
     .max_bitrate = DataRate::KilobitsPerSec(2500),
     .target_bitrate = DataRate::KilobitsPerSec(2500),
     .min_bitrate = DataRate::KilobitsPerSec(600)},
    {.width = 960,
     .height = 540,
     .max_layers = 3,
     .max_bitrate = DataRate::KilobitsPerSec(1200),
     .target_bitrate = DataRate::KilobitsPerSec(1200),
     .min_bitrate = DataRate::KilobitsPerSec(350)},
    {.width = 640,
     .height = 360,
     .max_layers = 2,
     .max_bitrate = DataRate::KilobitsPerSec(700),
     .target_bitrate = DataRate::KilobitsPerSec(500),
     .min_bitrate = DataRate::KilobitsPerSec(150)},
    {.width = 480,
     .height = 270,
     .max_layers = 2,
     .max_bitrate = DataRate::KilobitsPerSec(450),
     .target_bitrate = DataRate::KilobitsPerSec(350),
     .min_bitrate = DataRate::KilobitsPerSec(150)},
    {.width = 320,
     .height = 180,
     .max_layers = 1,
     .max_bitrate = DataRate::KilobitsPerSec(200),
     .target_bitrate = DataRate::KilobitsPerSec(150),
     .min_bitrate = DataRate::KilobitsPerSec(30)},
    // As the resolution goes down, interpolate the target and max bitrates down
    // towards zero. The min bitrate is still limited at 30 kbps and the target
    // and the max will be capped from below accordingly.
    {.width = 0,
     .height = 0,
     .max_layers = 1,
     .max_bitrate = DataRate::KilobitsPerSec(0),
     .target_bitrate = DataRate::KilobitsPerSec(0),
     .min_bitrate = DataRate::KilobitsPerSec(30)}};
// These tables describe from which resolution we can use how many
// simulcast layers at what bitrates (maximum, target, and minimum).
// Important!! Keep this table from high resolution to low resolution.
constexpr const SimulcastFormat kSimulcastFormatsVP9[] = {
    {.width = 1920,
    .height = 1080,
    .max_layers = 3,
    .max_bitrate = DataRate::KilobitsPerSec(3367),
    .target_bitrate = DataRate::KilobitsPerSec(3367),
    .min_bitrate = DataRate::KilobitsPerSec(769)},
    {.width = 1280,
    .height = 720,
    .max_layers = 3,
    .max_bitrate = DataRate::KilobitsPerSec(1524),
    .target_bitrate = DataRate::KilobitsPerSec(1524),
    .min_bitrate = DataRate::KilobitsPerSec(481)},
    {.width = 960,
    .height = 540,
    .max_layers = 3,
    .max_bitrate = DataRate::KilobitsPerSec(879),
    .target_bitrate = DataRate::KilobitsPerSec(879),
    .min_bitrate = DataRate::KilobitsPerSec(337)},
    {.width = 640,
    .height = 360,
    .max_layers = 2,
    .max_bitrate = DataRate::KilobitsPerSec(420),
    .target_bitrate = DataRate::KilobitsPerSec(420),
    .min_bitrate = DataRate::KilobitsPerSec(193)},
    {.width = 480,
    .height = 270,
    .max_layers = 2,
    .max_bitrate = DataRate::KilobitsPerSec(257),
    .target_bitrate = DataRate::KilobitsPerSec(257),
    .min_bitrate = DataRate::KilobitsPerSec(121)},
    {.width = 320,
    .height = 180,
    .max_layers = 1,
    .max_bitrate = DataRate::KilobitsPerSec(142),
    .target_bitrate = DataRate::KilobitsPerSec(142),
    .min_bitrate = DataRate::KilobitsPerSec(30)},
    {.width = 240,
    .height = 135,
    .max_layers = 1,
    .max_bitrate = DataRate::KilobitsPerSec(101),
    .target_bitrate = DataRate::KilobitsPerSec(101),
    .min_bitrate = DataRate::KilobitsPerSec(30)},
    // As the resolution goes down, interpolate the target and max bitrates down
    // towards zero. The min bitrate is still limited at 30 kbps and the target
    // and the max will be capped from below accordingly.
    {.width = 0,
    .height = 0,
    .max_layers = 1,
    .max_bitrate = DataRate::KilobitsPerSec(0),
    .target_bitrate = DataRate::KilobitsPerSec(0),
    .min_bitrate = DataRate::KilobitsPerSec(30)}};
  • VP8 向けが H.264 と VP8 に利用されます

  • VP9 向けが VP9 と AV1 と H.265 に利用されます

https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/video/config/simulcast.cc

SDK 対応状況

以下の SDK の最新版で、配信と視聴ともに VP8 と VP9 と AV1 と H.264 と H.265 に対応済みです。

  • JavaScript SDK

  • iOS SDK

  • Android SDK

  • Unity SDK

  • C++ SDK

  • Python SDK

配信ブラウザの対応状況

配信側は Chrome と Edge と Safari の最新バージョンに対応しています。

警告

Firefox は配信に対応していません。

視聴ブラウザの対応状況

視聴側は Chrome と Safari と Firefox と Edge の最新バージョンに対応しています。

警告

Firefox は AV1 に対応していません。

映像コーデック

配信時に利用できる映像コーデックは VP8 と VP9 と AV1 と H.264 と H.265 です。

映像ビットレート

利用するコーデックと解像度に合わせてビットレートを選択してください。

  • 1080p AV1 を利用し、デフォルトのサイマルキャストの設定

    • 解像度が 1080p / 540p / 270p の 3 種類の映像を配信します

    • 指定すべきビットレートは 3367 + 879 + 257 = 4503 kbps です

    • 1080p の映像は 3367 kbps で配信され、540p の映像は 879 kbps で配信され、270p の映像は 257 kbps で配信されます

  • 720p H.264 を利用し、デフォルトのサイマルキャストの設定

    • 解像度が 720p / 360p / 180p の 3 種類の映像を配信します

    • 指定すべきビットレートは 2500 + 700 + 450 = 3650 kbps です

    • 720p の映像は 2500 kbps で配信され、360p の映像は 700 kbps で配信され、180p の映像は 450 kbps で配信されます

VP9 と AV1 でのサイマルキャスト

注意

Safari 26.0 ではまだ VP9 と AV1 のサイマルキャストに対応していません

VP9 や AV1 でサイマルキャストを行う場合、ブラウザでは配信側が Chrome 113 / Edge 113 以降である必要があります。

また設定では scalabilityModescaleResolutionDownBy または scaleResolutionDownTo のどちらかの 2 つを設定する必要があります。

詳細は scalabilityMode をご確認ください。

H.265 でのサイマルキャスト

H.265 でサイマルキャストを行う場合、 ブラウザでは配信側が Chrome 137 か Safari 18.0 以降を利用する必要があり、 視聴側も同様に Chrome 137 か Safari 18.0 以降を利用する必要があります。

非対応機能

以下は今後対応予定です

  • ULPFEC 機能には対応していません

映像の優先度

サイマルキャストでは 1 つのクライアントからの同じ映像を複数のエンコードで配信できます。

Sora では 1 つのクライアントから最大 3 種類のエンコードで映像を受信する仕組みが入っています。 この 3 種類の映像のそれぞれに r0 / r1 / r2 の 3 つの値を定義しています。 この値は rid と呼ばれています。

配信継続の優先度は r0 > r1 > r2 です。

例えば、回線が不安定だったりマシンの負荷が高かった場合、rid が r2 の映像の配信が最初に停止します。 さらに配信状況が悪化した場合は rid が r1 の映像の配信が停止します。 r0 の映像は必ず配信されます。

映像の種類のデフォルト

Sora ではサイマルキャストで配信する映像の種類にデフォルト値を設定しています。

[
  {"rid": "r0", "active": true, "scaleResolutionDownBy": 4.0, "scalabilityMode": "L1T1"},
  {"rid": "r1", "active": true, "scaleResolutionDownBy": 2.0, "scalabilityMode": "L1T1"},
  {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "scalabilityMode": "L1T1"}
]

r0

ridr0 の場合は通常の解像度と比べて、一辺 が 1/4 の解像度の映像になるように設定されています。

r1

ridr1 の場合は通常の解像度と比べて、一辺 が 1/2 の解像度の映像になるように設定されています。

r2

ridr2 の場合は通常の解像度のままの映像に設定されています。

rid: none

Sora ではシグナリング開始時、認証成功時、および API で ridnone にリクエストすることができます。 ridnone を指定した場合、視聴側に映像ストリームが配信されなくなります。

  • シグナリング開始時の simulcast_request_ridnone を指定することができます

  • 認証成功時の simulcast_request_ridnone を指定することができます

  • RequestSimulcastRid API の ridnone を指定することができます

注意

sora.confsora_conf-simulcast_encodings や認証成功時に払いだす simulcast_encodings では ridnone を指定することはできません。

視聴側の自動 rid ストリーム切り替え機能

Added in version 2025.2.0.

注意

この機能は 実験的機能 のため、正式版では仕様が変更される可能性があります。

従来の Sora では、視聴側がどの rid ストリームを受信するかは、アプリケーション側が API を利用して明示的に切り替える必要がありました。

Sora 2025.2.0 では新たに、視聴側の環境に合わせて Sora が自動的に rid ストリームを切り替えて配信する機能を追加しました。

この機能をデフォルトで有効にする場合は、 sora.confdefault_simulcast_auto_rids に、自動切り替えに利用する rid をリストで指定してください。

接続ごとに設定を指定する場合は、認証成功時に simulcast_auto_rids を指定することができます。これは sora.confdefault_simulcast_auto_rids 設定を上書きします。

simulcast_auto_ridsrid が指定されている状態で、 simulcast_request_rid で指定した rid が視聴環境の制約により利用できないと判断された場合、 Sora は自動でより低いビットレートの rid に切り替えます。

simulcast_auto_rids には、 ["r0", "r1"] のように複数の rid を指定することができます

シグナリング通知での rid 切り替えイベント

sora.confsignaling_notify_simulcast_switchedtrue に設定することで、視聴側の自動 rid 切り替えが発生した際にシグナリング通知が送信されます。

映像のエンコーディングパラメーターのカスタマイズ

Sora ではサイマルキャストで配信する映像のエンコーディングパラメーターを自由に設定できます。

  • sora.conf のファイルで指定することで全体のサイマルキャストのエンコーディングパラメーターが指定できます

  • 認証成功時に simulcast_encodings で払い出すことで個別にサイマルキャストのエンコーディングパラメーターが指定できます

sora.conf でファイル指定

sora.conf にて simulcast_encodings_file で JSON を指定してください。

simulcast_encodings_file = etc/simulcast_encodings.json

sora.conf で指定する JSON ファイルの記述方法

[
  {"rid": "r0", "active": true, "scaleResolutionDownBy": 2.0, "maxFramerate": 5.0},
  {"rid": "r1", "active": true, "scaleResolutionDownBy": 2.0, "maxFramerate": 20.0},
  {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 30.0}
]

認証成功時に simulcast_encodings で払い出す記述方法

{
  "allowed": true,
  "simulcast_encodings": [
    {"rid": "r0", "active": true, "scaleResolutionDownBy": 2.0, "maxFramerate": 5.0},
    {"rid": "r1", "active": true, "scaleResolutionDownBy": 2.0, "maxFramerate": 20.0},
    {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 30.0}
  ]
}

カスタマイズの設定

active: false の挙動

r1 の active を false にカスタマイズしている配信で r1 を受信をリクエストした場合、r0 が配信されます。

[
  {"rid": "r0", "active": true},
  {"rid": "r1", "active": false},
  {"rid": "r2", "active": true}
]

r0 の active を false にカスタマイズしている配信で r0 を受信をリクエストした場合、r1 が配信されます。

[
  {"rid": "r0", "active": false},
  {"rid": "r1", "active": true},
  {"rid": "r2", "active": true}
]

r0 と r1 の active を false にカスタマイズしている配信で r0 を受信をリクエストした場合、r2 が配信されます。

[
  {"rid": "r0", "active": false},
  {"rid": "r1", "active": false},
  {"rid": "r2", "active": true}
]

scalabilityMode

この設定は Chrome / Edge M113 以降でのみ有効です

VP9 または AV1 でサイマルキャストを利用する場合の条件として、 scalabilityModescaleResolutionDownBy または scaleResolutionDownTo のどちらかをすべての rid に対して設定する必要があります。

サイマルキャスト利用時に scalabilityMode に設定可能な値は L1T1L1T2L1T3 のみです。

デフォルトでは L1T1 が指定されています。特に理由がなければ L1T1 を利用してください。

重要

AV1 でサイマルキャストやスポットライトを利用し、録画をする場合は L1T1 を利用してください。 L1T1 以外では正常に録画がされません。

[
  {"rid": "r0", "active": true, "scaleResolutionDownBy": 4.0, "scalabilityMode": "L1T1"},
  {"rid": "r1", "active": true, "scaleResolutionDownBy": 2.0, "scalabilityMode": "L1T1"},
  {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "scalabilityMode": "L1T1"}
]

配信側の利用方法

シグナリング開始時に指定できます。

シグナリング開始時

シグナリングの "type": "connect" 時に "simulcast": true を指定することで、有効になります。 映像コーデックは VP8 または H264 を選択してください。

{
  "type": "connect":,
  "role": "sendonly",
  "channel_id": "sora",
  "video": {"codec_type": "VP8"},
  "simulcast": true
}

視聴側の利用方法

シグナリング開始時に指定できます。

シグナリング開始時

  • シグナリング "type": "connect" 時に "simulcast": true を指定することで、有効になります

  • simulcast_request_rid には none / r0 / r1 / r2 が指定できます

    • simulcast_request_rid を指定しない場合は r0 が指定されます

    • この値は サイマルキャストで配信されている映像を受信する際のデフォルト値 です

    • この値は sora.confdefault_simulcast_rid で変更できます

    • none を指定した場合、映像は配信されません

  • 映像コーデックは VP8 または H264 を選択してください

{
  "type": "connect":,
  "role": "recvonly",
  "channel_id": "sora",
  "video": {"codec_type": "VP8"},
  "simulcast": true,
  "simulcast_request_rid": "r2"
}

視聴側のストリームの変更 API

詳細は サイマルキャスト API をご確認ください

シーケンス図

        sequenceDiagram
    participant C1 as クライアント1
    participant S as WebRTC SFU Sora
    participant C2 as クライアント2
    C1->>S: "type": "connect",<br/>"role": "sendonly",<br/>"simulcast":"true"
    note over C1, S: クライアント1 WebRTC 確立
    C2->>S: "type": "connect",<br/>"role": "recvonly",<br/>"simulcast":"true",<br/>"simulcast_rid": "r1"
    note over C2, S: クライアント2 WebRTC 確立
    par
        C1-)S: 映像<br>rid: r0
    and
        C1-)S: 映像<br>rid: r1
        S-)C2: 映像<br>rid: r1
    and
        C1-)S: 映像<br>rid: r2
    end
    
© Copyright 2025, Shiguredo Inc Created using Sphinx 9.0.4