L'ancienne API WebRTC getStats()
sera supprimée dans Chrome 117. Par conséquent, les applications qui l'utilisent devront migrer vers l'API standard. Cet article explique comment migrer votre code et comment procéder si vous avez besoin de plus de temps pour effectuer cette modification.
Par le passé, il existait deux versions concurrentes de l'API WebRTC getStats()
. L'ancienne API getStats() qui date d'avant le processus de normalisation et qui accepte un argument de rappel, et l'API normalisée et largement compatible qui renvoie une promesse.
L'API standard est plus complète et dispose de métriques bien définies, documentées publiquement dans la spécification du W3C Identifiers for WebRTC's Statistics API (Identifiants pour l'API de statistiques WebRTC). La spécification comprend des descriptions de chaque métrique listée dans ce guide et bien plus encore.
À partir de Chrome 117, l'ancienne API getStats()
génèrera une exception dans le canal de version stable (le déclenchement de l'exception sera déployé progressivement). Suivez ce guide pour faciliter la transition vers l'API standard.
Types de statistiques anciens et standards
Pour obtenir la liste complète des types de statistiques standards, consultez 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 de statistiques ont tous un attribut d'ID qui identifie de manière unique l'objet sous-jacent dans plusieurs appels getStats()
. Le même objet aura le même ID à chaque appel de la méthode. Cela permet de calculer le taux de variation des métriques (un exemple est fourni dans la section suivante). Les ID établissent également des relations de référence. 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 propose les types de statistiques suivants, qui correspondent aux types standards comme suit:
Ancien type |
Type standard |
---|---|
ssrc
|
Représente un flux RTP et des métriques sur le MediaStreamTrack associé.Les types standards sont inbound-rtp (pour les flux RTP de réception et le MediaStreamTrack distant associé), outbound-rtp (pour les flux RTP d'envoi) 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 de 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. La version standard est local-candidate et remote-candidate . |
googCandidatePair
|
Représente une paire de candidats ICE, qui est une 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 le RTCPeerConnection . Bien que son contenu ne corresponde à rien dans la norme, la norme comporte un type associé à RTCPeerConnection : peer-connection . |
Introuvable dans l'ancienne API |
Les types de statistiques suivants ont été ajoutés à l'API standard, mais ne disposent d'aucun type ancien correspondant:
|
Mappage des métriques anciennes vers les métriques standards
Ce mappage vise à aider les développeurs à trouver quelle métrique ancienne correspond à quelle 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. Consultez la spécification pour connaître les définitions des métriques.
L'API standard préfère exposer les compteurs totaux plutôt que les taux. Cela signifie que pour obtenir le débit correspondant (par exemple, le débit) comme dans l'ancienne API, l'application doit calculer le débit moyen en prenant 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;
Le fait de devoir calculer vous-même les tarifs et les moyennes peut sembler une étape supplémentaire fastidieuse, mais vous permet d'obtenir des moyennes sur n'importe quelle période souhaitée. Appeler l'API standard moins souvent que vous auriez pu le faire avec l'ancienne API présente certains avantages en termes de performances.
Métrique ancienne
googCertificate |
Correspondance standard
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Métrique ancienne
googComponent |
Correspondance standard
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Métrique ancienne
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
|
Métrique ancienne
remotecandidate |
Correspondance standard
remote-candidate |
---|---|
Identique à localcandidate ci-dessus. |
Identique à local-candidate ci-dessus. |
Métrique ancienne
googCandidatePair |
Correspondance standard
candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType (rechercher 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 (rechercher local-candidate via candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Identique à local-candidate.protocol et remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable est une valeur booléenne indiquant 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 lorsque 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
|
Métrique ancienne
ssrc |
Correspondance standard
inbound-rtp , outbound-rtp , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . L'ancienne métrique se situe dans la plage [0..32768], tandis que la métrique standard se situe dans la plage [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . L'ancienne métrique se situe dans la plage [0..32768], tandis que la métrique standard se situe 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 du type MIME "type/subtype", 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 la fréquence de modification de outbound-rtp.framesSent , il est en fait implémenté en tant que outbound-rtp.framesPerSecond , qui encode les 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
|
Vrai si outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
Vrai si outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
L'ancienne métrique comptabilise le nombre de fois où la résolution ou la fréquence d'images a changé 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 ou de la fréquence d'images source), mais la durée pendant laquelle nous avons été limités, outbound-rtp.qualityLimitationDurations , peut être plus utile que la fréquence à laquelle la résolution ou la fréquence d'images a été reconfigurée. |
.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
|
Ratio récent des paquets contenant une 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
|
Ratio récent des échantillons masqués: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Ratio récent des échantillons masqués lorsque le flux n'était pas silencieux : (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Ratio récent des échantillons supprimés pour accélérer la vitesse de lecture: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Ratio récent des échantillons synthétisés afin de 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 métrique Google restante. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Métrique ancienne
VideoBwe |
Correspondance standardoutbound-rtp et candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate en tant que valeur instantanée ou outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded en tant que moyenne |
.googActualEncBitrate
|
Les octets produits par l'encodeur sont les octets de la charge utile, à l'exclusion des nouvelles transmissions: le taux de variation de outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Taux de variation de outbound-rtp.headerBytesSent + outbound-rtp.bytesSent pour le débit par flux RTP, candidate-pair.bytesSent pour le débit par candidat ICE ou 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 le simulcast
Si vous utilisez la diffusion simultanée, vous avez peut-être remarqué que l'ancienne API ne signale qu'un seul SSRC, même lorsque vous utilisez la diffusion simultanée pour envoyer (par exemple) trois flux RTP sur trois SSRC distincts.
L'API standard ne partage pas cette limitation et renvoie trois objets statistiques outbound-rtp
, un pour chacun des SSRC. Cela signifie que vous pouvez analyser chaque flux RTP individuellement, mais aussi que vous devrez les agréger vous-même pour obtenir le débit total de tous les flux d'envoi RTP.
En revanche, les flux SVC ou RTP avec plusieurs couches spatiales configurées via l'API scalabilityMode
s'affichent toujours sous la forme d'un seul outbound-rtp
, car ils sont envoyés via un seul SSRC.
Si vous avez besoin de plus de temps pour la migration
Lorsque l'ancienne API sera supprimée dans Chrome 117, son utilisation générera une exception. Si vous ne parvenez pas à migrer votre code à temps, l'essai d'origine pour l'API getStats() basée sur le rappel RTCPeerConnection offre aux sites Web enregistrés plus de temps pour effectuer la migration. Avec un jeton de phase d'évaluation de l'origine, l'ancienne API getStats() peut continuer à être utilisée jusqu'à Chrome 121.