# シグナリング設定

## 概要

Sora に接続するにはシグナリングの設定が必要です。シグナリングとは、 Sora とクライアント間で接続のネゴシエーションを行うための仕組みです。

Sora のシグナリングの詳細については Sora のドキュメント [WebSocket 経由のシグナリング](https://sora-doc.shiguredo.jp/SIGNALING)  をご確認ください。

## 必須項目

Sora に接続するには `シグナリング URL` と `チャネル ID` 、 `ロール` を指定する必要があります。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>[
    'wss://example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
);
```

## シグナリング URL


**項目**: `signalingUrls`
**型**: `List<String>`

Sora に接続するシグナリング URL をリストで指定してください。
接続先が一つの場合でもリストで指定してください。

- **URL の検証エラー**- 接続を試みた URL の構文が不正な場合、スキームが `ws` / `wss` ではない場合、またはホスト名がない場合は、 `connect()` が `ArgumentError` を投げ、残りの URL は試しません
- **接続失敗**- URL の検証に成功しても `WebSocket` 接続を確立できない場合は、次の URL を試します
  - 最後に試した URL でもタイムアウト以外の接続失敗が発生した場合は、その接続エラーを返します
- **タイムアウト**- 候補 URL への `WebSocket` 接続が `signalingCandidateTimeout` を超えた場合は、次の URL を試します
  - 最後の候補 URL がタイムアウトした場合は、 `connect()` が `StateError` を投げます

### シグナリング URL を一つだけ設定する例

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>[
    'wss://example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
);
```

### シグナリング URL を複数設定する例

```dart
final config = SoraConnectionConfig(
  // wss://1.example.com/signaling から順番に接続を試みます
  signalingUrls: <String>[
    'wss://1.example.com/signaling',
    'wss://2.example.com/signaling',
    'wss://3.example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
);
```


## チャネル ID

**項目**: `channelId`
**型**: `String`

接続する Sora のチャネル ID を文字列で指定してください。

Sora の仕様では、チャネル ID に指定できる長さは 1 バイト以上 255 バイト以下です。
SDK は空文字列だけを `ArgumentError` として検証し、長さの上限は検証しません。
上限を超える値を指定した場合の接続可否は Sora の仕様に従います。


## ロール

**項目**: `role`
**型**: `SoraRole`

Sora に接続する際のロールを指定してください。

### SoraRole.sendrecv

双方向での通信を行いたい場合は `SoraRole.sendrecv` を指定します。

### SoraRole.sendonly

音声や映像のみを配信するだけで、視聴はしない場合は `SoraRole.sendonly` を指定します。

### SoraRole.recvonly

配信はせず、音声や映像を視聴するだけの場合は `SoraRole.recvonly` を指定します。


## 音声

**項目**: `audio`
**型**: `bool?`
**デフォルト**: `null`

音声を利用するかどうかを指定します。 `null` で追加設定がない場合は `connect` メッセージの `audio` キーを省略し、 Sora のデフォルト (`true`) を適用します。

この項目はロールによって挙動が変わります。

- `SoraRole.sendrecv` と `SoraRole.sendonly` の場合は、音声を配信するかどうか
- `SoraRole.recvonly` の場合は、音声を受信するかどうか

この項目はあくまでクライアントと Sora の間で音声をやりとりするかどうかの指定であり、音声デバイスから取得した音声を送るかどうかや、
受信した音声を再生するかどうかとは別の設定です。これらは [メディアデバイス](media_device.html) と [音声の送受信](audio.html) をご確認ください。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>[
    'wss://example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  audio: true,
);
```

### 音声コーデック指定

**項目**: `audioCodecType`
**型**: `AudioCodecType?`
**デフォルト**: `null`

未指定の場合は Sora 側のデフォルトコーデックが利用されます。 Sora は音声コーデックに `AudioCodecType.opus` のみを利用するため、この項目を明示的に指定する必要はありません。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>[
    'wss://example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  audio: true,
  audioCodecType: AudioCodecType.opus,
);
```

### 音声ビットレート指定

**項目**: `audioBitRate`
**型**: `int?`
**デフォルト**: `null`

音声ビットレートは kbps 単位の整数で指定する最大ビットレートです。指定可能な範囲は 6 〜 510 kbps です。 `null` の場合は `bit_rate` を `connect` メッセージに含めず、 `Sora` 側の設定に委ねます。

値は `SoraConnectionConfig.toMap()` の実行時に検証され、範囲外の値を指定すると `RangeError` が送出されます。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  audio: true,
  audioBitRate: 32,
);

