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 hai bisogno di più tempo per apportare questa modifica.

In passato sono state disponibili due versioni concorrenti dell'API WebRTC getStats(). L'API getStats() precedente, che precede il processo di standardizzazione e accetta un argomento di callback, e l'API standardizzata e ampiamente supportata che restituisce una promessa.

L'API standard è più completa e presenta metriche ben definite documentate pubblicamente nella specifica W3C Identifiers for WebRTC's Statistics API. La specifica include descrizioni di ogni metrica elencata in questa guida e molte altre.

A partire da Chrome 117, l'API getStats() precedente lancerà un'eccezione nel canale di rilascio stabile (l'eccezione 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'enum RTCStatsType della specifica. Sono incluse la definizione del dizionario delle statistiche che descrive le metriche raccolte per ogni tipo.

Tutti gli oggetti stats 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 (un esempio è riportato 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 disegni tutte le relazioni ...Id, ottieni un grafico.

L'API precedente ha i seguenti tipi di statistiche, corrispondenti ai tipi standard come segue:


Tipo legacy

Tipo standard
ssrc
Rappresenta uno stream RTP e le metriche relative al MediaStreamTrack associato.


I tipi standard per questo sono inbound-rtp (per gli stream RTP in ricezione e il relativo MediaStreamTrack remoto associato), outbound-rtp (per gli stream RTP in invio) e media-source (per le metriche MediaStreamTrack locali associate a uno stream RTP in invio). Le metriche dello stream RTP contengono anche informazioni sull'encoder o sul decodificatore utilizzato dallo stream RTP.
VideoBwe
Metriche di stima della larghezza di banda, velocità in bit target, velocità in bit dell'encoder 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 ICE. La versione standard è local-candidate e remote-candidate.
googCandidatePair
Rappresenta una coppia di candidati ICE, ovvero un accoppiamento di 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 RTCPeerConnection. Sebbene i relativi contenuti non corrispondano a nulla nello standard, lo standard ha un tipo associato a RTCPeerConnection: peer-connection.

Non presente nell'API precedente

All'API standard sono stati aggiunti questi tipi di statistiche che non hanno un tipo precedente corrispondente:
  • codec: un codec attualmente in uso da uno stream RTP, per la codifica o la decodifica. Si tratta di un sottoinsieme dei codec negoziati nel file SDP.
  • remote-inbound-rtp: lo stream RTP in entrata di un endpoint remoto corrispondente a uno stream RTP in uscita inviato da questo endpoint (outbound-rtp). Viene misurato nell'endpoint remoto e riportato in un report del ricevitore RTCP (RR) o nel report esteso RTCP (XR).
  • remote-outbound-rtp: lo stream RTP in uscita di un endpoint remoto corrispondente a uno stream RTP in entrata che questo endpoint sta ricevendo (inbound-rtp). Viene misurato nell'endpoint remoto e registrato in un report del mittente RTCP (SR).
  • media-playout: metriche relative alla riproduzione di un MediaStreamTrack remoto associato a uno stream RTP in entrata (inbound-rtp).
  • data-channel: rappresenta un RTCDataChannel.

Mappatura delle metriche precedenti a quelle standard

Lo scopo di questa mappatura è aiutare gli sviluppatori a trovare la metrica precedente corrispondente a quella standard, ma tieni presente che la metrica corrispondente potrebbe utilizzare unità diverse o essere espressa come un contatore totale anziché un valore istantaneo. Fai riferimento alla specifica per le definizioni delle metriche.
L'API standard preferisce esporre contatori totali anziché tariffe. Ciò significa che per ottenere la frequenza corrispondente (ad esempio la velocità in bit) come nell'API precedente, l'app deve calcolare la frequenza media prendendo 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 manualmente le tariffe e le medie può sembrare un passaggio aggiuntivo complicato, ma ha il vantaggio di consentire di ottenere medie in qualsiasi intervallo di tempo desiderato. Chiamare l'API standard meno spesso di quanto avresti dovuto fare con l'API precedente offre alcuni vantaggi in termini di rendimento.

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 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 indica 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 indica se abbiamo o meno incrementato di recente candidate-pair.responsesReceived
.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, media-source
.audioInputLevel media-source.audioLevel. La metrica precedente è nell'intervallo [0..32768], mentre la metrica standard è nell'intervallo [0..1].
.audioOutputLevel
inbound-rtp.audioLevel. La metrica precedente è nell'intervallo [0..32768], mentre la metrica standard è nell'intervallo [0..1].
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier per i MediaStreamTrack locali e inbound-rtp.trackIdentifier per i 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
Sebbene i FPS di invio siano la frequenza di variazione di outbound-rtp.framesSent, in realtà vengono implementati come outbound-rtp.framesPerSecond, ovvero FPS di codifica.
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
Il tasso di variazione di inbound-rtp.framesDecoded
.googFrameRateOutput
La velocità 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 è cambiata per motivi correlati a qualityLimitationReason. Questo potrebbe essere dedotto da altre metriche (ad es. la risoluzione di invio o la frequenza fotogrammi diversa dalla risoluzione o dalla frequenza fotogrammi di origine), ma la durata limitata, outbound-rtp.qualityLimitationDurations, potrebbe essere più utile della frequenza con cui è stata riconfigurata la risoluzione o la frequenza fotogrammi.
.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 dei pacchetti contenenti 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 di campioni nascosti quando lo stream non era silenzioso: (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate Il rapporto recente dei campioni che sono stati eliminati per accelerare la velocità di riproduzione: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Il rapporto recente dei 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-metric 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 frequenza di variazione di outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate La velocità di variazione di outbound-rtp.headerBytesSent + outbound-rtp.bytesSent per la velocità in bit dello stream per RTP, candidate-pair.bytesSent per la velocità in bit per candidato ICE o 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 è compatibile con il simulcast

Se utilizzi il simulcast, potresti aver notato che l'API precedente segnala un solo SSRC anche quando utilizzi il simulcast per inviare (ad esempio) tre stream RTP su tre SSRC distinti.

L'API standard non condivide questa limitazione e restituisce tre oggetti di statistiche outbound-rtp, uno per ogni SSRC. Ciò significa che puoi analizzare ogni stream RTP singolarmente, ma anche che per ottenere la velocità in bit totale di tutti gli stream di invio RTP dovrai aggregarli autonomamente.

Gli stream SVC o RTP con più livelli spaziali configurati tramite l'API scalabilityMode, invece, vengono 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 verrà rimossa in Chrome 117, il suo utilizzo genererà un'eccezione. Se non riesci a eseguire la migrazione del codice in tempo, la prova dell'origine per l'API getStats() basata su callback di RTCPeerConnection offre ai siti web registrati più tempo per eseguire la migrazione. Con un token di prova dell'origine, l'API getStats() precedente può continuare a essere utilizzata fino a Chrome 121.