# マルチストリーム機能

## 概要

マルチストリームとは一つの PeerConnection の中で複数の映像や音声を動的に追加したり削除したりする仕組みです。
この機能を利用することで、複数の PeerConnection を管理せずに複数の映像や音声を使用できるようになります。

## 制限

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

## ブラウザ

Chrome、Firefox、Safari、Edge と主要ブラウザすべてでマルチストリームを利用できます。

## シグナリング仕様

マルチストリームを利用する場合は、ユーザーが参加や離脱をするたびに SDP を交換する必要があります。

### "type": "connect"

マルチストリームはデフォルトで有効になっています。

```json
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora"
}
```

マルチストリームを無効にする場合は `"type": "connect"` 時に `"multistream": false` を追加します。

```json
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora",
    "multistream": false
}
```

### "type": "re-offer"

```json
{
    "type": "re-offer",
    "sdp": ".."
}
```

### "type": "re-answer"

`"type": "re-offer"` が送られてきた場合、 クライアントから Sora へ送るメッセージは `"type": "re-answer"` を送る必要があります。

```json
{
    "type": "re-answer",
    "sdp": ".."
}
```

## role

マルチストリームでは role に `sendrecv` と `sendonly` と `recvonly` を指定することができます。

- `sendrecv` は配信と視聴を行います
- `sendonly` は配信のみを行います
- `recvonly` は視聴のみを行います

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

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

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

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

そのため、マルチストリームにおける 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` に指定することで無効にできます。

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

## シーケンス図

seqdiag {
    default_fontsize = 15;
    edge_length = 250;

    activation = none;

    === クライアント1 認証成功 ===

    クライアント1 <<- Sora [label = '"type": "offer"'];
    クライアント1 ->> Sora [label = '"type": "answer"', noactivate];

    === クライアント1 WebRTC 確立 ===

    クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント1\n"type": "connection.craeted"'];

    === クライアント2 認証成功 ===

    クライアント2 <<- Sora [label = '"type": "offer"'];
    クライアント2 ->> Sora [label = '"type": "answer"', noactivate];

    クライアント1 <<- Sora [label = '"type": "re-offer"'];
    クライアント1 ->> Sora [label = '"type": "re-answer"', noactivate];

    === クライアント2 WebRTC 確立 ===

    クライアント2 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.craeted"'];

    クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.craeted"'];

    クライアント2 ->> Sora [label = '"type": "disconnect"', noactivate];
    クライアント2 <<- Sora [label = 'WebSocket Close'];

    クライアント1 <<- Sora [label = 'シグナリング通知\nクライアント2\n"type": "connection.destroyed"'];

}
