WebRTC 實戰 (8) —— WebRTC-Internals:專業級除錯與監控
在開發 WebRTC 應用時,你一定會遇到這些問題:「畫面為什麼變糊?」、「聲音為什麼斷斷續續?」。一般的應用日誌只能看見信令事件,媒體品質則需要搭配 chrome://webrtc-internals/ 與 RTCPeerConnection.getStats() 分析。
一、 如何開啟與使用
先開啟 chrome://webrtc-internals/,再建立 WebRTC 連線。頁面會記錄每個 RTCPeerConnection 的事件、SDP、ICE Candidate 與統計圖表。
除錯時建議保留三份資料:
- 發生問題的確切時間與使用者操作。
- WebRTC Internals 匯出的 dump。
- 應用程式的信令與連線狀態日誌。
Dump 可能包含 IP、裝置與會話資訊,分享前應先確認隱私與資料保存政策。
二、 核心標籤:關鍵監控指標
1. 統計值不能只看單一數字
| 指標 | 正確解讀 |
|---|---|
packetsLost | 累積遺失封包數,不是百分比。應比較兩次取樣的差值。 |
bytesSent / bytesReceived | 累積位元組數,可用兩次取樣差值計算實際碼率。 |
jitter | RTP 封包抵達時間的抖動估計,單位為秒。 |
jitterBufferDelay | 累積抖動緩衝延遲,需搭配 jitterBufferEmittedCount 計算平均值。 |
currentRoundTripTime | 目前 Candidate Pair 的往返時間,單位為秒。 |
frameWidth / frameHeight | 實際送出或接收的影像尺寸。 |
qualityLimitationReason | 影像品質受 bandwidth、cpu 或其他因素限制。 |
常用計算方式:
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 區分媒體流。完整監控通常還會保存 mid、ssrc、Codec、Candidate Pair 與品質限制原因,才能將數值還原成可追查的連線事件。
三、 常見問題診斷範例
- 有信令但沒有連線:檢查
iceConnectionState、connectionState,以及transport.selectedCandidatePairId指向的 Candidate Pair。 - 有連線但沒有遠端畫面:確認
ontrack是否觸發、接收端inbound-rtp.bytesReceived是否增加,以及<video>的 autoplay 狀態。 - 畫面解析度降低:檢查 outbound
frameWidth、frameHeight與qualityLimitationReason。bandwidth表示頻寬限制,cpu則偏向編碼負載。 - 聲音斷續:觀察丟包率、
jitter、平均抖動緩衝延遲與 concealed samples,並對照問題發生時間。 - 連線只能走 TURN:查看 selected pair 兩端的
candidateType。Relay 並不代表錯誤,但會增加 TURN 流量成本。
總結
掌握了 WebRTC-Internals 工具,你就能從「盲目開發」進化為能精準診斷延遲、掉包與連線失敗原因的實戰工程師。
下一章,我們將探討多人通訊的高級架構:Mesh, MCU 與 SFU。
進階挑戰
開啟兩個網頁建立通訊,使用作業系統的 Network Link Conditioner、Linux tc netem 或獨立測試網路加入延遲與丟包。每秒取樣 getStats(),畫出丟包率、碼率、RTT 與實際解析度的時間序列。
延伸閱讀與資源
- TestRTC: webrtc-internals guide
- MDN: RTCPeerConnection.getStats()