// 511 を指定すると、toMap() の実行時に RangeError が送出されます。
// config.toMap();
```

詳細は Sora の [オーディオビットレート指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#オーディオビットレート指定) をご確認ください。

### 音声ストリーミングの言語コード

**項目**: `audioStreamingLanguageCode`
**型**: `String?`
**デフォルト**: `null`

音声ストリーミングの言語コードを文字列で指定します。指定すると `connect` メッセージの `audio_streaming_language_code` に設定します。 `null` の場合はキーを送信しません。
`audio` が `false` の場合は音声を扱わないため送信しません。
Sora は指定された文字列をそのまま言語コードとして扱うため、 SDK は形式や長さを検証しません。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  audio: true,
  audioStreamingLanguageCode: 'ja-JP',
);
```

詳細は Sora の [音声ストリーミング機能](https://sora-doc.shiguredo.jp/AUDIO_STREAMING) をご確認ください。

### Opus の詳細パラメータ

**項目**: `audioOpusParamsChannels` / `audioOpusParamsMaxplaybackrate` / `audioOpusParamsMinptime` / `audioOpusParamsPtime` / `audioOpusParamsStereo` / `audioOpusParamsSpropStereo` / `audioOpusParamsUseinbandfec` / `audioOpusParamsUsedtx`

| フィールド | 型 | 説明 |
| --- | --- | --- |
| `audioOpusParamsChannels` | `int?` | Opus の `channels` (1 〜 8) |
| `audioOpusParamsMaxplaybackrate` | `int?` | Opus の `maxplaybackrate` (8000 〜 48000 Hz) |
| `audioOpusParamsMinptime` | `int?` | Opus の `minptime` (3 〜 120 ms) |
| `audioOpusParamsPtime` | `int?` | Opus の `ptime` (ms)。 Sora の仕様に範囲が定義されていないため、 SDK は範囲を検証しません |
| `audioOpusParamsStereo` | `bool?` | Opus の `stereo` |
| `audioOpusParamsSpropStereo` | `bool?` | Opus の `sprop_stereo` |
| `audioOpusParamsUseinbandfec` | `bool?` | Opus の `useinbandfec` |
| `audioOpusParamsUsedtx` | `bool?` | Opus の `usedtx` 。有効にすると録画がおかしくなります |

指定した値は `connect` メッセージの `audio.opus_params` に含まれます。 `null` の項目はキーを含めません。
`audioOpusParams` を 1 つでも指定した場合は、 `codec_type` に `OPUS` が併記されます。
`channels` / `maxplaybackrate` / `minptime` は、 `SoraConnectionConfig.toMap()` の実行時に検証され、値が範囲外の場合に `RangeError` が送出されます。

> **重要**
>
> Opus の詳細パラメータの指定は Sora の実験的機能です。利用する場合は、事前に Sora のサポートへ連絡してください。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  audio: true,
  audioOpusParamsChannels: 2,
  audioOpusParamsStereo: true,
);
```

詳細は Sora の [オーディオの Opus 設定指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#オーディオの-opus-設定指定) をご確認ください。


## 映像

**項目**: `video`
**型**: `bool?`
**デフォルト**: `null`

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  video: true,
);
```

映像を利用するかどうかを指定します。 `null` で追加設定がない場合は `connect` メッセージの `video` キーを省略し、 Sora のデフォルト (`true`) を適用します。

この項目はロールによって挙動が変わります。

- `SoraRole.sendrecv` と `SoraRole.sendonly` の場合は、映像を配信するかどうか
- `SoraRole.recvonly` の場合は、映像を受信するかどうか

この項目はあくまでクライアントと Sora の間で映像をやりとりするかどうかの指定であり、映像デバイスから取得した映像を送るかどうかや、
受信した映像を再生するかどうかとは別の設定です。これらは [メディアデバイス](media_device.html) と [映像を描画する](video_rendering.html) をご確認ください。

### 映像コーデック指定

**項目**: `videoCodecType`
**型**: `VideoCodecType?`
**デフォルト**: `null`

映像コーデックには `VideoCodecType.{vp8, vp9, av1, h264, h265}` が指定できます。未指定の場合は Sora 側で指定しているデフォルト映像コーデックが利用されます。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  video: true,
  videoCodecType: VideoCodecType.vp9,
);
```

### 映像ビットレート指定

**項目**: `videoBitRate`
**型**: `int?`
**デフォルト**: `null`

映像ビットレートは kbps 単位の整数で指定する最大ビットレートです。指定可能な範囲は 1 〜 50000 kbps です。 `null` の場合は `bit_rate` を `connect` メッセージに含めず、 Sora 側の設定が使われます。

値は `SoraConnectionConfig.toMap()` の実行時に検証され、範囲外の値を指定すると `RangeError` が送出されます。最適なビットレートは映像の内容、解像度、フレームレート、コーデックによって異なります。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  video: true,
  videoBitRate: 1500, // kbps
);
```

