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 hai bisogno di più tempo per apportare questa modifica.
Storicamente esistono due versioni concorrenti dell'API WebRTC getStats()
. L'API legacy getStats(), 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 presenta 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()
precedente genererà un'eccezione nel canale di rilascio stabile (la generazione delle eccezioni verrà implementata gradualmente). Segui questa guida per semplificare 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. Include la definizione del dizionario delle statistiche che descrive le metriche raccolte per ogni tipo.
Tutti gli oggetti statistica 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. Questo è utile per calcolare il tasso di variazione delle metriche (c'è un esempio nella sezione successiva). Gli ID formano anche 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
, viene visualizzato un grafico.
L'API legacy dispone dei 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 la ricezione di stream RTP e il relativo MediaStreamTrack remoto associato), outbound-rtp (per l'invio di stream RTP) 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 dal flusso 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 delle coppie di candidati ICE (candidate-pair ). |
googComponent
|
Rappresenta il trasporto (ICE e DTLS). La versione standard è transport . |
localcandidate and remotecandidate
|
Rappresenta un candidato dell'ICE. La versione standard è local-candidate e remote-candidate . |
googCandidatePair
|
Rappresenta una coppia di candidati dell'ICE, ovvero l'abbinamento di un candidato locale e di un candidato da remoto. La versione standard è candidate-pair . |
googCertificate
|
Rappresenta un certificato utilizzato dal trasporto DTLS. La versione standard è certificate . |
googLibjingleSession
|
Rappresenta il RTCPeerConnection . Anche se i suoi contenuti non sono associati a nessun elemento nello standard, lo standard ha un tipo associato a RTCPeerConnection : peer-connection . |
Non presente nell'API precedente |
Questi tipi di statistiche sono stati aggiunti all'API standard che non dispone di alcun tipo precedente corrispondente:
|
Mappatura delle metriche da legacy a standard
Questa mappatura è pensata per aiutare gli sviluppatori a capire quale metrica precedente corrisponde a una 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 alle specifiche per le definizioni delle metriche.
L'API standard preferisce esporre i contatori totali piuttosto che le tariffe. Ciò significa che per ottenere la velocità corrispondente (ad esempio, la velocità in bit) come nell'API precedente, l'app deve calcolare la velocità media facendo 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;
Dover calcolare personalmente tariffe e medie in questo modo può sembrare un passaggio aggiuntivo gravoso, ma ha l'aspetto positivo di consentirti di ottenere le medie sull'intervallo di tempo desiderato. Chiamare l'API standard meno spesso di quanto avresti dovuto fare con l'API legacy 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 o candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (ricerca inversa di 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 (ricerca remote-candidate tramite candidate-pair.remoteCandidateId ) |
.googReadable
|
googReadable è un valore booleano che riflette se di recente abbiamo incrementato o meno candidate-pair.requestsReceived o candidate-pair.responsesReceived
|
.googLocalAddress
|
local-candidate.address (ricerca 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 riflette se di recente abbiamo incrementato o meno candidate-pair.responsesReceived
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
La connessione attiva si riferisce alla coppia di candidati 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 , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . La metrica precedente è compresa nell'intervallo [0..32768], ma il metodo di misurazione standard è compreso nell'intervallo [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . La metrica precedente è compresa nell'intervallo [0..32768], ma il metodo di misurazione standard è compreso 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 del tipo MIME "type/subtype", 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 corrisponde alla codifica FPS. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Il tasso di variazione della metrica inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Tasso di variazione della metrica 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 motivi correlati a qualityLimitationReason . Questo risultato potrebbe essere dedotto da altre metriche (ad es. la risoluzione di invio o la frequenza fotogrammi sono diverse dalla risoluzione di origine o dalla frequenza fotogrammi), ma la durata che abbiamo limitato, outbound-rtp.qualityLimitationDurations , potrebbe essere più utile rispetto alla frequenza con cui la risoluzione o la frequenza fotogrammi sono state modificate è stata riconfigurata. |
.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
|
Il rapporto recente dei campioni nascosti: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Il rapporto recente dei campioni nascosti mentre lo stream non era silenzioso: di (inbound-rtp.concealedSamples -inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Il rapporto recente di campioni eliminati per accelerare la velocità dei playout: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Il rapporto recente di campioni sintetizzati per decelerare la velocità di playout: 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 del payload, escluse le ritrasmissioni: la velocità di variazione compresa tra outbound-rtp.bytesSent e outbound-rtp.retransmittedBytesSent . |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Il tasso di modifica di outbound-rtp.headerBytesSent + outbound-rtp.bytesSent per la velocità in bit dello stream per RTP, di candidate-pair.bytesSent per la velocità in bit del candidato per-ICE o di transport.bytesSent per la velocità in bit per trasporto |
.googRetransmitBitrate
|
L'intervallo di variazione di outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
L'API standard è sensibile alla simulcast
Se utilizzi simulcast, potresti aver notato che l'API legacy segnala solo un singolo SSRC anche quando utilizzi questa modalità per inviare (ad esempio) tre stream RTP su tre SSRC separati.
L'API standard non condivide questa limitazione e restituisce tre oggetti statistiche outbound-rtp
, uno per ciascuno degli SSRC. Ciò significa che puoi analizzare ogni singolo stream RTP, ma significa anche che per ottenere la velocità in bit totale di tutti gli stream di invio RTP dovrai aggregarli personalmente.
Gli stream SVC o RTP con più livelli spaziali configurati tramite l'API scalabilityMode
vengono invece visualizzati come un singolo outbound-rtp
perché vengono inviati tramite un singolo SSRC.
Se hai bisogno di più tempo per la migrazione
Quando l'API precedente viene rimossa in Chrome 117, il suo 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 più tempo ai siti web registrati per eseguire la migrazione. Con un token di prova dell'origine, l'API getStats() precedente potrebbe continuare a essere utilizzata fino a Chrome 121.