ライブ配信イベント (AGORA_V4) 仕様
イベントの RTC SDK 設定が AGORA_V4 のイベントを、ここでは「ライブ配信イベント」と呼ぶ。
AGORA_V4 は音声接続の方式を決める設定である。観戦者を発話できない audience として接続する代わりに、観戦者数の上限を 10 人から 1000 人へ引き上げる。
音声接続
Agora の channel profile に live broadcasting を指定し、役割によって接続ロールを分ける。
| 役割 | 接続ロール | 発話 | 音声の受信 |
|---|---|---|---|
| プレイヤー (ホスト含む) | broadcaster | できる | できる |
| 観戦者 | audience | できない | できる |
音質設定 (audio profile / scenario) は AGORA_V2 と同一で、channel profile だけが異なる。
AGORA_V2 は communication モードのため、観戦者は初期状態がミュートというだけで、解除すれば発話できる。ライブ配信イベントの観戦者は接続ロールの制約で発話できない。
設定できる経路
AGORA_V4 を設定できるのは UZU ADMIN の 2 箇所だけ。
- イベント作成モーダルの「RTC SDK」で
AGORA_V4を選ぶ - 既存イベントのイベント詳細で「RTC SDK」を
AGORA_V4に切り替える
アプリからの立卓では RTC SDK は RtcEngineConfigs の比率で抽選され、AGORA_V2 か AGORA になる。AGORA_V4 にはならない。
AGORA_V2 との差分
AGORA_V4 のときだけ変わるのは次の 6 項目。観戦料・チケット・ブロック・二重予約・観戦のキャンセルと返金・観戦者チャットなど、これ以外は AGORA_V2 と同じ処理を通る。
| 項目 | AGORA_V2 | AGORA_V4 |
|---|---|---|
| 観戦者数の上限 | 10 人 | 1000 人 |
| 観戦者のマイク | 初期ミュート。解除すれば発話できる | 発話できない。マイクボタンは無効表示 (v2 プレイ画面) または非表示 (UZU Code プレイ画面) |
| 観戦者のアイコン一覧 | 表示 | 非表示。代わりに観戦者数を出す |
| ホストによる観戦者の招待 | できる | できない。UI を出さず、サーバーも「このイベントでは観戦者を招待できません」で拒否する |
| ホストによる観戦者のキック | メンバー管理からできる | 導線なし (観戦者一覧が出ないため) |
| 観戦参加時の参加者への通知 | 送る | 送らない |
観戦者数の上限
上限はイベント単位で、次の 3 箇所に効く。
- 観戦参加時の満員判定
- イベント詳細の「観戦する」ボタンを満員で無効にする判定
- UZU ADMIN のイベント作成で観戦者を事前登録するときの件数
観戦に入れるかどうかの判定そのものは AGORA_V2 と共通で、観戦参加仕様 にまとめている。
アイコン一覧を非表示にする箇所
| 画面 | 非表示になるもの | 代わりに出すもの |
|---|---|---|
| イベントカード (募集中イベント一覧) | 観戦者数 | なし |
| イベント詳細の観戦者欄 | 観戦者一覧 | 自分が観戦者ならそのアイコン、および観戦者数 (人数の表記) |
| プレイ前 / v2 感想戦の下部バー | 観戦者名の羅列 | 観戦者数。自分が観戦者なら自分の名前も出す (人数の表記) |
| プレイ前 / v2 感想戦のボトムシートの観戦者セクション | 自分以外のアイコン | セクション見出しに観戦者数 (人数の表記) |
| v2 プレイ中のフッター | 観戦者名の羅列 | 観戦者数。自分が観戦者なら自分の名前も出す (人数の表記) |
| メンバー管理 | 観戦者一覧、観戦者の招待 | なし |
| 共有画面 | 観戦者の追加ボタン | なし |
| web のイベントページ / シナリオページの募集中イベント | 観戦者一覧、観戦者数 | なし |
観戦者数は GraphQL の Event.spectatorsCount / Event.watchingSpectatorsCount で引く。AGORA_V4 の event subscription は 配信量を抑えるため spectators を requester 自身に絞って eager-load するので、 配信された spectators の件数は観戦者数として使えない。
数える対象は画面によって違うので、フィールドを 2 つに分けている。
| 画面 | フィールド | 数える観戦者 |
|---|---|---|
| イベント詳細の観戦者欄 | Event.spectatorsCount | キャンセルしていない観戦者すべて。予約だけの観戦者も含む |
| プレイ画面 (下部バー・フッター・観戦者セクション) | Event.watchingSpectatorsCount | いま観戦中 (isWatching) の観戦者だけ |
観戦者は予約した時点では is_watching = false で、プレイ画面に入室して初めて観戦中になる。 そのため開始前のイベント詳細で観戦中だけを数えると予約者が何人いても 0 人になり、 逆にプレイ中に予約者まで数えると「◯◯人が観戦中」が実際に見ている人数より多く出る。
人数の表記
自分が観戦者のときは自分をアイコンか名前で出し、人数は自分以外だけを「+」付きで出す。 自分以外が 0 人なら人数を出さない。自分が観戦者でないときは「+」を付けずに全員の人数を出す。 ただしボトムシートの観戦者セクション見出しだけは、「+」を付けずに自分を含めた人数を出す。
例は自分のニックネームを「おき」としたもの。
| 画面 | 自分が観戦者・自分以外が 3 人 | 観戦者が自分だけ | 自分が観戦者でない・3 人 | 観戦者が 0 人 |
|---|---|---|---|---|
| イベント詳細の観戦者欄 | [自分のアイコン] +3人 | [自分のアイコン] | 3人 | 人数を出さない |
| プレイ前 / v2 感想戦の下部バー | 観戦者:おき+3人 | 観戦者:おき | 観戦者:3人 | 観戦者はいません |
| プレイ前 / v2 感想戦のボトムシートの観戦者セクション見出し | 観戦者 4人 | 観戦者 1人 | 観戦者 3人 | 観戦者 |
| v2 プレイ中のフッター | おき+3人が観戦中 | おきが観戦中 | 3人が観戦中 | 観戦者はいません |
イベント詳細で「自分」を判定するときは、配信された spectators (requester 自身だけ) の有無を使う。 プレイ画面で「自分」を判定するときも isWatching で絞った spectators を使う。 currentSpectatorProvider は観戦をやめた自分も返すため、watchingSpectatorsCount - 1 がずれる。
AGORA_V4 に対応していないアプリ
mobile 6.28.7 以前は AGORA_V4 を解釈できず、未知の RTC SDK として AGORA_V2 にフォールバックして接続する。
- 観戦者は audience にならないため、ミュートを解除すれば発話できる
- 観戦者のアイコン一覧は
AGORA_V2と同じく表示される - 観戦者数の上限はサーバーが判定するので 1000 人のまま変わらない
実装の参照先
| 内容 | ファイル |
|---|---|
| 観戦者数の上限の定数 (10 / 1000) | backend/internal/entities/event.go |
AGORA_V4 判定の述語 | backend/internal/usecase/event_rtc_sdk.go |
| イベントごとの観戦者数の上限 | backend/internal/adapters/graph/event_spectator_limit_helper.go |
| 立卓時の RTC SDK 決定 | backend/internal/usecase/event.go の RtcEngineConfigs |
| 観戦参加時の満員判定 | backend/internal/adapters/graph/spectator_join_event.resolvers.go |
| 「観戦する」ボタンの無効理由 | backend/internal/adapters/graph/event.resolvers.go の NonWatchableReason |
| 観戦者招待の拒否 | backend/internal/adapters/graph/spectator_invite_spectators.resolvers.go |
| 観戦参加通知の抑止 | backend/internal/usecase/notification.go の SendSpectatorJoinNotification |
| UZU ADMIN のイベント作成 (観戦者の事前登録) | backend/internal/adapters/graph/event_create_event_with_participant.resolvers.go |
| UZU ADMIN からの RTC SDK 切り替え | backend/internal/adapters/graph/event_update_event_rtc_sdk.resolvers.go |
| UZU ADMIN の作成モーダル / 切り替え UI | javascript/apps/admin/src/app/events/_components/create-event-modal.tsx, javascript/apps/admin/src/app/events/[id]/_components/rtcSdk.tsx |
| mobile の観戦者 UI 非表示判定 | dart/apps/mobile/lib/helpers/graphql_enum_helper.dart の hidesSpectatorUi |
| 観戦者数の解決 | backend/internal/adapters/graph/event.resolvers.go の SpectatorsCount |
subscription での spectators 絞り込み | backend/internal/adapters/graph/event_spectators_helper.go |
| mobile の観戦者マイク無効判定 | dart/apps/mobile/lib/views/pages/play_screen/provider.dart の isAudienceMicUnavailableProvider |
| mobile の live broadcasting 接続とフォールバック | dart/apps/mobile/lib/views/pages/play_screen/voice/rtc_engine/agora_v4.dart, 同 initializer.dart |
| web の観戦者 UI 非表示判定 | javascript/apps/web/src/utils/rtcSdk.ts |