WebRTC:舊版 getStats() 遷移指南

Henrik Boström
Henrik Boström

舊版 getStats() WebRTC API 將在 Chrome 117 中移除,因此使用這項 API 的應用程式必須遷移至標準 API。本文將說明如何遷移程式碼,以及如果需要更多時間進行變更,該怎麼做。

過去,WebRTC getStats() API 有兩個競爭版本。舊版 getStats() API 是標準化程序之前的版本,會採用回呼引數,而標準化且廣泛支援的 API 則會傳回承諾。

標準 API 功能更豐富,且在 W3C 規格 WebRTC 統計資料 API 的 ID 中公開記錄了明確的指標。規格說明包含本指南列出的各項指標說明,以及其他說明。

自 Chrome 117 起,舊版 getStats() API 會在穩定版發布管道中擲回例外狀況 (例外狀況擲回作業會逐步推出)。請按照本指南的說明,輕鬆轉換至標準 API。

舊版與標準統計資料類型

如需標準統計資料類型的完整清單,請參閱規格中的 RTCStatsType 列舉。包括哪些統計資料字典定義,可說明為每種類型收集的指標。

統計資料物件都具有 id 屬性,可在多個 getStats() 呼叫中唯一識別基礎物件。每次呼叫方法時,相同的物件都會具有相同的 ID。這項功能可用於計算指標的變化率 (下一節會提供範例)。這些 ID 也會形成參照的關係。舉例來說,outbound-rtp 統計資料物件會透過 outbound-rtp.mediaSourceId 屬性參照相關聯的 media-source 統計資料物件。如果繪製所有 ...Id 關係,就會得到一張圖表。

舊版 API 有下列統計資料類型,對應的標準類型如下:


舊版類型

標準類型
ssrc
代表 RTP 串流和相關 MediaStreamTrack 的指標。


標準類型為 inbound-rtp (用於接收 RTP 串流及其相關聯的遠端 MediaStreamTrack)、outbound-rtp (用於傳送 RTP 串流) 和 media-source (用於與傳送 RTP 串流相關聯的本地 MediaStreamTrack 指標)。RTP 串流指標也包含 RTP 串流使用的編碼器或解碼器相關資訊。
VideoBwe
頻寬預估指標、目標位元率、編碼器位元率和實際位元率。這些類型的指標屬於 RTP 指標 (outbound-rtpinbound-rtp) 和 ICE 候選組合指標 (candidate-pair)。
googComponent
代表傳輸 (ICE 和 DTLS)。標準版本為 transport
localcandidate and remotecandidate
代表 ICE 候選項目。標準版本為 local-candidateremote-candidate
googCandidatePair
代表 ICE 候選項目組合,也就是本機和遠端候選項目的組合。標準版本為 candidate-pair
googCertificate
代表 DTLS 傳輸所使用的憑證。標準版本為 certificate
googLibjingleSession
代表 RTCPeerConnection。雖然內容不會對應至標準中的任何項目,但標準確實有與 RTCPeerConnection 相關聯的類型:peer-connection

舊版 API 中缺少

這些統計資料類型已新增至標準 API,但沒有任何對應的舊版類型:
  • codec:目前由 RTP 串流使用的編碼器,用於編碼或解碼。這是 SDP 中協商的編解碼器子集。
  • remote-inbound-rtp:遠端端點的傳入 RTP 串流,對應至此端點傳送的傳出 RTP 串流 (outbound-rtp)。此值是在遠端端點進行測量,並在 RTCP 接收器報表 (RR) 或 RTCP 擴充報表 (XR) 中回報。
  • remote-outbound-rtp:遠端端點的傳出 RTP 串流,對應於這個端點接收的傳入 RTP 串流 (inbound-rtp)。這項資料是在遠端端點進行測量,並在 RTCP 傳送端報告 (SR) 中回報。
  • media-playout:與傳入 RTP 串流 (inbound-rtp) 相關聯的遠端 MediaStreamTrack 播放量指標。
  • data-channel:代表 RTCDataChannel

舊版指標與標準指標的對應關係

這份對應表旨在協助開發人員找出哪些舊指標對應至哪些標準指標,但請注意,對應指標可能會使用不同的單位,或以總計計數器而非即時值表示。請參閱指標定義規格。
標準 API 會優先公開總計數器,而非費率。也就是說,如要取得與舊版 API 相同的對應速率 (例如比特率),應用程式必須計算平均速率,方法是取得兩個 getStats() 呼叫之間的差異。例如:

