# Live コントローラー

Live コントローラーのメッセージ、イベント、音声プロトコルを使います。

Canonical: https://developer.realsee.ai/ja/docs/live/preparation/live-controller
Source: https://developer.realsee.ai/ja/docs/live/preparation/live-controller.md
Language: ja

> **tip**

メッセージ、イベント、音声の仕様を説明します。共同閲覧の構築にはコントローラーの理解が必要です。

## @realsee/live




> **info**

**Live** はブラウザー側の共同閲覧 SDK です。WebSocket は音声なしで使えます。音声が必要な場合は組み込み TRTC・Chime または独自 RTC を使います。

<span id="messaging-system" class="docs-anchor-alias" aria-hidden="true"></span>

## メッセージの仕組み

**Live** は永続 WebSocket の双方向通信で複数クライアントの共有画面を実現します。ユーザー間の通信は WebSocket メッセージに基づきます。

メッセージはキーフレーム、ブロードキャスト、ルーム情報に分かれ、それぞれ送受信 API があります。詳細は [Live API](https://unpkg.com/@realsee/live@0.7.6/docs/index.html) を参照してください。

**キーフレーム** は共有画面の同期データです。同期する情報を選び `{key: value}` にまとめます。

**ブロードキャスト** は指定ユーザーからメンバーへの独自イベントです。例えばホストが視聴者へ挨拶を送れます。

**ルーム情報** はサーバーが配信する組み込みメッセージで、ルーム状態、自分、参加ユーザー一覧を含みます。一部は Live の更新メソッドで変更できます。

<span id="keyframe-data-synchronization" class="docs-anchor-alias" aria-hidden="true"></span>

### キーフレームの同期

現在の UI 操作状態を同期します：

[Five SDK](https://developer.realsee.ai/ja/docs/five-sdk) の共有画面を例にします：

```js
// Send local keyframe data (Five State)
live.sendKeyframe("five", { panoIndex: 13 });

// Receive remote keyframe data (Five State)
live.keyframes.on("five", (newState, prevState) => {
  // You can use the latest `newState` to update the local UI state
});
```

`live.snapshot` から現在の全キーフレームのスナップショットを取得できます。

<span id="room-information" class="docs-anchor-alias" aria-hidden="true"></span>

### ルーム情報

WebSocket 接続後はルームにユーザーとして参加します。他のユーザーも参加でき、情報を次のように取得・更新できます：

```js
// Property: get the local user's information
live.selfInfo;

// Property: get the list of all users currently in the room
live.userList;

// Method: update the local user's information
live.setSelfInfo({});

// Event: the local user's information has changed
live.on("selfInfoUpdate", (userInfo) => {});

// Event: the room's user list information has changed
live.on("userListUpdate", (userList) => {});
```

<span id="broadcast-messages" class="docs-anchor-alias" aria-hidden="true"></span>

### ブロードキャスト

キーフレームやルーム情報に加え、他ユーザーへ独自イベントを送信できます：

```js
live.broadcast(
  data /* the data to broadcast */,
  ["user_id_1", "user_id_2"] /* userIds of the users who should receive this */
);
```

この例では `user_id_1` と `user_id_2` だけが受信し、他のユーザーは受信しません：

```js
live.on("broadcast", (data /* the broadcast data */) => {});
```

追加例は [Live API](https://unpkg.com/@realsee/live@0.7.6/docs/index.html) を参照してください。

<span id="event-mechanism" class="docs-anchor-alias" aria-hidden="true"></span>

## イベントの仕組み

非同期 Live イベントは `live.on('/* event name */', callback)`、任意の RTC イベントは `live.$RTC.on('/* event name */', callback)` で購読します。

例えば公開接続状態の変化を監視します：

```ts
import { LiveState } from "@realsee/live";

live.on("stateChange", (state, previousState) => {
  if (state === LiveState.OPEN) {
    console.log("Live connection opened", { previousState });
  }
});
```

<span id="connection-state" class="docs-anchor-alias" aria-hidden="true"></span>

### 接続状態

- `stateChange(state: LiveState, previousState?: LiveState): void`：公開接続状態の変化。

**WebSocket 接続状態：**

| 状態名 | 説明 |
| -------------- | ------------------ |
| NOTINITIALIZED | 未初期化 |
| CONNECTING | 接続中 |
| OPEN | 接続済み |
| CLOSED | 切断済み |

Live のフロントとバックエンドは永続 WebSocket を使います。`OPEN` と `CLOSED` が参加・退出の状態を表します。VRTC のイベント処理は `OPEN` の後に行います。

<span id="live-events" class="docs-anchor-alias" aria-hidden="true"></span>

### Live イベント

- `broadcast(evtMsg: Record<string, any>, frontRequestId: string): void`：他ユーザーからブロードキャストを受信。

- `builtinEvent(builtinMsg: BuiltinMsg): void`：サーバーの組み込みイベントを受信。

- `keyframes(keyframes: Partial<Snapshot>, frontRequestId: string): void`：他ユーザーからキーフレームを受信。

- `selfInfoUpdate(userInfo: UserInfo, frontRequestId: string): void`：自分の情報の変化。

- `userListUpdate(userList: UserInfo[], frontRequestId: string): void`：ユーザー一覧の変化。

`live.connect()`、`live.broadcast()`、`live.sendKeyframe()` などは非同期で応答し、他ユーザーにも影響します。上のイベントで変化を把握できます。

`LiveState.OPEN` がキーフレーム送信可能の状態です。初回・後続の更新は `keyframes` または `live.keyframes.on(key, callback)` で購読します。古い `readyKeyframeSync` は 0.7.6 で非推奨です。

<span id="rtc-events" class="docs-anchor-alias" aria-hidden="true"></span>

### RTC イベント

- `error(error: Error): void`：エラー。

- `initWillStart(): void`：初期化開始前。

- `inited(): void`：初期化完了。

- `joinWillStart(): void`：音声ルーム参加前。

- `joined(): void`：音声ルーム参加成功。

- `userVolumes(userVolumes: UserVolume[]): void`：発話ユーザーごとの音量。

- `weakNetwork(): void`：弱いネットワークの警告。

`live.$RTC` は RTC プロトコルを満たす必要があります。`live.$RTC.on('/*event name*/', /*event callback*/)` で購読します。発話ユーザーと音量の監視例です：

```ts
live.$RTC.on("userVolumes", (userVolumes: UserVolume[]) => {
  console.log(userVolumes); // userVolumes: the speaking users and their volume data.
});
```

<span id="error-handling" class="docs-anchor-alias" aria-hidden="true"></span>

### エラー処理

- `ws.error(error: WebSocketError): void`：WebSocket 接続エラー。

**WebSocket エラー状態：**

| エラー項目 | 説明 | 発生条件 |
| ---------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Close | [CloseEvent](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) に準拠 | 原因も CloseEvent に準拠 |
| Error            |
| MicroAuth | マイク認可エラー | 音声用のマイク認可を取得できない |
| DuplicateConnect | 重複接続 | 同じ WS リンクで接続を要求 |
| IllegalURL | 無効な WS リンク | 指定されたリンクが無効 |
| Unknown | 不明なエラー | 列挙されていないエラーをそのまま返す |

- `error(liveMsg: LiveMsg): void`：サーバー配信エラー。

WebSocket 通信の `LiveMsg` は以下の構造です：

| 名前 | 型 | 説明 |
| --------------- | --------------------- | ----------------------------------------------------------------------------------------------------- |
| appId           | string                |
| code | string | 結果コード |
| command | command | WebSocket 命令種別。[Live API](https://unpkg.com/@realsee/live@0.7.6/docs/index.html) を参照 |
| data | Record\<string, any\> | 命令に対応する業務データ |
| frontRequestId: | string | WS サーバーがそのまま返すフロント側の要求 ID |
| message | string | 結果の説明 |
| requestId | string | バックエンドの要求 ID |
| roomCode | string | 共同閲覧ルーム番号 |
| triggerUserId | string | 命令を実行したユーザーの ID |

配信データが `LiveMsg` を満たさない場合や `code` が `SUCCESS` でない場合は `error` イベントになります。

- `error(error: Error): void`：RTC 音声エラー。


> **caution**

音声エラーの内容はコンテナーや RTC の実装によって異なる場合があります。

<span id="rtc-protocol" class="docs-anchor-alias" aria-hidden="true"></span>

## RTC プロトコル

音声は任意です。0.7.6 は `BrowserRTC`、`BrowserRTC4Chime`、`VRWebViewRTC`、`RTCProtocol` を公開します。対応ブラウザーには組み込み実装、他コンテナーには独自実装を使います。[RTC と環境](https://developer.realsee.ai/ja/docs/live/rtc-and-environment) を参照してください。

Live は **jsbridge-x** でコンテナー SDK 導入済みのクライアントアプリや WeChat ミニプログラムのネイティブ機能を呼びます。このインスタンスは `createLive()` に設定として渡します。

iOS・Android アプリで Realsee VRTC コンテナー SDK を導入済みの場合：

```js
import { JSBridgeApp } from "@realsee/jsbridge-x/lib/app";
import { createLive } from "@realsee/live";
import { VRWebViewRTC } from "@realsee/live";

const jsBridge = new JSBridgeApp();

const rtcInstance = new VRWebViewRTC({
  jsBridge,
  getVoiceSign: () => {},
});

const live = createLive({
  rtc: rtcInstance,
  jsBridge,
  getTicket: async () => "",
});
```

RTC を指定すると音声の接続・切断・再接続を Live に委ねられます。`$RTC` から音声の状態とイベントを扱います。

```js
// State: whether the user has successfully joined the voice room
live.$RTC.joined;
// State: the user's microphone status
live.$RTC.micro;
// Listen for changes in user volume
live.$RTC.on("userVolumes", (userVolumes) => {});
```

