舊版 getStats()
WebRTC API 將在 Chrome 117 版中移除,因此使用這組 API 的應用程式需遷移至標準 API。本文將說明如何遷移程式碼,以及需要更多時間變更這項設定時應採取的行動。
在過去,WebRTC getStats()
API 有兩個競爭版本。舊版 getStats() API 會預先處理標準化程序並使用回呼引數,以及傳回承諾且廣泛支援的 API。
標準 API 提供更豐富的功能,且已在 W3C 規格 WebRTC 的 Statistics 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-rtp 和 inbound-rtp ) 和 ICE 候選組合指標 (candidate-pair ) 的一部分。 |
googComponent
|
代表傳輸 (ICE 和 DTLS)。標準版為 transport 。 |
localcandidate and remotecandidate
|
代表 ICE 候選人。標準版為 local-candidate 和 remote-candidate 。 |
googCandidatePair
|
代表 ICE 候選人組合,代表本機與遠端候選人的配對。標準版為 candidate-pair 。 |
googCertificate
|
代表 DTLS 傳輸使用的憑證。標準版為 certificate 。 |
googLibjingleSession
|
代表 RTCPeerConnection 。雖然其內容未對應至標準中的任何項目,但標準確實有與 RTCPeerConnection 相關聯的類型:peer-connection 。 |
舊版 API 缺少 |
下列統計資料類型已新增至標準 API,沒有任何對應的舊版類型:
|
從舊版指標對應
這份對應旨在協助開發人員找出與哪個標準指標對應的舊版指標,但請注意,對應指標可能會使用不同的單位或以總計數器表示,而非即時值。請參閱指標定義的規格。
標準 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-candidate 或candidate-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.requestsReceived 或 candidate-pair.responsesReceived
|
.googLocalAddress
|
local-candidate.address (透過 candidate-pair.localCandidateId 查詢 local-candidate ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
與 local-candidate.protocol 和 remote-candidate.protocol 相同。 |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable 是一個布林值,可反映我們最近是否遞增 candidate-pair.responsesReceived
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
「有效連線」是指傳輸目前選取的候選組合,例如 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-rtp 、outbound-rtp 、media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel 。舊版指標的範圍介於 [0..32768] 之間,但標準符合曲線在 [0..1] 範圍內。 |
.audioOutputLevel
|
inbound-rtp.audioLevel 。舊版指標的範圍介於 [0..32768] 之間,但標準符合曲線在 [0..1] 範圍內。 |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
本機 MediaStreamTrack 為 media-source.trackIdentifier ,遠端 MediaStreamTrack 為 inbound-rtp.trackIdentifier |
.googRtt
|
remote-inbound-rtp.roundTripTime (請參閱「outbound-rtp.remoteId 」) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
轉碼器名稱是「type/subtype」的子類型MIME 類型:codec.mimeType (請參閱 inbound-rtp.codecId 和 outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId 和outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind 和outbound-rtp.kind 或media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
「inbound-rtp.totalAudioEnergy 」和「media-source.totalAudioEnergy 」
|
ssrc.totalSamplesDuration
|
「inbound-rtp.totalSamplesDuration 」和「media-source.totalSamplesDuration 」
|
.ssrc
|
「inbound-rtp.ssrc 」和「outbound-rtp.ssrc 」
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType 和outbound-rtp.contentType |
.googFrameWidthInput
|
media-source.width
|
.googFrameHeightInput
|
media-source.height
|
.googFrameRateInput
|
media-source.framesPerSecond
|
.googFrameWidthSent
|
outbound-rtp.frameWidth
|
.googFrameHeightSent
|
outbound-rtp.frameHeight
|
.googFrameRateSent
|
雖然傳送每秒影格數是 outbound-rtp.framesSent 的變更速率,但實際上是實作為 outbound-rtp.framesPerSecond (編碼每秒影格數)。 |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
inbound-rtp.framesDecoded 的變化率 |
.googFrameRateOutput
|
inbound-rtp.framesDecoded - inbound-rtp.framesDropped 的變化率 |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
「 |
.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-rtp 和candidate-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
|
每個 RTP 串流位元率的 outbound-rtp.headerBytesSent + outbound-rtp.bytesSent 變化速率、每個 ICE 候選位元率 candidate-pair.bytesSent ,或每個傳輸位元率的 transport.bytesSent |
.googRetransmitBitrate
|
outbound-rtp.retransmittedBytesSent 的變化範圍 |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
標準 API 可感知模擬功能
使用模擬結果時,您可能會發現舊版 API 只會回報一個 SSRC,即使您使用模擬功能傳送三個不同的 SSRC 來傳送三個 RTP 串流 (例如),
標準 API 並未分享這項限制,並會傳回三個 outbound-rtp
統計資料物件 (每個 SSRC 各一個)。也就是說,您可以個別分析每個 RTP 串流,但也代表您必須自行匯總所有 RTP 傳送串流的總位元率。
另一方面,具有多個空間層透過 scalabilityMode
API 設定的 SVC 串流或 RTP 串流,仍會顯示為單一 outbound-rtp
,因為這些內容是透過單一 SSRC 傳送。
需要更多時間遷移
在 Chrome 117 中移除舊版 API 後,使用該 API 將產生例外狀況。如果您無法及時遷移程式碼,可以參考 RTCPeerConnection 回呼式 getStats() API 的來源試用,讓已註冊的網站有更多時間遷移。如為來源試用權杖,則可繼續使用舊版 getStats() API,直到 Chrome 121 版為止。