L'API WebRTC getStats()
precedente verrà rimossa in Chrome 117, pertanto le app che la utilizzano dovranno eseguire la migrazione all'API standard. Questo articolo spiega come eseguire la migrazione del codice e cosa fare se si ha bisogno di più tempo per apportare questa modifica.
Storicamente esistono due versioni concorrenti dell'API getStats()
WebRTC. L'API getStats() legacy, che precede il processo di standardizzazione e utilizza un argomento di callback, e l'API standardizzata e ampiamente supportata che restituisce una promessa.
L'API standard è più ricca di funzionalità e dispone di metriche ben definite documentate pubblicamente nella specifica W3C Identifiers for WebRTC's Statistics API. La specifica include le descrizioni di ogni metrica elencata in questa guida e molte altre.
A partire da Chrome 117, l'API getStats()
legacy genererà un'eccezione nel canale di rilascio Stabile (la generazione delle eccezioni verrà implementata gradualmente). Segui questa guida per facilitare la transizione all'API standard.
Tipi di statistiche precedenti e standard
L'elenco completo dei tipi di statistiche standard è disponibile nell'enumerazione RTCStatsType nella specifica. Ciò include la definizione del dizionario delle statistiche che descrive le metriche raccolte per ogni tipo.
Tutti gli oggetti Statistiche hanno un attributo ID che identifica in modo univoco l'oggetto sottostante in più chiamate getStats()
. Lo stesso oggetto avrà lo stesso ID ogni volta che viene chiamato il metodo. È utile per calcolare il tasso di variazione delle metriche (c'è un esempio nella sezione successiva). Gli ID formano inoltre relazioni di riferimenti. Ad esempio, l'oggetto statistiche outbound-rtp
fa riferimento all'oggetto statistiche media-source
associato tramite l'attributo outbound-rtp.mediaSourceId
. Se tracci tutte le relazioni di ...Id
, ottieni un grafico.
L'API legacy ha i seguenti tipi di statistiche, corrispondenti ai tipi standard come segue:
Tipo precedente |
Tipo standard |
---|---|
ssrc
|
Rappresenta uno stream RTP e le metriche relative al MediaStreamTrack associato.I tipi standard sono inbound-rtp (per gli stream RTP di ricezione e il relativo MediaStreamTrack remoto associato), outbound-rtp (per gli stream RTP di invio) e media-source (per le metriche MediaStreamTrack locali associate a uno stream RTP di invio). Le metriche di flusso RTP contengono anche informazioni sull'encoder o sul decoder utilizzato dallo stream RTP. |
VideoBwe
|
Metriche per la stima della larghezza di banda, velocità in bit target, velocità in bit del codificatore e velocità in bit effettiva. Questi tipi di metriche fanno parte delle metriche RTP ( outbound-rtp e inbound-rtp ) e delle metriche sulla coppia di candidati ICE (candidate-pair ). |
googComponent
|
Rappresenta il trasporto (ICE e DTLS). La versione standard è transport . |
localcandidate and remotecandidate
|
Rappresenta un candidato all'ICE. La versione standard è local-candidate e remote-candidate . |
googCandidatePair
|
Rappresenta una coppia di candidati ICE, ovvero un candidato locale e uno remoto. La versione standard è candidate-pair . |
googCertificate
|
Rappresenta un certificato utilizzato dal trasporto DTLS. La versione standard è certificate . |
googLibjingleSession
|
Rappresenta il RTCPeerConnection . Sebbene i suoi contenuti non corrispondano a nulla nello standard, lo standard ha un tipo associato a RTCPeerConnection : peer-connection . |
Mancante nell'API precedente |
All'API standard sono stati aggiunti questi tipi di statistiche che non hanno alcun tipo precedente corrispondente:
|
Mappatura delle metriche legacy a standard
Lo scopo di questa mappatura è aiutare gli sviluppatori a individuare la metrica precedente corrispondente a una determinata metrica standard, ma tieni presente che la metrica corrispondente potrebbe utilizzare unità diverse o essere espressa come contatore totale anziché come valore istantaneo. Fai riferimento alla specifica per le definizioni delle metriche.
L'API standard preferisce l'esposizione dei contatori totali anziché delle tariffe. Ciò significa che per ottenere la tariffa corrispondente (ad esempio, la velocità in bit) come nell'API precedente, l'app deve calcolare la tariffa media utilizzando il delta tra due chiamate getStats()
. Ad esempio:
// 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;
Il fatto di dover calcolare le tariffe e le medie autonomamente può sembrare un'operazione complicata, ma ha l'aspetto positivo di consentirti di ottenere le medie su qualsiasi intervallo di tempo desiderato. Chiamare l'API standard con meno frequenza rispetto a quella che avresti potuto fare con l'API precedente offre alcuni vantaggi in termini di prestazioni.
Metrica precedente
googCertificate |
Corrispondenza standard
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Metrica precedente
googComponent |
Corrispondenza standard
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Metrica precedente
localcandidate |
Corrispondenza standard
local-candidate oppure candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (ricerca inversa candidate-pair tramite 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
|
Metrica precedente
remotecandidate |
Corrispondenza standard
remote-candidate |
---|---|
Come localcandidate sopra. |
Come local-candidate sopra. |
Metrica precedente
googCandidatePair |
Corrispondenza standard
candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType (cerca remote-candidate tramite candidate-pair.remoteCandidateId ) |
.googReadable
|
googReadable è un valore booleano che indica se abbiamo incrementato di recente candidate-pair.requestsReceived o candidate-pair.responsesReceived
|
.googLocalAddress
|
local-candidate.address (cerca local-candidate tramite candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Uguale a local-candidate.protocol e remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable è un valore booleano che indica se abbiamo incrementato di recente candidate-pair.responsesReceived o meno
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
La connessione attiva si riferisce alla coppia candidata attualmente selezionata dal trasporto, ad esempio dove 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
|
Metrica precedente
ssrc |
Corrispondenza standard
inbound-rtp , outbound-rtp e media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . La metrica legacy è compresa nell'intervallo [0..32768], ma il metro standard è nell'intervallo [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . La metrica legacy è compresa nell'intervallo [0..32768], ma il metro standard è nell'intervallo [0..1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier per MediaStreamTrack locali e inbound-rtp.trackIdentifier per MediaStreamTrack remoti |
.googRtt
|
remote-inbound-rtp.roundTripTime (vedi outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Il nome del codec è il sottotipo di "type/subtype" tipo MIME, codec.mimeType (vedi inbound-rtp.codecId e outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId e outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind e outbound-rtp.kind o 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
|
Mentre l'FPS di invio è la frequenza di modifica di outbound-rtp.framesSent , in realtà viene implementato come outbound-rtp.framesPerSecond , che codifica l'FPS. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Il tasso di variazione di inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Il tasso di variazione di inbound-rtp.framesDecoded - inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
Vero se outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
Vero se outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
La metrica precedente conteggia il numero di volte in cui la risoluzione o la frequenza fotogrammi sono cambiate per qualityLimitationReason motivi correlati. Questo valore può essere dedotto da altre metriche (ad es. la risoluzione di invio o la frequenza fotogrammi sono diverse dalla risoluzione o dalla frequenza fotogrammi dell'origine), ma la durata che è stata limitata (outbound-rtp.qualityLimitationDurations ) potrebbe essere più utile rispetto alla frequenza con cui la risoluzione o la frequenza fotogrammi sono state riconfigurate. |
.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
|
Il rapporto recente di pacchetti contenenti la correzione degli errori: inbound-rtp.fecPacketsReceived - inbound-rtp.fecPacketsDiscarded |
.packetsReceived
|
inbound-rtp.packetsReceived
|
.googJitterBufferMs
|
inbound-rtp.jitterBufferDelay /inbound-rtp.jitterBufferEmittedCount
|
.googTargetDelayMs (video) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googPreferredJitterBufferMs (audio) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googExpandRate
|
Rapporto recente tra campioni nascosti: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Il rapporto recente di campioni nascosti mentre lo stream non era silenziato: di (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Il rapporto recente di campioni scartati per accelerare la velocità di playout: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Il rapporto recente di campioni sintetizzati per decelerare la velocità di riproduzione: 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
|
L'unica metrica goog-metrica rimanente. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Metrica precedente
VideoBwe |
Corrispondenza standard
outbound-rtp e candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate come valore istantaneo o outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded come media |
.googActualEncBitrate
|
I byte prodotti dall'encoder sono i byte payload, escluse le ritrasmissioni: il tasso di variazione di outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
La frequenza di modifica di outbound-rtp.headerBytesSent + outbound-rtp.bytesSent per la velocità in bit per streaming con RTP, di candidate-pair.bytesSent per la velocità in bit del candidato ICE o di transport.bytesSent per la velocità in bit per trasporto |
.googRetransmitBitrate
|
L'intervallo di modifica di outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
L'API standard è simulcast-aware
Se utilizzi la modalità simulcast, avrai notato che l'API precedente segnala un solo SSRC anche se utilizzi simulcast per inviare (ad esempio) tre stream RTP su tre SSRC separati.
L'API standard non condivide questa limitazione e restituirà tre oggetti statistiche outbound-rtp
, uno per ciascuno degli SSRC. Ciò significa che è possibile analizzare ogni stream RTP singolarmente, ma anche che per ottenere la velocità in bit totale di tutti gli stream in invio RTP dovrai aggregarli personalmente.
Gli stream SVC o gli stream RTP con più livelli spaziali configurati tramite l'API scalabilityMode
vengono comunque visualizzati come un singolo outbound-rtp
perché vengono inviati su un singolo SSRC.
Se hai bisogno di più tempo per la migrazione
Quando l'API precedente viene rimossa in Chrome 117, la sua utilizzo genera un'eccezione. Se non riesci a eseguire la migrazione del codice in tempo, la prova dell'origine per l'API getStats() basata su callback RTCPeerConnection offre ai siti web registrati più tempo per la migrazione. Con un token di prova dell'origine, l'API getStats() precedente potrebbe continuare a essere utilizzata fino a Chrome 121.