跳至主要內容
Skip to content

WebRTC 實戰 (8) —— WebRTC-Internals:專業級除錯與監控

在開發 WebRTC 應用時,你一定會遇到這些問題:「畫面為什麼變糊?」、「聲音為什麼斷斷續續?」。一般的應用日誌只能看見信令事件,媒體品質則需要搭配 chrome://webrtc-internals/RTCPeerConnection.getStats() 分析。


一、 如何開啟與使用

先開啟 chrome://webrtc-internals/,再建立 WebRTC 連線。頁面會記錄每個 RTCPeerConnection 的事件、SDP、ICE Candidate 與統計圖表。

除錯時建議保留三份資料:

  1. 發生問題的確切時間與使用者操作。
  2. WebRTC Internals 匯出的 dump。
  3. 應用程式的信令與連線狀態日誌。

Dump 可能包含 IP、裝置與會話資訊,分享前應先確認隱私與資料保存政策。


二、 核心標籤:關鍵監控指標

1. 統計值不能只看單一數字

指標正確解讀
packetsLost累積遺失封包數,不是百分比。應比較兩次取樣的差值。
bytesSent / bytesReceived累積位元組數,可用兩次取樣差值計算實際碼率。
jitterRTP 封包抵達時間的抖動估計,單位為秒。
jitterBufferDelay累積抖動緩衝延遲,需搭配 jitterBufferEmittedCount 計算平均值。
currentRoundTripTime目前 Candidate Pair 的往返時間,單位為秒。
frameWidth / frameHeight實際送出或接收的影像尺寸。
qualityLimitationReason影像品質受 bandwidthcpu 或其他因素限制。

常用計算方式:

text
丟包率 = ΔpacketsLost / (ΔpacketsReceived + ΔpacketsLost)
碼率   = 8 × Δbytes / Δtime
平均抖動緩衝延遲 = ΔjitterBufferDelay / ΔjitterBufferEmittedCount

所有累積計數都應以固定週期取樣後計算差值,不能直接拿頁面上的總數判斷當下品質。

2. 用 getStats() 建立產品內監控

WebRTC Internals 適合人工除錯;正式產品應定期取樣 getStats(),將必要欄位整理成自己的品質事件:

javascript
const previousById = new Map();

async function sampleInboundVideo(pc) {
  const reports = await pc.getStats();

  for (const report of reports.values()) {
    if (report.type !== "inbound-rtp" || report.kind !== "video") continue;

    const previous = previousById.get(report.id);

    if (previous) {
      const received = report.packetsReceived - previous.packetsReceived;
      const lost = Math.max(0, report.packetsLost - previous.packetsLost);
      const total = received + lost;
      const elapsedSeconds = (report.timestamp - previous.timestamp) / 1000;
      const receivedBytes = report.bytesReceived - previous.bytesReceived;

      console.log({
        packetLossRate: total > 0 ? lost / total : 0,
        bitrate: elapsedSeconds > 0
          ? (receivedBytes * 8) / elapsedSeconds
          : 0,
        framesDropped: report.framesDropped,
        frameWidth: report.frameWidth,
        frameHeight: report.frameHeight,
      });
    }

    previousById.set(report.id, report);
  }
}

範例以 report ID 區分媒體流。完整監控通常還會保存 midssrc、Codec、Candidate Pair 與品質限制原因,才能將數值還原成可追查的連線事件。


三、 常見問題診斷範例

  1. 有信令但沒有連線:檢查 iceConnectionStateconnectionState,以及 transport.selectedCandidatePairId 指向的 Candidate Pair。
  2. 有連線但沒有遠端畫面:確認 ontrack 是否觸發、接收端 inbound-rtp.bytesReceived 是否增加,以及 <video> 的 autoplay 狀態。
  3. 畫面解析度降低:檢查 outbound frameWidthframeHeightqualityLimitationReasonbandwidth 表示頻寬限制,cpu 則偏向編碼負載。
  4. 聲音斷續:觀察丟包率、jitter、平均抖動緩衝延遲與 concealed samples,並對照問題發生時間。
  5. 連線只能走 TURN:查看 selected pair 兩端的 candidateType。Relay 並不代表錯誤,但會增加 TURN 流量成本。

總結

掌握了 WebRTC-Internals 工具,你就能從「盲目開發」進化為能精準診斷延遲、掉包與連線失敗原因的實戰工程師。

下一章,我們將探討多人通訊的高級架構:Mesh, MCU 與 SFU。


進階挑戰

開啟兩個網頁建立通訊,使用作業系統的 Network Link Conditioner、Linux tc netem 或獨立測試網路加入延遲與丟包。每秒取樣 getStats(),畫出丟包率、碼率、RTT 與實際解析度的時間序列。


延伸閱讀與資源

← 上一章:信令機制的正式封裝 | 返回專題首頁 | 下一章:多人通訊架構概論