WebRTC: guida alla migrazione con getStats() precedente

Henrik Boström
Henrik Boström

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:
  • codec: un codec attualmente utilizzato da uno stream RTP per la codifica o la decodifica. Si tratta di un sottoinsieme dei codec negoziati nell'SDP.
  • remote-inbound-rtp: stream RTP in entrata di un endpoint remoto corrispondente a uno stream RTP in uscita inviato da questo endpoint (outbound-rtp). Viene misurato all'endpoint remoto e riportato in un RTCP receiver Report (RR) o RTCP Extended Report (XR).
  • remote-outbound-rtp: stream RTP in uscita di un endpoint remoto corrispondente a uno stream RTP in entrata che questo endpoint sta ricevendo (inbound-rtp). Viene misurato all'endpoint remoto e riportato in un report RTCP Sender Report (SR).
  • media-playout: metriche relative al playout di un dispositivo MediaStreamTrack remoto associato a uno stream RTP in entrata (inbound-rtp).
  • data-channel: rappresenta un RTCDataChannel.

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

inbound-rtp.qpSum e outbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime/outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementation e outbound-rtp.encoderImplementation

.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.