### コーデック固有パラメータ

コーデック毎に固有のパラメータを指定できます。

#### videoVp9Params

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  video: true,
  videoCodecType: VideoCodecType.vp9,
  videoVp9Params: <String, Object?>{
   'profileId': 1,
  },
);
```

詳細は Sora のドキュメント [ビデオの VP9 設定指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#ビデオの-vp9-設定指定) をご確認ください。

#### videoAv1Params

詳細は Sora のドキュメント [ビデオの AV1 設定指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#ビデオの-av1-設定指定) をご確認ください。

#### videoH264Params

詳細は Sora のドキュメント [ビデオの H.264 設定指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#ビデオの-h-264-設定指定) をご確認ください。

#### videoH265Params

詳細は Sora のドキュメント [ビデオの H265 設定指定](https://sora-doc.shiguredo.jp/WEBSOCKET_SIGNALING#ビデオの-h-265-設定指定) をご確認ください。


## 転送フィルター

**項目**: `forwardingFilters`
**型**: `List<Map<String, Object?>>?`
**デフォルト**: `null`

`forwardingFilters` は、 `Sora` がこの接続へ転送する音声 / 映像の条件を指定します。
Sora の仕様では `SoraRole.sendrecv` または `SoraRole.recvonly` を対象としており、 `SoraRole.sendonly` では利用できません。
SDK は role による検証を行わないため、 `SoraRole.sendonly` を指定しても `forwarding_filters` は `connect` メッセージに含まれます。

シグナリング接続時に転送フィルターを利用するには、 `Sora` の `sora.conf` で
`signaling_forwarding_filters = true` を設定する必要があります。

音声だけをこの接続へ転送する設定例は次のとおりです。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>[
    'wss://example.com/signaling',
  ],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  forwardingFilters: <Map<String, Object?>>[
    <String, Object?>{
      'action': 'allow',
      'rules': <List<List<Map<String, Object?>>>[
        <List<Map<String, Object?>>>[
          <String, Object?>{
            'field': 'kind',
            'operator': 'is_in',
            'values': <String>['audio'],
          },
        ],
      ],
    },
  ],
);
```

この例では、 `kind` が `audio` のパケットだけを許可します。
`rules` の外側のリストは OR、内側のリストは AND を表します。

