Die alte getStats()
WebRTC API wird in Chrome 117 entfernt. Daher müssen Apps, die sie verwenden, zur Standard-API migriert werden. In diesem Artikel erfahren Sie, wie Sie Ihren Code migrieren und was Sie tun können, wenn Sie mehr Zeit für diese Änderung benötigen.
In der Vergangenheit gab es zwei konkurrierende Versionen der WebRTC getStats()
API. Die alte getStats()-API, die aus der Zeit vor dem Standardisierungsprozess stammt und ein Callback-Argument verwendet, und die standardisierte und allgemein unterstützte API, die ein Promise zurückgibt.
Die Standard-API bietet mehr Funktionen und klar definierte Messwerte, die öffentlich in der W3C-Spezifikation Identifiers for WebRTC's Statistics API dokumentiert sind. Die Spezifikation enthält unter anderem Beschreibungen aller in diesem Leitfaden aufgeführten Messwerte.
Ab Chrome 117 löst die alte getStats()
API eine Ausnahme in der stabilen Release-Version aus. Diese wird nach und nach eingeführt. Folgen Sie dieser Anleitung, um den Übergang zur Standard-API zu erleichtern.
Bisherige und Standard-Statistiktypen
Die vollständige Liste der Standard-Statistiktypen finden Sie in der RTCStatsType-Enum in der Spezifikation. Dazu gehört, welche Definition des Statistikwörterbuchs die für jeden Typ erfassten Messwerte beschreibt.
Alle Statistikobjekte haben ein ID-Attribut, das das zugrunde liegende Objekt über mehrere getStats()
-Aufrufe hinweg eindeutig identifiziert. Dasselbe Objekt hat bei jedem Aufruf der Methode dieselbe ID. Dies ist nützlich, um die Änderungsrate von Messwerten zu berechnen. Im nächsten Abschnitt finden Sie ein Beispiel. Die IDs bilden auch Beziehungen von Referenzen. Beispielsweise verweist das Statistikobjekt outbound-rtp
über das Attribut outbound-rtp.mediaSourceId
auf das zugehörige Statistikobjekt media-source
. Wenn Sie alle ...Id
-Beziehungen zeichnen, erhalten Sie ein Diagramm.
Die alte API hat die folgenden Statistiktypen, die den Standardtypen wie folgt entsprechen:
Alterstyp |
Standardtyp |
---|---|
ssrc
|
Steht für einen RTP-Stream und Messwerte zum zugehörigen MediaStreamTrack .Die Standardtypen dafür sind inbound-rtp (für RTP-Empfangsstreams und die zugehörige Remote-MediaStreamTrack ), outbound-rtp (für RTP-Sendestreams) und media-source (für lokale MediaStreamTrack -Messwerte, die mit einem RTP-Sendestream verknüpft sind). RTP-Stream-Messwerte enthalten auch Informationen zum Encoder oder Decoder, der vom RTP-Stream verwendet wird. |
VideoBwe
|
Messwerte zur Bandbreitenschätzung, Ziel-Bitrate, Encoder-Bitrate und tatsächliche Bitrate. Diese Messwerte sind Teil der RTP-Messwerte ( outbound-rtp und inbound-rtp ) und der ICE-Kandidatenpaare (candidate-pair ). |
googComponent
|
Repräsentiert den Transport (ICE und DTLS). Die Standardversion ist transport . |
localcandidate and remotecandidate
|
Repräsentiert einen ICE-Kandidaten. Die Standardversion ist local-candidate und remote-candidate . |
googCandidatePair
|
Stellt ein ICE-Kandidatenpaar dar, bei dem es sich um ein Paar aus einem lokalen und einem Remote-Kandidaten handelt. Die Standardversion ist candidate-pair . |
googCertificate
|
Stellt ein Zertifikat dar, das vom DTLS-Transport verwendet wird. Die Standardversion ist certificate . |
googLibjingleSession
|
Steht für RTCPeerConnection . Der Inhalt ist im Standard zwar nicht zugeordnet, aber der Standard hat einen Typ, der mit RTCPeerConnection verknüpft ist: peer-connection . |
Fehlt in der Legacy-API |
Diese Statistiktypen wurden der Standard-API hinzugefügt, für die es keinen entsprechenden Legacy-Typ gibt:
|
Zuordnung von Legacy- zu Standardmesswerten
Diese Zuordnung soll Entwicklern helfen, herauszufinden, welcher alte Messwert welchem Standardmesswert entspricht. Für den entsprechenden Messwert können jedoch andere Einheiten verwendet oder als Gesamtzähler und nicht als momentaner Wert ausgedrückt werden. Die Messwertdefinitionen finden Sie in der Spezifikation.
Die Standard-API bevorzugt die Angabe von Gesamtzählern anstelle von Preisen. Das bedeutet: Um die entsprechende Rate (z. B. die Bitrate) wie in der Legacy-API zu erhalten, muss die App die durchschnittliche Rate anhand der Differenz zwischen zwei getStats()
-Aufrufen berechnen. Beispiel:
// 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;
Raten und Durchschnittswerte selbst berechnen zu müssen, mag wie ein umständlicher zusätzlicher Schritt erscheinen, bietet aber den Vorteil, dass Sie über jedes gewünschte Zeitintervall Durchschnittswerte ermitteln können. Wenn die Standard-API seltener aufgerufen wird, als dies bei der alten API sonst der Fall wäre, hat dies einige Leistungsvorteile.
Legacy-Messwert
googCertificate |
Standardkorrespondenz
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Legacy-Messwert
googComponent |
Standardkorrespondenz
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Legacy-Messwert
localcandidate |
Standardkorrespondenz
local-candidate oder candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (umgekehrte Suche candidate-pair über 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
|
Legacy-Messwert
remotecandidate |
Standardkorrespondenz
remote-candidate |
---|---|
Wie bei localcandidate oben. |
Wie bei local-candidate oben. |
Legacy-Messwert
googCandidatePair |
Standardkorrespondenz
candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType ( remote-candidate über candidate-pair.remoteCandidateId suchen) |
.googReadable
|
googReadable ist ein boolescher Wert, der angibt, ob vor Kurzem candidate-pair.requestsReceived oder candidate-pair.responsesReceived erhöht wurde.
|
.googLocalAddress
|
local-candidate.address ( local-candidate über candidate-pair.localCandidateId suchen) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Wie bei local-candidate.protocol und remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable ist ein boolescher Wert, der angibt, ob kürzlich candidate-pair.responsesReceived erhöht wurde oder nicht.
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
Die aktive Verbindung bezieht sich auf das Kandidatenpaar, das derzeit durch den Transport ausgewählt wird, z. B. wenn 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
|
Legacy-Messwert
ssrc |
Standardkorrespondenz
inbound-rtp , outbound-rtp , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . Der Legacy-Messwert liegt im Bereich [0–32768], der Standardmesswert im Bereich [0–1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel Der Legacy-Messwert liegt im Bereich [0–32768], der Standardmesswert im Bereich [0–1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier für lokale MediaStreamTrack s und inbound-rtp.trackIdentifier für Remote-MediaStreamTrack s |
.googRtt
|
remote-inbound-rtp.roundTripTime (siehe outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Der Codec-Name ist der Subtyp des MIME-Typs „type/subtype“, codec.mimeType (siehe inbound-rtp.codecId und outbound-rtp.codecId ). |
.transportId
|
inbound-rtp.transportId und outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind und outbound-rtp.kind oder media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
inbound-rtp.totalAudioEnergy und media-source.totalAudioEnergy
|
ssrc.totalSamplesDuration
|
inbound-rtp.totalSamplesDuration und media-source.totalSamplesDuration
|
.ssrc
|
inbound-rtp.ssrc und outbound-rtp.ssrc
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType und outbound-rtp.contentType |
.googFrameWidthInput
|
media-source.width
|
.googFrameHeightInput
|
media-source.height
|
.googFrameRateInput
|
media-source.framesPerSecond
|
.googFrameWidthSent
|
outbound-rtp.frameWidth
|
.googFrameHeightSent
|
outbound-rtp.frameHeight
|
.googFrameRateSent
|
Obwohl die fps beim Senden die Änderungsrate von outbound-rtp.framesSent ist, wird dies tatsächlich als outbound-rtp.framesPerSecond implementiert, das die fps codiert. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Die Änderungsrate von inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Die Änderungsrate von inbound-rtp.framesDecoded bis inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
„True“, wenn outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
„True“, wenn outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
Mit dem Legacy-Messwert wird gezählt, wie oft sich die Auflösung oder Framerate aus qualityLimitationReason Gründen geändert hat. Aus anderen Messwerten lässt sich schließen, z. B. die Auflösung oder die Framerate beim Senden, die von der Quellauflösung oder Framerate abweicht. Allerdings ist die von uns beschränkte Dauer (outbound-rtp.qualityLimitationDurations ) möglicherweise nützlicher als die Häufigkeit, mit der die Auflösung oder die Framerate neu konfiguriert wurde. |
.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
|
Der aktuelle Anteil der Pakete mit Fehlerkorrekturen: 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
|
Das aktuelle Verhältnis von verborgenen Beispielen: inbound-rtp.concealedSamples ÷ inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Das aktuelle Verhältnis von verdeckten Samples, während der Stream nicht lautlos war: von (inbound-rtp.concealedSamples –inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Das aktuelle Verhältnis von Stichproben, die verworfen wurden, um die Spielgeschwindigkeit zu beschleunigen: inbound-rtp.removedSamplesForAcceleration ÷ inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Das aktuelle Verhältnis von Samples, die zur Verlangsamung der Playout-Geschwindigkeit synthetisiert wurden: 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
|
Der einzige verbleibende goog-Messwert inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Legacy-Messwert
VideoBwe |
Standardkorrespondenz
outbound-rtp und candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate als sofortiger Wert oder outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded als Durchschnitt |
.googActualEncBitrate
|
Die vom Encoder erzeugten Byte sind die Nutzlastbyte ohne erneute Übertragungen: die Änderungsrate von outbound-rtp.bytesSent –outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay / outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Die Änderungsrate von outbound-rtp.headerBytesSent + outbound-rtp.bytesSent für die Bitrate pro RTP-Stream, candidate-pair.bytesSent für die Bitrate pro ICE-Kandidaten oder transport.bytesSent für die Bitrate pro Transport |
.googRetransmitBitrate
|
Der Änderungsbereich von outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
Die Standard-API ist Simulcast-fähig
Wenn Sie Simulcast verwenden, haben Sie vielleicht bemerkt, dass die Legacy-API nur einen einzelnen SSRC meldet, auch wenn Sie Simulcast verwenden, um zum Beispiel drei RTP-Streams über drei separate SSRCs zu senden.
Die Standard-API teilt diese Einschränkung nicht und gibt drei outbound-rtp
-Statistikobjekte zurück, eines für jeden der SSRCs. Das bedeutet, dass Sie jeden RTP-Stream einzeln analysieren können. Um die Gesamtbitrate aller RTP-Sendestreams zu erhalten, müssen Sie sie aber selbst aggregieren.
SVC-Streams oder RTP-Streams mit mehreren über die scalabilityMode
API konfigurierten räumlichen Ebenen werden dagegen weiterhin als einzelne outbound-rtp
angezeigt, da sie über einen einzelnen SSRC gesendet werden.
Wenn Sie mehr Zeit für die Migration benötigen
Wenn die alte API in Chrome 117 entfernt wird, wird durch ihre Verwendung eine Ausnahme generiert. Wenn Sie Ihren Code nicht rechtzeitig migrieren können, gibt der Ursprungstest für die RTCPeerConnection-Callback-basierte getStats() API registrierten Websites mehr Zeit für die Migration. Mit einem Ursprungstesttoken kann die alte getStats() API bis Chrome 121 weiter verwendet werden.