連線成功卻聽不到歌聲:即時音訊備援實務

即時通訊介面顯示「已連線」,只代表信令或傳輸協商已完成;真正的聲音還要經過資料抵達、解碼、瀏覽器播放與使用者裝置輸出。

「連線中」與「有聲音」之間隔著多層狀態

CVoice Stage 中,歌手的麥克風會優先以 Opus 透過 WebRTC 發布,房間服務只把歌聲轉送給同一房間的聽眾;影片則由每個瀏覽器自行載入,不經歌房伺服器。即使連線協商已完成,公網媒體連接埠、入站資料、解碼器、音訊內容與喇叭權限仍可能在任何一層失敗。

早期狀態只顯示「OPUS」,很容易把協商成功誤認為播放成功。後來拆成「OPUS 發布」「RTC 偵測中」「OPUS 有聲」與「PCM 備援」,讓狀態描述對應到真正可觀察的事實。

如何證明聽眾真的收到聲音

只看到入站資料封包還不夠:封包可能沒有正常解碼,也可能解碼後全部是靜音。聽眾端會定期讀取 WebRTC 入站統計,並進一步觀察實際解碼後的波形。只有最近真的出現有效聲音時,才會停止並行播放的 PCM 備援通道。

這項檢查也必須理解正常停頓。歌手換氣時波形短暫安靜,不該立刻判定串流中斷;只要入站資料仍持續,而且該音軌已驗證過確實有聲,系統就會保留主通道狀態。若沒有封包、持續解碼為靜音或音軌中斷,備援通道則會繼續承擔聲音。

行動瀏覽器還有「使用者手勢」這一關

手機瀏覽器經常禁止網頁在沒有點擊操作時自動播放聲音或恢復音訊內容。房間連線不應等待音訊授權,否則重新整理後可能永遠卡在重新連線階段;但真正要播放時,需要提供明確的「啟用影片與歌聲」按鈕,在同一次使用者操作中啟動媒體與音訊處理。

iOS 對媒體元素的音量控制也有特殊限制。Stage 會把可控制的媒體音軌接到 Web Audio 增益節點,若第一次接入失敗,也允許透過使用者手勢再次嘗試,而不是讓一次失敗導致整個房間都無法混音。

備援不能以明顯不同步為代價

即時歌聲與每位聽眾在本機載入的影片來自不同鏈路,網路延遲與裝置緩衝不可能完全一致。主通道切換到備援通道時,聲音要繼續跟著歌曲時間軸走,影片不應跳格。系統會記錄歌手設定的提前量與目前鏈路估計,替遠端聲音增加有限延遲,讓兩條路徑盡量靠近同一個時間參考。

判斷訊號它能證明什麼不能證明什麼
信令連線成功雙方可以交換協商資訊不能證明媒體封包已抵達
入站封包持續增加網路正在傳輸媒體資料不能證明瀏覽器已解碼出聲音
解碼後的波形出現有效訊號主要通道最近確實有聲不能保證使用者的喇叭音量適當
使用者確認聽見完整鏈路在目前裝置可用不能代表其他聽眾的裝置
這次實務的核心可靠的系統不應把內部狀態名稱當成成功證據。每一層都要尋找盡可能貼近使用者實際結果的可觀察訊號。