// Periodically (e.g. every second or every 10 seconds)...
const currReport = await pc.getStats();
// Calculate bitrate since the last getStats() call.
// Handling of undefined is omitted for clarity.
const currOutboundRtp = currReport.values().find(s => s.type == 'outbound-rtp');
const prevOutboundRtp = prevReport.get(currOutboundRtp.id);
const deltaBits = (currOutboundRtp.bytesSent - prevOutboundRtp.bytesSent) * 8;
const deltaSeconds = (currOutboundRtp.timestamp - prevOutboundRtp.timestamp) / 1000;
logBitrateMeasurement(deltaBits / deltaSeconds);
// Remember the report for next time.
prevReport = currReport;

雖然這種方式需要自行計算費率和平均值,看似是額外的步驟,但優點是可讓您取得任意時間間隔的平均值。與傳統 API 相比,減少呼叫標準 API 的頻率可帶來一些效能優勢。

舊版指標
googCertificate
標準信函
certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
舊版指標
googComponent
標準信函
transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
舊版指標
localcandidate
標準對應關係:
local-candidatecandidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (透過 candidate-pair.localCandidateId 進行逆向查詢 candidate-pair)
.portNumber local-candidate.port
.networkType local-candidate.networkType
.ipAddress local-candidate.address
.stunKeepaliveResponsesReceived candidate-pair.responsesReceived
.stunKeepaliveRttTotal candidate-pair.totalRoundTripTime
.transport local-candidate.protocol
.candidateType local-candidate.candidateType
.priority local-candidate.priority
舊版指標
remotecandidate
標準信函
remote-candidate
與上述 localcandidate 相同。 與上述 local-candidate 相同。
舊版指標
googCandidatePair
標準信函
candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(透過
candidate-pair.remoteCandidateId 查詢 remote-candidate)
.googReadable googReadable 是布林值,反映我們是否最近才遞增 candidate-pair.requestsReceivedcandidate-pair.responsesReceived
.googLocalAddress local-candidate.address
(透過
candidate-pair.localCandidateId 查詢 local-candidate)
.consentRequestsSent candidate-pair.consentRequestsSent
.googTransportType local-candidate.protocolremote-candidate.protocol 相同。
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable 是布林值,反映我們是否最近才遞增 candidate-pair.responsesReceived
.googRemoteAddress remote-candidate.address
.googRtt candidate-pair.currentRoundTripTime
.googActiveConnection 「active connection」是指目前由傳輸程序選取的候選組合,例如 candidate-pair.id == transport.selectedCandidatePairId
.packetsDiscardedOnSend candidate-pair.packetsDiscardedOnSend
.bytesReceived candidate-pair.bytesReceived
.responsesReceived candidate-pair.responsesReceived
.remoteCandidateId candidate-pair.remoteCandidateId
.localCandidateId candidate-pair.localCandidateId
.bytesSent candidate-pair.bytesSent
.packetsSent candidate-pair.packetsSent
.bytesReceived candidate-pair.bytesReceived
.bytesReceived candidate-pair.bytesReceived
舊版指標
ssrc
標準對應關係
inbound-rtpoutbound-rtpmedia-source
.audioInputLevel media-source.audioLevel。舊版指標的範圍為 [0..32768],而標準指標的範圍為 [0..1]。
.audioOutputLevel
inbound-rtp.audioLevel。舊版指標的範圍為 [0..32768],而標準指標的範圍為 [0..1]。
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier 代表本機 MediaStreamTrackinbound-rtp.trackIdentifier 代表遠端 MediaStreamTrack
.googRtt remote-inbound-rtp.roundTripTime (請參閱 outbound-rtp.remoteId)
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName 編解碼名稱是「type/subtype」MIME 類型 codec.mimeType 的子類型 (請參閱 inbound-rtp.codecIdoutbound-rtp.codecId)
.transportId inbound-rtp.transportIdoutbound-rtp.transportId
.mediaType inbound-rtp.kindoutbound-rtp.kindmedia-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergymedia-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDurationmedia-source.totalSamplesDuration
.ssrc inbound-rtp.ssrcoutbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentTypeoutbound-rtp.contentType
.googFrameWidthInput media-source.width
.googFrameHeightInput media-source.height
.googFrameRateInput media-source.framesPerSecond
.googFrameWidthSent outbound-rtp.frameWidth
.googFrameHeightSent outbound-rtp.frameHeight
.googFrameRateSent
雖然傳送 FPS 是 outbound-rtp.framesSent 的變化率,但實際上會實作為 outbound-rtp.framesPerSecond,也就是編碼 FPS。
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
inbound-rtp.framesDecoded 的變化率
.googFrameRateOutput
inbound-rtp.framesDecoded - inbound-rtp.framesDropped 的變化率
.hugeFramesSent outbound-rtp.hugeFramesSent
.qpSum

