# スポットライト機能

## 概要

WebRTC SFU サーバーを利用して 20 名で会議を行う場合、各参加者は自分以外の 19 名分の音声と映像を常に受信し続ける必要があります。
また、WebRTC SFU サーバーも、常に 20 名分の音声や映像を受信し、配信し続ける必要があります。

ところが実際は 20 名の会議であっても、ひとつのトピックに対して発言している人はせいぜい 2 名から 3 名です。
また、映像も常に参加者全員のものを高画質で配信しなくとも、その時点でアクティブに発言している人の映像がクリアであれば十分というケースも多いです。

この **スポットライト機能** を利用すると、発言していない大多数の参加者の音声は配信せず、低画質の映像のみを配信できます。ある参加者が発言し始めると、自動でその参加者の音声の配信を開始し、さらにあらかじめ設定した秒数が経過すると、映像の画質も自動で高画質に切り替えることができます。

この仕組を使うことで、クライアントやサーバーの負荷を抑えながら大人数で会議できるようになります。

この機能は、発言している参加者のみの音声と高画質の映像が配信されることから、スポットライトが当たるイメージに見立てて、スポットライト機能と名付けています。

## 仕組み

開始前に、フォーカスする人数を決めます。
フォーカスする人数とは、会議の参加者のうち、最大何人分の映像を高画質で配信するかの数です。

ここではフォーカスする人数を 1 人とします。

この機能を利用した場合は、発言していない参加者の映像は低画質で配信され、音声は配信されません。

最初に A さんが発言し始めると、 A さんの映像が高画質になって配信されます。

次に B さんが発言すると、 B さんの映像が高画質になって配信されます。
このタイミングで A さんの映像は低画質になります。

その後は同じように、直近で発言した 1 人分の映像が高画質で配信され、音声も配信されます。
それ以外の参加者の映像は低画質で配信され、音声は配信されません。

このように、高画質で配信する人数を限定することで、クライアントやサーバーの負荷を抑えながら大人数での会議が実現できます。

ただし、上記のような自動切り替えでは、参加者の映像が頻繁に入れ替わると逆に負荷が高くなってしまいます。
それを抑えるため、Sora では、参加者が発言し始めるとまずは音声だけを配信し始め、映像の切り替えはしばらく時間が経ってから行うことができます。

この時、映像が切り替わる前に、先に音声を配信することをフォーカスなし音声配信と呼びます。
これにより、映像の切り替わりの有無に関わらず、短い発言、あいづちなども配信し、スムーズな会話を成立させられます。

また、音声よりも遅れて映像を切り替えることを遅延フォーカスと呼びます。
映像の切り替えを遅延させることにより、ちょっとした雑音や短い発言のたびに映像が切り替わることを抑制できます。

これらのフォーカスなし音声配信や遅延フォーカス機能を利用すれば、スポットライト機能でフォーカスする人数は 1 〜 2 人で十分です。多くても 3 人です。

## 注意

### スポットライト機能はサイマルキャスト機能を活用した機能です

デフォルトであれば解像度が VGA 以上のサイズであれば 2 つの画質の映像を配信します。

- 高画質 (r1)- 解像度の縮小比が 1 で 30 fps
- 低画質 (r0)- 解像度の縮小比が 4 で 5 fps

> **注釈**
>
> スポットライト機能はデフォルトで r2 をエンコードを行いません。

### Chrome 、 Edge 、 Safari で動作します

現時点では Chrome と Edge と Safari の最新版に対応しています。

