A API WebRTC getStats()
legada será removida no Chrome 117. Os apps que a usam precisarão migrar para a API padrão. Neste artigo, explicamos como migrar seu código e o que fazer se você precisar de mais tempo para fazer essa alteração.
Historicamente, há duas versões concorrentes da API getStats()
do WebRTC. A API getStats() legada, que é anterior ao processo de padronização e aceita um argumento de callback, e a API padronizada e amplamente compatível que retorna uma promessa.
A API padrão é mais repleta de recursos e tem métricas bem definidas e documentadas publicamente na especificação do W3C Identificadores para a API Statistics do WebRTC (em inglês). A especificação inclui descrições de cada métrica listada neste guia e muito mais.
No Chrome 117, a API getStats()
legada gera uma exceção no canal de lançamento Stable. A geração da exceção será lançada gradualmente. Siga este guia e facilite a transição para a API padrão.
Tipos de estatísticas legados versus padrão
A lista completa dos tipos de estatísticas padrão pode ser encontrada no enum RTCStatsType na especificação. Isso inclui a definição do dicionário de estatísticas que descreve as métricas coletadas para cada tipo.
Todos os objetos de estatísticas têm um atributo de ID que identifica exclusivamente o objeto subjacente em várias chamadas de getStats()
. O mesmo objeto terá o mesmo ID sempre que o método for chamado. Isso é útil para calcular a taxa de mudança de métricas (há um exemplo na próxima seção). Os IDs também formam relações de referências. Por exemplo, o objeto de estatísticas outbound-rtp
faz referência ao objeto de estatísticas media-source
associado usando o atributo outbound-rtp.mediaSourceId
. Ao desenhar todas as relações ...Id
, você recebe um gráfico.
A API legada tem os seguintes tipos de estatísticas, que correspondem aos tipos padrão da seguinte forma:
Tipo legado |
Tipo padrão |
---|---|
ssrc
|
Representa um stream RTP e métricas sobre o MediaStreamTrack associado.Os tipos padrão para isso são inbound-rtp (para streams de RTP recebidos e o MediaStreamTrack remoto associado a eles), outbound-rtp (para streams de RTP de envio) e media-source (para métricas locais de MediaStreamTrack associadas a um stream de RTP de envio). Elas também contêm informações sobre o codificador ou decodificador usado pelo stream RTP. |
VideoBwe
|
Métricas de estimativa de largura de banda, taxa de bits desejada, taxa de bits do codificador e taxa de bits real. Esses tipos de métricas fazem parte das métricas de RTP ( outbound-rtp e inbound-rtp ) e de pares de candidatos ICE (candidate-pair ). |
googComponent
|
Representa o transporte (ICE e DTLS). A versão padrão é transport . |
localcandidate and remotecandidate
|
Representa um candidato ICE. A versão padrão é local-candidate e remote-candidate . |
googCandidatePair
|
Representa um par de candidatos ICE, que é um par de candidatos locais e remotos. A versão padrão é candidate-pair . |
googCertificate
|
Representa um certificado usado pelo transporte DTLS. A versão padrão é certificate . |
googLibjingleSession
|
Representa o RTCPeerConnection . Embora o conteúdo dele não seja mapeado para nada no padrão, ele tem um tipo associado ao RTCPeerConnection : peer-connection . |
Ausência da API legada |
Estes tipos de estatísticas foram adicionados à API padrão e não têm nenhum tipo legado correspondente:
|
Mapeamento de métricas legadas para padrão
O objetivo desse mapeamento é ajudar os desenvolvedores a descobrir qual métrica legada corresponde a qual métrica padrão. No entanto, a métrica correspondente pode usar unidades diferentes ou ser expressa como um contador total em vez de um valor instantâneo. Consulte a especificação para definições de métrica.
A API padrão prefere expor o total de contadores em vez de taxas. Isso significa que, para conseguir a taxa correspondente (por exemplo, taxa de bits), como na API legada, o app precisa calcular a taxa média usando o delta entre duas chamadas getStats()
. Exemplo:
// 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;
Calcular as taxas e médias dessa forma pode parecer uma etapa adicional complicada, mas permite que você obtenha médias em qualquer intervalo de tempo desejado. Chamar a API padrão com menos frequência do que com a API legada gera alguns benefícios de desempenho.
Métrica legada
e googCertificate |
Correspondência padrão
e certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Métrica legada
e googComponent |
Correspondência padrão
e transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Métrica legada
e localcandidate |
Correspondência padrão
local-candidate ou candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (pesquisa reversa de candidate-pair via candidate-pair.localCandidateId ) |
.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
|
Métrica legada
e remotecandidate |
Correspondência padrão
e remote-candidate |
---|---|
Igual à localcandidate acima. |
Igual à local-candidate acima. |
Métrica legada
e googCandidatePair |
Correspondência padrão
e candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType (pesquisa remote-candidate via candidate-pair.remoteCandidateId ) |
.googReadable
|
googReadable é um booleano que reflete se recentemente incrementamos candidate-pair.requestsReceived ou candidate-pair.responsesReceived
|
.googLocalAddress
|
local-candidate.address (pesquisa local-candidate via candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Igual a local-candidate.protocol e remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable é um booleano que reflete se incrementamos candidate-pair.responsesReceived recentemente ou não.
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
A conexão ativa se refere ao par candidato selecionado no momento pelo transporte, como 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
|
Métrica legada
e ssrc |
Correspondência padrão
inbound-rtp , outbound-rtp e media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . A métrica legada está no intervalo [0..32768], mas a métrica padrão está no intervalo [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . A métrica legada está no intervalo [0..32768], mas a métrica padrão está no intervalo [0..1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier para MediaStreamTrack s locais e inbound-rtp.trackIdentifier para MediaStreamTrack s remotos |
.googRtt
|
remote-inbound-rtp.roundTripTime (consulte outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
O nome do codec é o subtipo de "tipo/subtipo" tipo MIME, codec.mimeType (consulte inbound-rtp.codecId e outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId e outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind e outbound-rtp.kind ou media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
inbound-rtp.totalAudioEnergy e media-source.totalAudioEnergy
|
ssrc.totalSamplesDuration
|
inbound-rtp.totalSamplesDuration e media-source.totalSamplesDuration
|
.ssrc
|
inbound-rtp.ssrc e outbound-rtp.ssrc
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType e outbound-rtp.contentType |
.googFrameWidthInput
|
media-source.width
|
.googFrameHeightInput
|
media-source.height
|
.googFrameRateInput
|
media-source.framesPerSecond
|
.googFrameWidthSent
|
outbound-rtp.frameWidth
|
.googFrameHeightSent
|
outbound-rtp.frameHeight
|
.googFrameRateSent
|
Embora o QPS de envio seja a taxa de mudança de outbound-rtp.framesSent , isso é implementado como outbound-rtp.framesPerSecond , que codifica QPS. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
A taxa de mudança de inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Taxa de mudança de inbound-rtp.framesDecoded - inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
Verdadeiro se outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
Verdadeiro se outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
A métrica legada conta quantas vezes a resolução ou o frame rate mudou por motivos relacionados ao qualityLimitationReason . Isso pode ser deduzido de outras métricas (por exemplo, se a resolução de envio ou o frame rate são diferentes da resolução da origem ou do frame rate), mas a duração limitada, outbound-rtp.qualityLimitationDurations , pode ser mais útil do que a frequência com que a resolução ou o frame rate alterado foi reconfigurado. |
.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
|
A proporção recente de pacotes que contêm correção de erro: inbound-rtp.fecPacketsReceived - inbound-rtp.fecPacketsDiscarded |
.packetsReceived
|
inbound-rtp.packetsReceived
|
.googJitterBufferMs
|
inbound-rtp.jitterBufferDelay / inbound-rtp.jitterBufferEmittedCount
|
.googTargetDelayMs (vídeo) |
inbound-rtp.jitterBufferTargetDelay / inbound-rtp.jitterBufferEmittedCount
|
.googPreferredJitterBufferMs (áudio) |
inbound-rtp.jitterBufferTargetDelay / inbound-rtp.jitterBufferEmittedCount
|
.googExpandRate
|
A proporção recente de amostras ocultas: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
A proporção recente de amostras ocultas enquanto o stream não estava silencioso: de (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
É a proporção recente de amostras que foram descartadas para acelerar a velocidade de reprodução: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
É a proporção recente de amostras sintetizadas para desacelerar a velocidade da reprodução: 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
|
A única métrica do goog restante. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Métrica legada
e VideoBwe |
Correspondência padrão
outbound-rtp e candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate como um valor instantâneo ou outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded como uma média |
.googActualEncBitrate
|
Os bytes produzidos pelo codificador são os bytes do payload, excluindo retransmissões: a taxa de mudança de outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay / outbound-rtp.packetsSent
|
.googTransmitBitrate
|
A taxa de mudança de outbound-rtp.headerBytesSent + outbound-rtp.bytesSent para taxa de bits de stream por RTP, candidate-pair.bytesSent para taxa de bits de candidato por ICE ou transport.bytesSent para taxa de bits por transporte |
.googRetransmitBitrate
|
O intervalo da mudança de outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
A API padrão reconhece transmissões simultâneas
Se você usa a transmissão simultânea, pode ter notado que a API legada só informa um único SSRC, mesmo quando você a usa para enviar (por exemplo) três streams de RTP em três SSRCs separados.
A API padrão não compartilha essa limitação e retorna três objetos de estatísticas outbound-rtp
, um para cada um dos SSRCs. Isso significa que é possível analisar cada stream de RTP individualmente, mas também é necessário agregar todos eles para conseguir a taxa de bits total de todos os streams de RTP.
Por outro lado, os streams SVC ou RTP com várias camadas espaciais configuradas pela API scalabilityMode
ainda aparecem como um único outbound-rtp
porque são enviados por um único SSRC.
Se você precisar de mais tempo para a migração
Quando a API legada for removida no Chrome 117, o uso dela vai gerar uma exceção. Se você não conseguir migrar seu código a tempo, o teste de origem da API getStats() baseada em callback do RTCPeerConnection oferecerá mais tempo para a migração dos sites registrados. Com um token de teste de origem, a API getStats() legada pode continuar sendo usada até o Chrome 121.