inbound-rtp.qpSumoutbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime / outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementationoutbound-rtp.encoderImplementation

.googCpuLimitedResolution
如果 outbound-rtp.qualityLimitationReason == "cpu" 為 True
.googBandwidthLimitedResolution
如果 outbound-rtp.qualityLimitationReason == "bandwidth" 為 True
.googAdaptationChanges
舊版指標會計算因 qualityLimitationReason 相關原因而變更解析度或影格速率的次數。這可以從其他指標推斷 (例如傳送解析度或影格速率與來源解析度或影格速率不同),但我們限制的時間長度 (outbound-rtp.qualityLimitationDurations) 可能比解析度或影格速率變更重新設定的頻率更有用。
.googNacksReceived inbound-rtp.nackCount
.googNacksSent inbound-rtp.nackCount
.googPlisReceived inbound-rtp.pliCount
.googPlisSent inbound-rtp.pliCount
.googFirsReceived inbound-rtp.firCount
.googFirsSent inbound-rtp.firCount
.googSecondaryDecodedRate
最近含有錯誤修正的封包比率:inbound-rtp.fecPacketsReceived - inbound-rtp.fecPacketsDiscarded
.packetsReceived inbound-rtp.packetsReceived
.googJitterBufferMs inbound-rtp.jitterBufferDelay/inbound-rtp.jitterBufferEmittedCount
.googTargetDelayMs (影片) inbound-rtp.jitterBufferTargetDelay/inbound-rtp.jitterBufferEmittedCount
.googPreferredJitterBufferMs (音訊) inbound-rtp.jitterBufferTargetDelay/inbound-rtp.jitterBufferEmittedCount
.googExpandRate
最近的隱藏樣本比率:inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate 在串流非靜音時,隱藏樣本的近期比率:(inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate 為了加快播放速度而捨棄的最近樣本比率:inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
為了減緩播放速度而合成的樣本最近的比率:inbound-rtp.insertedSamplesForDeceleration / inbound-rtp.totalSamplesReceived
.googSecondaryDiscardedRate inbound-rtp.fecPacketsDiscarded
.bytesReceived inbound-rtp.bytesReceived
s.googCurrentDelayMs inbound-rtp.jitterBufferDelay + media-playout.totalPlayoutDelay
.googDecodeMs inbound-rtp.totalDecodeTime / inbound-rtp.framesDecoded
.googTimingFrameInfo
唯一剩餘的 goog-metric。inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
舊版指標
VideoBwe
標準對應關係:
outbound-rtpcandidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate 做為即時值,或 outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded 做為平均值
.googActualEncBitrate 編碼器產生的位元組是酬載位元組,不含重傳:outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent 的變化率
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate outbound-rtp.headerBytesSent + outbound-rtp.bytesSent 的變化率 (每個 RTP 串流位元率)、candidate-pair.bytesSent (每個 ICE 候選位元率) 或 transport.bytesSent (每個傳輸位元率)
.googRetransmitBitrate outbound-rtp.retransmittedBytesSent 的變化範圍
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

標準 API 支援並發功能

如果您使用同步廣播,可能會發現即使您使用同步廣播透過三個獨立的 SSRC 傳送三個 RTP 串流,舊版 API 也只會回報單一 SSRC。

標準 API 沒有這項限制,會傳回三個 outbound-rtp 統計資料物件,每個 SSRC 一個。這表示您可以個別分析每個 RTP 串流,但也表示您必須自行匯總所有 RTP 傳送串流,才能取得所有 RTP 傳送串流的總比特率。

另一方面,透過 scalabilityMode API 設定多個空間層的 SVC 串流或 RTP 串流,仍會顯示為單一 outbound-rtp,因為這些串流會透過單一 SSRC 傳送。

如需更多時間進行遷移

當 Chrome 117 中移除舊版 API 時,使用舊版 API 會產生例外狀況。如果您無法及時遷移程式碼,以 RTCPeerConnection 回呼為基礎的 getStats() API 的來源測試可讓已註冊的網站有更多時間進行遷移。使用來源試用憑證後,舊版 getStats() API 可能會繼續使用,直到 Chrome 121 版為止。