L'ancienne API WebRTC getStats()
sera supprimée dans Chrome 117. Les applications qui l'utilisent devront donc migrer vers l'API standard. Cet article explique comment migrer votre code et que faire si vous avez besoin de plus de temps pour effectuer cette modification.
Deux versions de l'API WebRTC getStats()
ont toujours été concurrentes. L'ancienne API getStats() qui est antérieure au processus de normalisation et qui accepte un argument de rappel, ainsi que l'API standardisée et largement prise en charge qui renvoie une promesse.
L'API standard offre davantage de fonctionnalités et possède des métriques bien définies, documentées publiquement dans la spécification W3C, intitulée Identifiants de l'API Statistics de WebRTC. Cette spécification comprend, entre autres, une description de chaque métrique répertoriée dans ce guide.
À partir de Chrome 117, l'ancienne API getStats()
générera une exception dans la version disponible stable (l'exception générée sera progressivement déployée). Suivez ce guide pour faciliter votre transition vers l'API standard.
Anciens types de statistiques et types de statistiques standards
La liste complète des types de statistiques standards est disponible en consultant l'énumération RTCStatsType dans la spécification. Cela inclut la définition du dictionnaire de statistiques qui décrit les métriques collectées pour chaque type.
Les objets statistiques possèdent tous un attribut "id" qui identifie de manière unique l'objet sous-jacent dans plusieurs appels getStats()
. Le même objet aura le même identifiant chaque fois que la méthode est appelée. Cela s'avère utile pour calculer le taux de variation des métriques (voir un exemple dans la section suivante). Les identifiants forment également des relations de références. Par exemple, l'objet de statistiques outbound-rtp
fait référence à l'objet de statistiques media-source
associé via l'attribut outbound-rtp.mediaSourceId
. Si vous dessinez toutes les relations ...Id
, vous obtenez un graphique.
L'ancienne API comporte les types de statistiques suivants, correspondant aux types standards:
Ancien type |
Type standard |
---|---|
ssrc
|
Représente un flux RTP et des métriques sur le MediaStreamTrack associé.Les types standards correspondants sont inbound-rtp (pour les flux de réception RTP et son MediaStreamTrack distant associé), outbound-rtp (pour les flux d'envoi RTP) et media-source (pour les métriques MediaStreamTrack locales associées à un flux RTP d'envoi). Les métriques de flux RTP contiennent également des informations sur l'encodeur ou le décodeur utilisé par le flux RTP. |
VideoBwe
|
Métriques d'estimation de la bande passante, débit cible, débit de l'encodeur et débit réel. Ces types de métriques font partie des métriques RTP ( outbound-rtp et inbound-rtp ) et des métriques des paires de candidats ICE (candidate-pair ). |
googComponent
|
Représente le transport (ICE et DTLS). La version standard est transport . |
localcandidate and remotecandidate
|
Représente un candidat ICE. Les versions standard sont local-candidate et remote-candidate . |
googCandidatePair
|
Représente une paire de candidats ICE, c'est-à-dire l'association d'un candidat local et d'un candidat distant. La version standard est candidate-pair . |
googCertificate
|
Représente un certificat utilisé par le transport DTLS. La version standard est certificate . |
googLibjingleSession
|
Représente RTCPeerConnection . Bien que son contenu ne corresponde à aucun élément de la norme, celui-ci possède un type associé à RTCPeerConnection : peer-connection . |
Manquant dans l'ancienne API |
Ces types de statistiques ont été ajoutés à l'API standard sans ancien type correspondant: <ph type="x-smartling-placeholder">
|
Mappage des anciennes métriques vers les métriques standards
Ce mappage a pour but d'aider les développeurs à identifier l'ancienne métrique qui correspond à chaque métrique standard. Notez toutefois que la métrique correspondante peut utiliser des unités différentes ou être exprimée sous la forme d'un compteur total plutôt que d'une valeur instantanée. Reportez-vous à la spécification pour obtenir la définition des métriques.
L'API standard préfère exposer les compteurs totaux plutôt que les taux. Comme dans l'ancienne API, pour obtenir le débit correspondant (par exemple, le débit), l'application doit calculer le tarif moyen en calculant le delta entre deux appels getStats()
. Exemple :
// 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;
Avoir à calculer vous-même les taux et les moyennes de cette manière peut sembler une étape supplémentaire fastidieuse, mais cela a l'avantage de vous permettre d'obtenir des moyennes sur n'importe quel intervalle de temps souhaité. Appeler l'API standard moins souvent qu'avec l'ancienne API présente des avantages en termes de performances.
Ancienne métrique
googCertificate |
Correspondance standard
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Ancienne métrique
googComponent |
Correspondance standard
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Ancienne métrique
localcandidate |
Correspondance standard
local-candidate ou candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (recherche inverse 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
|
Ancienne métrique
remotecandidate |
Correspondance standard
remote-candidate |
---|---|
Identique à localcandidate ci-dessus. |
Identique à local-candidate ci-dessus. |
Ancienne métrique
googCandidatePair |
Correspondance standard
candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType (recherche remote-candidate via candidate-pair.remoteCandidateId ) |
.googReadable
|
googReadable est une valeur booléenne indiquant si nous avons récemment incrémenté candidate-pair.requestsReceived ou candidate-pair.responsesReceived .
|
.googLocalAddress
|
local-candidate.address (recherche local-candidate via candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Identiques à local-candidate.protocol et remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable est une valeur booléenne qui indique si nous avons récemment incrémenté candidate-pair.responsesReceived ou non.
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
La connexion active fait référence à la paire candidate actuellement sélectionnée par le transport, par exemple où 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
|
Ancienne métrique
ssrc |
Correspondance standard
inbound-rtp outbound-rtp media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . L'ancienne métrique est comprise dans la plage [0..32768], mais la métrique standard est comprise dans la plage [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel L'ancienne métrique est comprise dans la plage [0..32768], mais la métrique standard est comprise dans la plage [0..1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier pour les MediaStreamTrack locaux et inbound-rtp.trackIdentifier pour les MediaStreamTrack distants |
.googRtt
|
remote-inbound-rtp.roundTripTime (voir outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Le nom du codec est le sous-type de "type/sous-type" Type MIME, codec.mimeType (voir inbound-rtp.codecId et outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId et outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind et outbound-rtp.kind ou media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
inbound-rtp.totalAudioEnergy et media-source.totalAudioEnergy
|
ssrc.totalSamplesDuration
|
inbound-rtp.totalSamplesDuration et media-source.totalSamplesDuration
|
.ssrc
|
inbound-rtp.ssrc et outbound-rtp.ssrc
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType et outbound-rtp.contentType |
.googFrameWidthInput
|
media-source.width
|
.googFrameHeightInput
|
media-source.height
|
.googFrameRateInput
|
media-source.framesPerSecond
|
.googFrameWidthSent
|
outbound-rtp.frameWidth
|
.googFrameHeightSent
|
outbound-rtp.frameHeight
|
.googFrameRateSent
|
Bien que le FPS d'envoi soit le taux de changement de outbound-rtp.framesSent , il est en fait implémenté en tant que outbound-rtp.framesPerSecond , qui encode le FPS. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Taux de variation de inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Taux de variation de inbound-rtp.framesDecoded – inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
"True" si outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
"True" si outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
L'ancienne métrique comptabilise le nombre de modifications de la résolution ou de la fréquence d'images pour des raisons liées à qualityLimitationReason . Cela peut être déduit d'autres métriques (par exemple, la résolution d'envoi ou la fréquence d'images est différente de la résolution source ou de la fréquence d'images), mais la durée que nous avons limitée, outbound-rtp.qualityLimitationDurations , peut être plus utile que la fréquence de modification de la résolution ou de la fréquence d'images. |
.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
|
Taux récent de paquets contenant la correction d'erreur: inbound-rtp.fecPacketsReceived - inbound-rtp.fecPacketsDiscarded |
.packetsReceived
|
inbound-rtp.packetsReceived
|
.googJitterBufferMs
|
inbound-rtp.jitterBufferDelay /inbound-rtp.jitterBufferEmittedCount
|
.googTargetDelayMs (vidéo) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googPreferredJitterBufferMs (audio) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googExpandRate
|
Taux récent d'échantillons masqués: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Ratio récent d'échantillons masqués pendant que le flux n'était pas silencieux: sur (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Taux récent d'échantillons supprimés afin d'accélérer la vitesse de lecture: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Taux récent d'échantillons synthétisés pour ralentir la vitesse de lecture: 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
|
Seule la métrique "goog-metric" restante. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Ancienne métrique
VideoBwe |
Correspondance standard
outbound-rtp et candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate en tant que valeur instantanée ou outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded en moyenne |
.googActualEncBitrate
|
Les octets produits par l'encodeur correspondent aux octets de la charge utile, à l'exclusion des retransmissions: le taux de variation de outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent . |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Taux de changement de outbound-rtp.headerBytesSent + outbound-rtp.bytesSent pour le débit de flux RTP, de candidate-pair.bytesSent pour le débit candidat par ICE ou de transport.bytesSent pour le débit par transport |
.googRetransmitBitrate
|
Plage de variation de outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
L'API standard est compatible avec la diffusion simultanée
Si vous utilisez la diffusion simultanée, vous avez peut-être remarqué que l'ancienne API ne signale qu'un seul numéro SSRC, même si vous utilisez la diffusion simultanée pour envoyer (par exemple) trois flux RTP sur trois fichiers SSRC distincts.
L'API standard ne partage pas cette limitation et renvoie trois objets de statistiques outbound-rtp
, une pour chacune des chaînes SSRC. Cela signifie que vous pouvez analyser chaque flux RTP individuellement, mais cela signifie également que pour obtenir le débit total de tous les flux d'envoi RTP, vous devrez les agréger vous-même.
En revanche, les flux SVC ou RTP avec plusieurs couches spatiales configurées via l'API scalabilityMode
apparaissent toujours sous la forme d'un outbound-rtp
unique, car ils sont envoyés via une seule SSRC.
Si vous avez besoin de plus de temps pour la migration
Lorsque l'ancienne API est supprimée dans Chrome 117, son utilisation génère une exception. Si vous ne parvenez pas à migrer votre code à temps, la phase d'évaluation pour l'API getStats() basée sur le rappel RTCPeerConnection accorde plus de temps aux sites Web enregistrés pour la migration. Avec un jeton d'évaluation de l'origine, l'ancienne API getStats() peut continuer d'être utilisée jusqu'à Chrome 121.