`forwardingFilters` のリストに複数の `Map` を指定すると、 `connect` メッセージにも複数の転送フィルターが含まれます。
複数の転送フィルターを指定する場合は、各フィルターに `name` と `priority` を指定し、 `name` は重複させないでください。
単一のフィルターで利用できるキーと値、複数のフィルターの指定方法については、
`Sora` のドキュメント [転送フィルター機能](https://sora-doc.shiguredo.jp/FORWARDING_FILTER) と
[マルチ転送フィルター機能](https://sora-doc.shiguredo.jp/MULTI_FORWARDING_FILTER) をご確認ください。

SDK の `forwardingFilters` は、 `connect` メッセージでは `forwarding_filters` という名前になります。
SDK は `Map` のキーや値を変換、検証しません。

- `null` を指定した場合は、 `connect` メッセージに `forwarding_filters` を含めません
- 空リストを指定した場合は、 `connect` メッセージに `forwarding_filters: []` を含めます
- 1 つ以上の `Map` を指定した場合は、指定した `Map` を `forwarding_filters` の配列として含めます

空リストはキーを省略する設定とは異なりますが、この接続単位の転送フィルターは指定しません。
チャネル単位の転送フィルターを含む最終的な挙動は、 `Sora` の仕様に従います。
転送フィルターは音声 / 映像の転送だけを対象とし、 `DataChannel` を利用したメッセージングには適用されません。
また、シグナリング接続時に指定した転送フィルターは、接続したコネクションにだけ影響します。


## 認証メタデータ

**項目**: `metadata`
**型**: `Object?`
**デフォルト**: `null`

Sora に接続する際に Sora の認証ウェブフックに渡すメタデータを指定します。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  video: true,
  videoCodecType: VideoCodecType.vp9,
  metadata: <String, Object?>{
    'jwt': 'a.b.c',
  },
);
```

> **注釈**
>
> Sora の認証ウェブフックは接続単位で認証するための Sora 側の仕組みです。


## クライアント ID

**項目**: `clientId`
**型**: `String?`
**デフォルト**: `null`

Sora に接続する際に、自分の接続に任意のクライアント ID を指定することができます。


## バンドル ID

**項目**: `bundleId`
**型**: `String?`
**デフォルト**: `null`

Sora に接続する際に、自分の接続に任意のバンドル ID を指定することができます。
接続の束ね方を制御したい場合に利用します。

## サイマルキャスト

**項目**: `simulcast`
**型**: `bool?`
**デフォルト**: `null`

サイマルキャストは同一映像で複数の画質の映像を同時に配信する仕組みです。

詳細は Sora のドキュメント [サイマルキャスト機能](https://sora-doc.shiguredo.jp/SIMULCAST) をご確認ください。

### 送信側

サイマルキャストで同時に送れる映像の本数は、コーデック、解像度、ビットレートに依存しています。また仕様は WebRTC ライブラリによって異なります。

Sora の SDK で採用している WebRTC ライブラリである libwebrtc の仕様は Sora ドキュメントの [サイマルキャストの仕様](https://sora-doc.shiguredo.jp/SIMULCAST#67a936) をご確認ください。

### 視聴側

**項目**: `simulcastRequestRid`
**型**: `SimulcastRequestRid?`
**デフォルト**: `null`

`none` / `r0` / `r1` / `r2` のいずれかを指定します。 `null` の場合は `simulcast_request_rid` を `connect` メッセージに含めません。

サイマルキャストを視聴する側は接続時にどの画質の映像を受信するかを指定できます。これは接続後に Sora の HTTP API や [RPC 機能](rpc.html) を使って変更することができます。

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.recvonly,
  simulcast: true,
  simulcastRequestRid: SimulcastRequestRid.r1,
);
```

## スポットライト

**項目**: `spotlight`
**型**: `bool?`
**デフォルト**: `null`

スポットライト機能は「直近で話をしている N 人」の映像の画質を上げる機能です。スポットライト機能を有効にすると、 Sora は話者の切り替わりを検知して、直近で話をしている N 人の映像の画質を上げます。

詳細は Sora のドキュメント [スポットライト機能](https://sora-doc.shiguredo.jp/SPOTLIGHT) をご確認ください。

### スポットライトがフォーカスした際に利用する映像の ID

**項目**: `spotlightFocusRid`
**型**: `SpotlightRid?`
**デフォルト**: Sora の設定に依存

音声が一定時間以上続いた場合、その話者にスポットライトがフォーカスします。
その際に利用する映像の rid を指定します。rid は Sora 側で設定している spotlight_encodings の rid と一致させる必要があります。

> rid は `none` / `r0` / `r1` / `r2` のいずれかを指定します。

### スポットライトがアンフォーカスした際に利用する映像の ID

**項目**: `spotlightUnfocusRid`
**型**: `SpotlightRid?`
**デフォルト**: Sora の設定に依存

音声が一定時間以上続かなかったり、他の話者が話し始めた場合、スポットライトがアンフォーカスします。
その際に利用する映像の ID を指定します。ID は Sora 側で設定している spotlight_encodings の rid と一致させる必要があります。

> rid は `none` / `r0` / `r1` / `r2` のいずれかを指定します。


## シグナリング通知メタデータ

- signalingNotifyMetadata
- 型: `Object?`
- デフォルト: `null`
- シグナリング通知に含めるメタデータを指定します

## タイムアウト


### timeoutOptions

- 型: `SoraTimeoutOptions`
- 省略可能。省略時は `SoraTimeoutOptions` のデフォルト値を使用します
- WebRTC 接続ライフサイクルのタイムアウト設定です

`SoraTimeoutOptions` では次の項目を設定できます。

- `connectionTimeout` (`Duration` 、デフォルト: 30 秒): WebSocket 接続から PeerConnection 接続完了までの待機時間
- `disconnectWaitTimeout` (`Duration` 、デフォルト: 10 秒): `disconnect()` のリソース解放待機時間
- `signalingCandidateTimeout` (`Duration` 、デフォルト: 5 秒): シグナリング URL への WebSocket 接続確立時間

```dart
final config = SoraConnectionConfig(
  signalingUrls: <String>['wss://sora.example.com/signaling'],
  channelId: 'example-channel',
  role: SoraRole.sendrecv,
  timeoutOptions: SoraTimeoutOptions(
    connectionTimeout: Duration(seconds: 60),
    disconnectWaitTimeout: Duration(seconds: 15),
    signalingCandidateTimeout: Duration(seconds: 10),
  ),
);
```

詳しくは [タイムアウト機能](timeout.html) をご確認ください。
