# サイマルキャストマルチコーデック機能

> **注意**
>
> この機能を利用する場合は事前にサポートまでご連絡ください

> **警告**
>
> この機能は [実験的機能](EXPERIMENTAL.html) のため、正式版では仕様が変更される可能性があります

## 概要

サイマルキャストマルチコーデックは、複数のコーデックを同時に使用して、サイマルキャストを実現する仕組みです。

## 注意

この機能は実験的機能として提供しており、かつブラウザ側の実装が未定のため、
将来的に仕様が大きく変更する可能性があります。それを踏まえてご利用ください。

不明点がある場合はサポートまでお問い合わせください。

## 制限

### ブラウザでの配信

> **重要**
>
> 2025 年 12 月 現在、ブラウザでサイマルキャストマルチコーデック機能を利用することはできません。

### ブラウザでの視聴

一部ブラウザでサイマルキャストマルチコーデックで配信された映像を視聴することはできます。
視聴時のコーデック切り替えにも対応しています。

動作が確認できているブラウザは Chrome と Edge と Safari Technology Preview です。
それ以外のブラウザでは正常に動作しない可能性があります。

### 録画機能の利用

**将来的に対応予定です**

サイマルキャストマルチコーデックが有効なクライアントでは録画機能を利用することはできません。

### 映像コーデック指定の無視

サイマルキャストマルチコーデックを指定した場合、
クライアントや認証時の払い出しでのコーデック指定は無視されます。

## 利用方法

サイマルキャストマルチコーデックを利用する

### sora.conf で simulcast_multicodec を有効にする

サイマルキャストマルチコーデック機能を利用するには `sora.conf` で [simulcast_multicodec](SORA_CONF.html#a8cf0f) を `true` に設定します。

```ini
simulcast_multicodec = true
```

### シグナリング接続時に `"simulcast": true` と `"simulcast_multicodec": true` を指定する

マルチコーデックサイマルキャストを利用するにはシグナリング接続時に `"simulcast": true` と `"simulcast_multicodec": true` を指定します。

この際、 `"video": {"codec_type": "VP8"}` などのコーデック指定は無視されます。

```javascript
{
  "type": "connect",
  "role": "sendrecv",
  "channel_id": "sora",
  "simulcast": true,
  "simulcast_multicodec": true
}
```

### サイマルキャストマルチコーデックのデフォルト値

サイマルキャストマルチコーデック用のコーデックには以下のデフォルト値が設定されています。

```javascript
[
  {"rid": "r0", "codec_type": "AV1", "codec_params": {"profile": 0}},
  {"rid": "r1", "codec_type": "AV1", "codec_params": {"profile": 0}},
  {"rid": "r2", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}}
]
```


### サイマルキャストマルチコーデックのデフォルト値を変更する

`sora.conf` の [simulcast_codecs_file](SORA_CONF.html#cc4473) でサイマルキャストマルチコーデックで利用するコーデックのデフォルトを指定することができます。

```ini
simulcast_codecs_file = etc/simulcast_codecs.json
```

```javascript
[
  {"rid": "r0", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
  {"rid": "r1", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
  {"rid": "r2", "codec_type": "H265"}
]
```

### 認証成功時の払い出しで指定する

サイマルキャストマルチコーデックを利用する場合 `simulcast` と `simulcast_multicodec` を認証成功時に払い出すことができます。

```javascript
{
  "allowed": true,
  "simulcast": true,
  "simulcast_multicodec": true
}
```

r0 と r1 に H264 、r2 に H265 を利用する場合の例です。

```javascript
{
  "allowed": true,
  "simulcast": true,
  "simulcast_multicodec": true,
  "simulcast_codecs": [
    {"rid": "r0", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
    {"rid": "r1", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
    {"rid": "r2", "codec_type": "H265"}
  ]
}
```

### simulcast_encodings の指定

サイマルキャストマルチコーデックのサイマルキャストエンコード部分は `simulcast_encodings` のデフォルト値を利用します。

そのため、サイマルキャストマルチコーデック向けに `simulcast_encodings` を指定したい場合は、
認証成功時に払い出す必要があります。

```javascript
{
  "allowed": true,
  "simulcast": true,
  "simulcast_multicodec": true,
  "simulcast_encodings": [
    {"rid": "r0", "active": true, "scaleResolutionDownBy": 4.0, "maxFramerate": 10.0},
    {"rid": "r1", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 30.0},
    {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 30.0}
  ],
  "simulcast_codecs": [
    {"rid": "r0", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
    {"rid": "r1", "codec_type": "H264", "codec_params": {"profile_level_id": "42e02a"}},
    {"rid": "r2", "codec_type": "H265"}
  ]
}
```

### type: offer 時に払い出される内容

`simulcast_encodings` と `simulcast_codecs` に指定された値から、
W3C WebRTC 準拠の [RTCRtpEncodingParameters](https://w3c.github.io/webrtc-pc/#dom-rtcrtpencodingparameters) を生成し、
`"type": "offer"` の `"encodings"` として追加します。

`"codec"` については [W3C WebRTC RTCRtpCodecParameters](https://w3c.github.io/webrtc-pc/#rtcrtpcodecparameters) と [W3C WebRTC Extension   RTCRtpEncodingParameters](https://w3c.github.io/webrtc-extensions/#rtcrtpencodingparameters) に準拠しています。

```javascript
{
  "type": "offer",
  "simulcast": true,
  "simulcast_multicodec": true,
  "encodings": [
    {
      "rid": "r0",
      "active": true,
      "scaleResolutionDownBy": 4.0,
      "maxFramerate": 10.0,
      "codec": {
        "mimeType": "video/H264",
        "clockRate": 90000,
        "sdpFmtpLine": "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e02a"
      }
    },
    {
      "rid": "r1",
      "active": true,
      "scaleResolutionDownBy": 1.0,
      "maxFramerate": 30.0,
      "codec": {
        "mimeType": "video/H264",
        "clockRate": 90000,
        "sdpFmtpLine": "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e02a"
      }
    },
    {
      "rid": "r2",
      "active": true,
      "scaleResolutionDownBy": 1.0,
      "maxFramerate": 30.0,
      "codec": {
        "mimeType": "video/H265",
        "clockRate": 90000,
        "sdpFmtpLine": "profile-id=1;level-id=93"
      }
    }
  ]
}
```
