旧版 getStats()
WebRTC API 将从 Chrome 117 中移除,因此使用该 API 的应用需要迁移到标准 API。本文介绍了如何迁移代码,以及如果您需要更多时间来完成此更改,应该怎么做。
WebRTC getStats()
API 过去有两个竞争版本。旧版 getStats() API(早于标准化流程日期并采用回调参数)和广泛支持的标准化 API(会返回 promise)。
标准 API 功能更丰富,并且在 W3C 规范 WebRTC Statistics API 的标识符中公开记录了明确定义的指标。该规范包括对本指南中列出的每个指标的说明以及其他更多内容。
从 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 中,但没有任何对应的旧版类型: <ph type="x-smartling-placeholder">
|
旧版指标与标准指标的映射
此映射旨在帮助开发者找到哪个旧版指标对应于哪个标准指标,但请注意,相应的指标可能使用不同的单位,或者以总计数器(而非瞬时值)的形式表示。如需了解指标定义,请参阅规范。
标准 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] 范围内,但标准 Merc 在 [0..1] 范围内。 |
.audioOutputLevel
|
inbound-rtp.audioLevel 。旧版指标在 [0..32768] 范围内,但标准 Merc 在 [0..1] 范围内。 |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier 用于本地 MediaStreamTrack ,inbound-rtp.trackIdentifier 用于远程 MediaStreamTrack |
.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
|
虽然发送 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
|
|
.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 可感知同步播放
如果您使用同时直播,可能会注意到,即使您使用同步直播通过三个单独的 SSRC 发送(举例而言)三个 RTP 流,旧版 API 也只会报告一个 SSRC。
标准 API 没有此限制,将返回三个 outbound-rtp
统计信息对象,每个 SSRC 对应一个。也就是说,您可以单独分析每个 RTP 流,但要获得所有 RTP 发送流的总比特率,您需要自行聚合它们。
另一方面,通过 scalabilityMode
API 配置多个空间层的 SVC 视频流或 RTP 视频流仍会显示为单个 outbound-rtp
,因为它们是通过单个 SSRC 发送的。
如果您需要更多时间进行迁移
在 Chrome 117 中移除旧版 API 后,使用该 API 会引发异常。如果您无法及时迁移代码,基于 RTCPeerConnection 回调的 getStats() API 源试用会为已注册的网站提供更多迁移时间。借助源试用令牌,旧版 getStats() API 可继续使用到 Chrome 121。