「オンライン」と「音が出ている」の間には多くの状態がある
CVoice Stageでは、歌い手のマイクは優先的にOpusでWebRTC配信され、ルームサービスは同じ部屋のリスナーだけへ歌声を中継します。動画は各ブラウザが個別に読み込み、歌唱ルームサーバーを経由しません。接続ネゴシエーションが完了していても、公開メディアポート、受信データ、デコーダー、AudioContext、スピーカー権限のどの層でも失敗する可能性があります。
初期の状態表示は「OPUS」だけだったため、ネゴシエーション成功を再生成功と誤認しやすい状態でした。その後「OPUS公開」「RTC検出中」「OPUS有声」「PCMフォールバック」に分け、各状態名が実際に観測できる事実に対応するようにしました。
リスナーが本当に音を受信したと確認する方法
受信パケットがあるだけでは不十分です。正常にデコードされていない可能性も、デコード後がすべて無音の可能性もあります。リスナー側ではWebRTCの受信統計を定期的に読み、実際にデコードされた波形も確認します。直近に有効な音声が本当に出た場合だけ、並行再生しているPCMフォールバック経路を停止します。
このチェックでは正常な無音も理解する必要があります。歌い手が息継ぎすると波形は一時的に静かになりますが、それだけでストリーム切断と判断してはいけません。受信データが継続し、そのトラックで実音声が一度確認されていれば、システムはメインチャネル状態を維持します。パケットが来ない、デコード後の無音が続く、トラックが中断した場合は、フォールバック経路が音声を引き継ぎます。
モバイルブラウザには「ユーザー操作」という壁もある
モバイルブラウザでは、クリックなしでの音声自動再生やAudioContextの再開が禁止されることがよくあります。ルーム接続そのものが音声許可を待つ設計だと、更新後に再接続段階から進まなくなる可能性があります。一方、実際に再生するときは「動画と歌声を有効にする」のような明確なボタンを用意し、同じユーザー操作の中でメディアと音声処理を開始する必要があります。
iOSにはメディア要素の音量制御にも特有の制限があります。Stageは制御可能なメディアトラックをWeb Audioのゲインノードへ接続し、初回接続に失敗してもユーザー操作で再試行できるようにしています。一度の失敗で部屋全体のミキシングができなくなる設計にはしていません。
フォールバックのために明らかな同期ずれを許してはいけない
リアルタイム歌声と、各リスナーがローカルで読み込む動画は別々の経路を通るため、ネットワーク遅延やデバイスバッファを完全に同じにはできません。メインチャネルからフォールバックへ切り替える際も、音声は曲のタイムラインに追従し続け、動画を飛ばしてはいけません。システムは歌い手が設定した先行量と現在の経路推定を記録し、遠隔音声へ有限の遅延を加えて、2経路をできるだけ同じ時間基準に近づけます。
| 判断シグナル | 証明できること | 証明できないこと |
|---|---|---|
| シグナリング接続に成功 | 双方がネゴシエーション情報を交換できる | メディアパケット到着の証明にはならない |
| 受信パケットが増え続ける | ネットワークでメディアデータを転送中 | ブラウザが音声をデコードできた証明にはならない |
| デコード波形に有効な信号がある | メインチャネルで直近に実音声を確認 | ユーザーのスピーカー音量が適切とは保証できない |
| ユーザーが聞こえたと確認 | 現在のデバイスで完全な経路が利用可能 | 他のリスナー端末を代表しない |