Die alte getStats()
WebRTC API wird in Chrome 117 entfernt. Daher müssen Apps, die sie verwenden, zur Standard-API migrieren. In diesem Artikel wird erläutert, wie Sie Ihren Code migrieren und was Sie tun können, wenn Sie mehr Zeit für diese Änderung benötigen.
Bisher gab es zwei konkurrierende Versionen der WebRTC getStats()
API. Die alte getStats()-API, die vor der Standardisierung entwickelt wurde und ein Callback-Argument annimmt, und die standardisierte und weithin unterstützte API, die ein Promise zurückgibt.
Die Standard-API ist funktionsreicher und bietet klar definierte Messwerte, die in der W3C-Spezifikation Identifiers for WebRTC's Statistics API öffentlich dokumentiert sind. Die Spezifikation enthält Beschreibungen aller in diesem Leitfaden aufgeführten und vieler weiterer Messwerte.
Ab Chrome 117 wird in der stabilen Version eine Ausnahme für die alte getStats()
API geworfen. Die Ausnahme wird nach und nach eingeführt. Folgen Sie dieser Anleitung, um die Umstellung auf die Standard-API zu erleichtern.
Legacy- und Standardstatistiktypen
Eine vollständige Liste der Standardstatistiktypen findest du in der Spezifikation im Enum RTCStatsType. Dazu gehört auch, welche Statistikwörterbuchdefinition die für jeden Typ erfassten Messwerte beschreibt.
Die Statistikobjekte haben alle ein „id“-Attribut, das das zugrunde liegende Objekt über mehrere getStats()
-Aufrufe hinweg eindeutig identifiziert. Das gleiche Objekt hat jedes Mal dieselbe ID, wenn die Methode aufgerufen wird. Das ist nützlich, um die Änderungsrate von Messwerten zu berechnen. Im nächsten Abschnitt finden Sie ein Beispiel. Die IDs bilden auch Referenzbeziehungen. Beispiel: Das Statistikobjekt outbound-rtp
verweist ü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 bietet die folgenden Statistiktypen, die den Standardtypen entsprechen:
Legacy-Typ |
Standardtyp |
---|---|
ssrc
|
Steht für einen RTP-Stream und Messwerte zum zugehörigen MediaStreamTrack .Die Standardtypen dafür sind inbound-rtp (für empfangene RTP-Streams und die zugehörigen Remote-MediaStreamTrack ), outbound-rtp (für gesendete RTP-Streams) und media-source (für lokale MediaStreamTrack -Messwerte, die mit einem gesendeten RTP-Stream verknüpft sind). RTP-Stream-Messwerte enthalten auch Informationen zum Encoder oder Decoder, der vom RTP-Stream verwendet wird. |
VideoBwe
|
Messwerte zur Bandbreitenschätzung, Zielbitrate, Encoder-Bitrate und tatsächliche Bitrate. Diese Messwerttypen sind Teil der RTP-Messwerte ( outbound-rtp und inbound-rtp ) und der ICE-Kandidatenpaar-Messwerte (candidate-pair ). |
googComponent
|
Stellt den Transport (ICE und DTLS) dar. Die Standardversion ist transport . |
localcandidate and remotecandidate
|
Stellt einen ICE-Kandidaten dar. Die Standardversionen sind local-candidate und remote-candidate . |
googCandidatePair
|
Stellt ein ICE-Kandidatenpaar dar, also die Kombination aus einem lokalen und einem Remote-Kandidaten. Die Standardversion ist candidate-pair . |
googCertificate
|
Steht für ein Zertifikat, das vom DTLS-Transport verwendet wird. Die Standardversion ist certificate . |
googLibjingleSession
|
Steht für die RTCPeerConnection . Der Inhalt entspricht zwar keinem Element im Standard, aber dem RTCPeerConnection ist ein Typ zugewiesen: peer-connection . |
In der Legacy API nicht vorhanden |
Diese Statistiktypen wurden der Standard-API hinzugefügt, da es keinen entsprechenden älteren Typ gibt:
|
Zuordnung von Legacy- zu Standardmesswerten
Diese Zuordnung soll Entwicklern dabei helfen, herauszufinden, welcher alte Messwert welchem Standardmesswert entspricht. Beachten Sie jedoch, dass für den entsprechenden Messwert möglicherweise andere Einheiten verwendet werden oder er als Gesamtzähler und nicht als Momentanwert ausgedrückt wird. Messwertdefinitionen finden Sie in der Spezifikation.
Die Standard-API gibt bevorzugt Gesamtzähler anstelle von Raten an. Das bedeutet, dass die App die entsprechende Rate (z. B. die Bitrate) wie in der alten API ermitteln muss, indem sie die Differenz zwischen zwei getStats()
-Aufrufen berechnet. 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;
Die Berechnung von Preisen und Durchschnittswerten auf diese Weise mag auf den ersten Blick wie ein umständlicher zusätzlicher Schritt erscheinen. Der Vorteil besteht jedoch darin, dass Sie so Durchschnittswerte für ein beliebiges gewünschtes Zeitintervall erhalten. Wenn Sie die Standard-API seltener aufrufen als mit der bisherigen API, können Sie einige Leistungsvorteile erzielen.
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 (Rückwärtssuche 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 localcandidate oben. |
Wie 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 candidate-pair.requestsReceived oder candidate-pair.responsesReceived in letzter Zeit erhöht wurde.
|
.googLocalAddress
|
local-candidate.address ( local-candidate über candidate-pair.localCandidateId suchen) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Entspricht local-candidate.protocol und remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable ist ein boolescher Wert, der angibt, ob candidate-pair.responsesReceived vor Kurzem erhöht wurde.
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
Die aktive Verbindung bezieht sich auf das Kandidatenpaar, das derzeit vom 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 alte Messwert liegt im Bereich [0..32768], der Standardmesswert jedoch im Bereich [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . Der alte Messwert liegt im Bereich [0..32768], der Standardmesswert jedoch 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 Untertyp 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
|
Die Sende-FPS ist die Änderungsrate von outbound-rtp.framesSent , wird aber tatsächlich als outbound-rtp.framesPerSecond implementiert, was die Codierungs-FPS ist. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Die Änderungsrate von inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Die Änderungsrate von inbound-rtp.framesDecoded – inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
Wahr, wenn outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
Wahr, wenn outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
Mit dem bisherigen Messwert wird gezählt, wie oft sich die Auflösung oder Framerate aus qualityLimitationReason -bezogenen Gründen geändert hat. Das lässt sich anhand anderer Messwerte ableiten (z. B. wenn sich die Sendeauflösung oder -Framerate von der Quellauflösung oder -Framerate unterscheidet). Die Dauer der Einschränkung, outbound-rtp.qualityLimitationDurations , ist jedoch möglicherweise nützlicher als die Häufigkeit, mit der die Auflösung oder Framerate geändert 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
|
Das aktuelle Verhältnis der Pakete mit Fehlerkorrektur: 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 der verdeckten Stichproben: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Das aktuelle Verhältnis der ausgeblendeten Samples, während der Stream nicht stummgeschaltet war: (inbound-rtp.concealedSamples – inbound-rtp.silentConcealedSamples ) ÷ inbound-rtp.concealedSamples |
.googAccelerateRate
|
Das aktuelle Verhältnis der Stichproben, die verworfen wurden, um die Wiedergabegeschwindigkeit zu beschleunigen: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Das aktuelle Verhältnis der Samples, die synthetisiert wurden, um die Wiedergabegeschwindigkeit zu verlangsamen: 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 Google-Messwert. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Legacy-Messwert
VideoBwe |
Standardkorrespondenzoutbound-rtp und candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate als Momentanwert oder outbound-rtp.totalEncodedBytesTarget ÷ outbound-rtp.framesEncoded als Durchschnitt |
.googActualEncBitrate
|
Die vom Encoder erzeugten Bytes sind die Nutzlast-Byte, ausgenommen die Wiederholungen: 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 RTP-Stream-Bitrate, candidate-pair.bytesSent für die ICE-Kandidaten-Bitrate oder transport.bytesSent für die Transport-Bitrate |
.googRetransmitBitrate
|
Der Änderungsbereich von outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
Die Standard-API unterstützt Simulcasts.
Wenn du Simulcast verwendest, hast du vielleicht bemerkt, dass die alte API nur einen einzelnen SSRC meldet, auch wenn du mit Simulcast beispielsweise drei RTP-Streams über drei separate SSRCs sendest.
Diese Einschränkung gilt nicht für die Standard-API. Sie gibt drei outbound-rtp
-Statistikobjekte zurück, eines für jeden SSRC. Das bedeutet, dass du jeden RTP-Stream einzeln analysieren kannst. Wenn du jedoch die Gesamtbitrate aller RTP-Sendestreams ermitteln möchtest, musst du sie selbst zusammenfassen.
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 bei der Verwendung eine Ausnahme ausgelöst. Wenn Sie Ihren Code nicht rechtzeitig migrieren können, erhalten Sie mit dem Ursprungstest für die callbackbasierte getStats() API von RTCPeerConnection mehr Zeit für die Migration. Mit einem Ursprungstest-Token kann die alte getStats() API bis Chrome 121 weiter verwendet werden.