# マルチストリーム

## 概要

Sora ではマルチストリームを採用しています。

マルチストリームとは一つのコネクションの中で複数の映像や音声を動的に追加したり削除したりする仕組みです。
この機能を利用することで、複数のコネクションを管理せずに複数の映像や音声、データのやりとりが利用できます。

## 制限

- 配信側は音声 1 トラック、映像 1 トラック固定です
- 動的に配信側のトラックを追加したりするマルチトラックには対応していません


## マルチストリームにおける映像ビットレート自動シェアリング機能

> **重要**
>
> ビットレート自動シェアリング機能はデフォルトで有効になっています。

**音声のビットレートには影響しません**

マルチストリームでは複数の映像を大量に受信するため、
配信側の映像ビットレートを、参加している配信者全員でシェアする機能がデフォルトで有効になっています。

そのため、マルチストリームにおける video の `bit_rate` は、
非マルチストリームの `bit_rate` とは扱いが異なります。

例えば、 `bit_rate` を 1200 と指定した場合、 2 人で配信している場合はそれぞれ配信に 600 kbps ずつ使用します。
ここに 1 人が加わり 3 人になると、 1 人 400 kbps ずつ使用して配信するようになります。

また、ここに 5 人が加わり、合計で 8 人になると、 1 人 150 kbps ずつ使用して配信するようになります。

配信の合計のビットレートを指定するのが video の `bit_rate` です。

### 同じチャネルに参加している人が異なる `bit_rate` を指定した場合

2 人が同じチャネルに参加している状態で、1 人は映像のビットレートを 500 、もう 1 人は 1000 を指定して接続しているとします。
その場合、Sora では 500 を指定した人は配信に 250 kbps を使用し、 1000 を指定した人は配信に 500 kbps を使用します。

### ビットレート自動シェアリング機能が適用されない条件

マルチストリームにおいても、以下の条件ではシェアされず、 `bit_rate` で指定した値を使います。

- スポットライトの場合
- サイマルキャストの場合

### 無効にする場合

`sora.conf` の [multistream_auto_sharing_video_bit_rate](SORA_CONF.html#93f542) を `false` に指定することで無効にできます。

> **注釈**
>
> 設定を無効にした状態で、高いビットレートの配信者が増えていく場合、
> クライアント側の転送量が増え、さらにデコードの負荷も高くなってしまいます。
> そのため配信が安定的にできなくなり、結果的にクライアント側で配信ビットレートを下げるといった挙動が発生します。
>
> 参加者が増えた場合でも高いビットレートを維持したいという状況ではない限りは設定を無効にすることは推奨しません。

## シーケンス図

```mermaid
sequenceDiagram
    autonumber
    participant C1 as クライアント1
    participant C2 as クライアント2
    participant S as Sora
    note over C1,S: クライアント1 認証成功
    S->>+C1: "type": "offer"
    C1->>-S: "type": "answer"
    note over C1,S: クライアント1 WebRTC 確立
    S->>C1: シグナリング通知<br/>クライアント1<br/>"type": "connection.created"
    note over C1,S: クライアント2 認証成功
    S->>+C2: "type": "offer"
    C2->>-S: "type": "answer"
    S->>+C1: "type": "re-offer"
    C1->>-S: "type": "re-answer"
    note over C1,S: クライアント2 WebRTC 確立
    par
        S->>C2: シグナリング通知<br/>クライアント1<br/>"type": "connection.created"
    and

        S->>C1: シグナリング通知<br/>クライアント2<br/>"type": "connection.created"
    end
    C2->>S: "type": "disconnect"
    S->>C2: WebSocket Close
    S->>C1: シグナリング通知<br/>クライアント2<br/>"type": "connection.destroyed"
```