> **注釈**
>
> Firefox ではサイマルキャスト機能ができないため、
> Firefox を利用する場合はサイマルキャスト機能を無効にして接続する必要があります。
>
> 詳細は [サイマルキャスト機能を無効にして接続する](SPOTLIGHT.html#ae2845) をご確認ください。

## サイマルキャストとの違い

サイマルキャストを利用する場合、
受信する映像の種類を切り替えるには [RequestRtpStream](DEPRECATED_API_SIMULCAST.html#6fe0b3) API を利用する必要があります。

スポットライトはこの API の切り替え部分を Sora が自動で判断します。判断には参加者の音量を利用します。

例えば、音量が閾値を下回った場合は rid は r0 、閾値を超えた場合は rid は r1 のように、他の参加者が受信する映像の rid を切り替えます。

- マルチストリームの詳細は [マルチストリーム機能](MULTISTREAM.html) をご確認ください
- サイマルキャストの詳細は [サイマルキャスト機能](SIMULCAST.html) をご確認ください

## SDK 対応状況

- 最新版の JavaScript SDK- 対応済みです
- 最新版の iOS SDK- 対応済みです
- 最新版の Android SDK- 対応済みです
- 最新版の Unity SDK- 対応済みです
- 最新版の C++ SDK- 対応済みです
- 最新版の Python SDK- 対応済みです

## スポットライト利用時の映像の種類のデフォルト

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

```javascript
[
  {"rid": "r0", "active": true, "maxFramerate":  5.0, "scaleResolutionDownBy": 4.0, "scalabilityMode": "L1T1"},
  {"rid": "r1", "active": true, "maxFramerate": 30.0, "scaleResolutionDownBy": 1.0, "scalabilityMode": "L1T1"},
  {"rid": "r2", "active": false}
]
```

### r0

rid が r0 の場合は通常の解像度から解像度(一辺) が 1/4 で、
フレームレートが 5 になるようなエンコードがされるように設定されています。

### r1

rid が r1 の場合は通常の解像度のままで、
フレームレートが 30 でエンコードがされるように設定されています。

### r2

rid が r2 の場合はエンコードがされないように設定されています。


## スポットライト利用時の映像のエンコーディングパラメーターのカスタマイズ

Sora ではスポットライトでの映像のエンコーディングパラメーターを自由に設定できます。

- `sora.conf` のファイルで指定することで全体のスポットライトのエンコーディングパラメーターが指定できます
- 認証成功時に `spotlight_encodings` で払い出すことで個別にスポットライトのエンコーディングパラメーターが指定できます

### sora.conf でファイル指定

`sora.conf` にて スポットライトの場合は [spotlight_encodings_file](SORA_CONF.html#6115fb) で JSON ファイルを指定してください。

```ini
spotlight_encodings_file = etc/spotlight_encodings.json
```

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

```javascript
[
  {"rid": "r0", "active": true, "scaleResolutionDownBy": 4.0, "maxFramerate": 5.0},
  {"rid": "r1", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 10.0},
  {"rid": "r2", "active": true, "scaleResolutionDownBy": 1.0, "maxFramerate": 30.0}
]
```

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

```javascript
{
  "allowed": true,
  "spotlight_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}
  ]
}
```

### カスタマイズの設定

スポットライトでの映像のエンコーディングパラメーターのカスタマイズの設定方法はサイマルキャスト機能と同様です。

サイマルキャスト機能の [カスタマイズの設定](SIMULCAST.html#439977) をご確認ください。

## フォーカスする配信数

フォーカスする配信数はチャネル ID ごとに 1 から 8 までのいずれかを選択できます。
同一チャネル ID へ接続しているクライアント全てが同じ値を指定する必要があります。

デフォルトのフォーカス数は 1 です。

`sora.conf` の [default_spotlight_number](SORA_CONF.html#41c42b) でデフォルトの値を変更することができます。

> **注釈**
>
> 遅延フォーカスやフォーカスなしでの音声配信を有効にしていればフォーカス数は 1 で十分です。

フォーカスする配信数を途中で変更するには [ChangeSpotlightNumber](API_SPOTLIGHT.html#17e930) API を利用してください。

### シグナリング接続時の指定

> **警告**
>
> この機能は非推奨です。
> セッションウェブフック [session.created](SESSION_WEBHOOK.html#1d1984) の払い出しを利用してください。

シグナリング接続時に `spotlight_number` を指定することで、フォーカスする配信数を指定することができます。

そのチャネルのセッションが存在しない状態で、一番最初に接続したクライアントの `spotlight_number` が適用されます。
未指定であれば `sora.conf` の [default_spotlight_number](SORA_CONF.html#41c42b) の値が適用されます。

この値は [default_spotlight_number](SORA_CONF.html#41c42b) の値を上書きします。

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

> **警告**
>
> この機能は非推奨です。
> セッションウェブフック [session.created](SESSION_WEBHOOK.html#1d1984) の払い出しを利用してください。

認証ウェブフック成功時の払い出しに `spotlight_number` を指定することで、フォーカスする配信数を指定することができます。

この値は [default_spotlight_number](SORA_CONF.html#41c42b) やシグナリング接続時の値を上書きします。

### セッション生成時の払い出し指定

セッションウェブフック [session.created](SESSION_WEBHOOK.html#1d1984) の払い出しに `spotlight_number` を指定することで、
フォーカスする配信数を指定することができます。

この値は [default_spotlight_number](SORA_CONF.html#41c42b) やシグナリング接続時、認証成功時の払い出しの値を上書きします。

## 遅延フォーカス

ちょっとした物音でフォーカスをしないようにするため、フォーカスを遅延させる機能です。
この機能を有効にした場合、フォーカスされる場合に一定時間以上、音が出続けている必要があります。

### [sora_conf-default_spotlight_delayed_focus](SPOTLIGHT.html#da30b6)

`sora.conf` で遅延フォーカスを有効にするかどうかを指定してください。デフォルトで `true` です。

### [sora_conf-default_spotlight_delayed_focus_interval](SPOTLIGHT.html#a5df3b)

`sora.conf` でフォーカスを遅延させる時間を指定してください。デフォルトは `2000 ms` です。

## 遅延アンフォーカス

スポットライトの数が少ないときに、フォーカスの奪い合いが発生しないように、フォーカスが発生してからアンフォーカスするまで遅延させる機能です。

### [sora_conf-default_spotlight_focus_min_interval](SPOTLIGHT.html#9ba866)

`sora.conf` でフォーカスしてからアンフォーカスされるまでの最低時間間隔を指定します。デフォルトは `2000 ms` です。

## フォーカスなし音声配信

フォーカスがない状態でも音声を配信するかを指定する機能です。
この機能を有効にすると、フォーカスが他の配信者にとられても音声を配信し続けます。

配信するレートの上限も指定できます。

### [sora_conf-default_spotlight_unfocus_audio](SPOTLIGHT.html#3bd7f7)

`sora.conf` でフォーカスなし音声を有効にするかどうかを指定してください。デフォルトで `true` です。

### [sora_conf-default_spotlight_unfocus_audio_rate_limit](SPOTLIGHT.html#27c5ad)

`sora.conf` でフォーカスなし音声を配信する上限レートを指定してください。デフォルトは `2` です。

レートの単位は `1 音声ストリーム = 50 packets / s` です。

## 自動アンフォーカス

無音状態が一定時間続くとフォーカスを自動で外す機能です。この機能を利用するとフォーカス数が 0 になることもあります。

クライアントが受信するパケット、Sora が配信するパケットを減らすことができます。

### [sora_conf-default_spotlight_auto_unfocus](SPOTLIGHT.html#d57acb)

`sora.conf` で音がない場合に自動でアンフォーカスするかどうかを指定してください。デフォルトは `true` です。

### [sora_conf-default_spotlight_auto_unfocus_interval](SPOTLIGHT.html#fcf07a)

`sora.conf` で自動でアンフォーカスする無音時間を指定してください。デフォルトは `10 s` です。


## サイマルキャスト機能を無効にして接続する

> **注釈**
>
> サイマルキャストを無効にして接続すると常にフォーカスされ続けます。

スポットライト機能でサイマルキャスト機能を無効にして利用できます。

無効にする場合はシグナリング接続時または認証成功時に `"simulcast": "false"` を指定する必要があります。

サイマルキャスト機能を無効にしてスポットライトを利用した場合、
そのクライアントは常にフォーカスされている状態となります。
そのため `spotlight_focus_rid` や `spotlight_unfocus_rid` の影響も受けません。

サイマルキャスト機能を無効にした利用は、
画面共有やサイマルキャストが利用できないクライアントでの利用を想定しています。

## シグナリング

- シグナリングの `"type": "connect"` で `spotlight` を `true` に設定してください- これは必須です
- シグナリングの `"type": "connect"` で  `simulcast` を設定してください- これはオプションです
  - サイマルキャストを無効にする場合は [サイマルキャスト機能を無効にして接続する](SPOTLIGHT.html#ae2845) をご確認ください
- シグナリングの `"type": "connect"` で `spotlight_number` で 1..8 の値を指定してください- 1 から 3 の間がお勧めです
  - これはオプションです

その他の項目は [シグナリング](SIGNALING.html) を参照ください。以下に シグナリング `"type": "connect"` の例を示します。

### "type": "connect"

#### simulcast: false

サイマルキャスト無効。

```javascript
{
  "type": "connect",
  "channel_id": "sora",
  "role": "sendrecv",
  "spotlight": true,
  "simulcast": false,
  "video": {
    "codec_type": "VP8",
    "bit_rate": 800
  }
}
```

#### spotlight_number

> **重要**
>
> `spotlight_number` は同一セッションで同じ値を指定する必要があります。

`spotlight_number` はセッションウェブフック [session.created](SESSION_WEBHOOK.html#1d1984) の戻り値で指定することをお勧めします。

フォーカス数はデフォルトの 1

```javascript
{
  "type": "connect",
  "channel_id": "sora",
  "role": "sendrecv",
  "spotlight": true,
  "simulcast": true,
  "video": {
    "codec_type": "VP8",
    "bit_rate": 800
  }
}
```

フォーカス数は指定した値の 5

```javascript
{
  "type": "connect",
  "channel_id": "sora",
  "role": "sendrecv",
  "spotlight": true,
  "spotlight_number": 5,
  "simulcast": true,
  "video": {
    "codec_type": "VP8",
    "bit_rate": 800
  }
}
```

#### spotlight_focus_rid / spotlight_unfocus_rid

シグナリング接続時、認証成功時にフォーカスした場合とフォーカスしていない場合に受信する映像の rid を接続ごとに指定できます。

例えば、映像は特に受け取らなくていい場合は、両方の設定で none を指定することで参加者全員の映像を受信しなくなります。

また、話している人は rid は r1 で受信し、それ以外は受信しない (rid に none を指定) といった設定もできます。

```javascript
{
  "type": "connect",
  "channel_id": "sora",
  "role": "sendrecv",
  "spotlight": true,
  "spotlight_focus_rid": "r0",
  "spotlight_unfocus_rid": "none",
  "simulcast": true,
  "video": {
    "codec_type": "VP8",
    "bit_rate": 800
  }
}
```

`sora.conf` で [default_spotlight_focus_rid](SORA_CONF.html#c71c97) と [default_spotlight_unfocus_rid](SORA_CONF.html#a7cd9b) を指定することで、個別ではなくサーバー全体の設定もできます。

## シグナリング通知

シグナリング通知の詳細は [スポットライト機能のシグナリング通知](SIGNALING_NOTIFY.html#dcfbb9) をご確認ください。

フォーカスされたタイミングとフォーカスが外れたタイミングでシグナリング通知をクライアントに送ります。
クライアントはこの通知を利用することで、配信が切り替わったことを知ることができるようになります。

## セッションウェブフック

セッションウェブフック [session.created](SESSION_WEBHOOK.html#1d1984) の払い出しで `spotlight_number` を指定することができます。
この値はセッション単位で適用され、シグナリング接続時や認証成功時の払い出しの値を上書きします。

この `spotlight_number` の値を変更するには [ChangeSpotlightNumber](API_SPOTLIGHT.html#17e930) API を利用してください。

## イベントウェブフック

フォーカスされたタイミングとフォーカスが外れたタイミングでウェブフックリクエストが送信されます。

`sora.conf` の [ignore_spotlight_changed_webhook](SORA_CONF.html#7f5ed5) で指定できます。
デフォルトではイベントウェブフックのリクエスト送信は無効になっています。

- [spotlight.focused](EVENT_WEBHOOK.html#d79712) イベントウェブフック
- [spotlight.unfocused](EVENT_WEBHOOK.html#41715c) イベントウェブフック

## API

API の詳細は [スポットライト API](API_SPOTLIGHT.html) をご確認ください。

- [FocusSpotlightFixed](API_SPOTLIGHT.html#beaf88) API- 特定のクライアントにフォーカスし続ける API
- [FocusSpotlight](API_SPOTLIGHT.html#90a256) API- 特定のクライアントにフォーカスする API
- [UnfocusSpotlight](API_SPOTLIGHT.html#1390bc) API- 特定のクライアントからアンフォーカスする API
- [ChangeSpotlightNumber](API_SPOTLIGHT.html#17e930) API- フォーカスする数を変更する API
- [RequestSpotlightRid](API_SPOTLIGHT.html#5c2650) API- 特定のクライアントのフォーカス/アンフォーカス時の rid を変更する API
- [ResetSpotlightRid](API_SPOTLIGHT.html#680344) API- 特定のクライアントのフォーカス/アンフォーカス時の rid をリセットする API
- [BatchRequestSpotlightRid](API_SPOTLIGHT.html#a2e06c) API- フォーカス/アンフォーカス時の rid を一括で変更する API

## シーケンス図

```mermaid
sequenceDiagram
    participant C1 as クライアント1
    participant S as WebRTC SFU Sora
    participant C2 as クライアント2
    C1->>S: "type": "connect",<br/>"role": "sendrecv"<br/>"spotlight": true,<br/>"simulcast": true
    note over C1,S: クライアント1 WebRTC 確立
    par
        C1-)S: 映像<br/>rid: r0
    and
        C1-)S: 映像<br/>rid: r1
    end
    C2->>S: "type": "connect",<br/>"role": "sendrecv"<br/>"spotlight": true,<br/>"simulcast": true
    note over C2,S: クライアント2 WebRTC 確立
    par
        C2-)S: 映像<br/>rid: r0
    and
        C2-)S: 映像<br/>rid: r1
    end
    par
        S-)C2: クライアント1映像<br/>rid: r0
    and
        S-)C1: クライアント2映像<br/>rid: r0
    end
    note over C1: クライアント1が話し始める
    S-)C2: クライアント1音声
    note over C1: しゃべり初めて 2 秒経過
    note right of S: r0 の代わりに r1 映像を配信
    S-)C2: クライアント1映像<br/>rid: r1
```
