WebRTC: Legacy getStats()-migratiegids

Henrik Boström
Henrik Boström

De oude getStats() WebRTC API wordt verwijderd in Chrome 117. Daarom moeten apps die hiervan gebruikmaken, migreren naar de standaard API. In dit artikel wordt uitgelegd hoe u uw code kunt migreren en wat u moet doen als u meer tijd nodig heeft om deze wijziging door te voeren.

Historisch gezien zijn er twee concurrerende versies van de WebRTC getStats() API geweest. De oude getStats() API, die dateert van vóór het standaardisatieproces en een callback-argument accepteert, en de gestandaardiseerde en breed ondersteunde API die een belofte teruggeeft.

De standaard API is rijker aan functies en beschikt over goed gedefinieerde statistieken die openbaar zijn gedocumenteerd in de W3C-specificatie Identifiers for WebRTC's Statistics API . De specificatie bevat beschrijvingen van elke statistiek die in deze handleiding wordt vermeld, en nog veel meer.

Vanaf Chrome 117 genereert de oude getStats() API een uitzondering in het stabiele releasekanaal (het genereren van uitzonderingen wordt geleidelijk uitgerold). Volg deze handleiding om uw overstap naar de standaard API te vergemakkelijken.

Legacy versus standaardstatistieken

De volledige lijst met standaardstatistiekentypen kunt u vinden door naar de RTCStatsType- opsomming in de specificatie te kijken. Dit omvat onder meer welke definitie van het statistiekenwoordenboek de voor elk type verzamelde statistieken beschrijft.

De stats-objecten hebben allemaal een id-attribuut dat het onderliggende object op unieke wijze identificeert via meerdere getStats() aanroepen. Telkens wanneer de methode wordt aangeroepen, heeft hetzelfde object dezelfde ID. Dit is handig voor het berekenen van de mate waarin statistieken veranderen (er staat een voorbeeld in de volgende sectie). De ID's vormen ook referentierelaties. Het outbound-rtp stats-object verwijst bijvoorbeeld naar het bijbehorende media-source stats-object via het outbound-rtp.mediaSourceId attribuut. Als je alle ...Id relaties tekent, krijg je een grafiek.

De oude API heeft de volgende typen statistieken, die als volgt overeenkomen met de standaardtypen:


Legacy-type

Standaard type
ssrc
Vertegenwoordigt een RTP-stream en statistieken over de bijbehorende MediaStreamTrack .


De standaardtypen hiervoor zijn inbound-rtp (voor ontvangst-RTP-streams en de bijbehorende externe MediaStreamTrack ), outbound-rtp (voor verzend-RTP-streams) en media-source (voor lokale MediaStreamTrack statistieken die zijn gekoppeld aan een verzend-RTP-stream). RTP-streamstatistieken bevatten ook informatie over de encoder of decoder die door de RTP-stream wordt gebruikt.
VideoBwe
Geschatte bandbreedte, doelbitsnelheid, encoderbitsnelheid en werkelijke bitsnelheid. Dit soort statistieken maken deel uit van de RTP-statistieken ( outbound-rtp en inbound-rtp ) en de ICE-kandidaatpaarstatistieken ( candidate-pair ).
googComponent
Vertegenwoordigt het transport (ICE en DTLS). De standaardversie is transport .
localcandidate and remotecandidate
Vertegenwoordigt een ICE-kandidaat. De standaardversie is local-candidate en remote-candidate .
googCandidatePair
Vertegenwoordigt een ICE-kandidaatpaar, dat bestaat uit een combinatie van een lokale en een externe kandidaat. De standaardversie is candidate-pair .
googCertificate
Vertegenwoordigt een certificaat dat wordt gebruikt door het DTLS-transport. De standaardversie is certificate .
googLibjingleSession
Vertegenwoordigt de RTCPeerConnection . Hoewel de inhoud ervan op niets in de standaard betrekking heeft, heeft de standaard wel een type dat is gekoppeld aan RTCPeerConnection : peer-connection .

Ontbreekt in verouderde API

Deze statistiekentypen zijn toegevoegd aan de standaard-API en hebben geen corresponderend verouderd type:
  • codec : een codec die momenteel wordt gebruikt door een RTP-stream, voor codering of decodering. Dit is een subset van de codecs waarover in de SDP is onderhandeld.
  • remote-inbound-rtp : de inkomende RTP-stream van een extern eindpunt die overeenkomt met een uitgaande RTP-stream die dit eindpunt verzendt ( outbound-rtp ). Het wordt gemeten op het externe eindpunt en gerapporteerd in een RTCP Receiver Report (RR) of RTCP Extended Report (XR).
  • remote-outbound-rtp : de uitgaande RTP-stream van een extern eindpunt die overeenkomt met een inkomende RTP-stream die dit eindpunt ontvangt ( inbound-rtp ). Het wordt gemeten op het externe eindpunt en gerapporteerd in een RTCP Sender Report (SR).
  • media-playout : Gegevens over de weergave van een externe MediaStreamTrack die is gekoppeld aan een inkomende RTP-stream ( inbound-rtp ).
  • data-channel : vertegenwoordigt een RTCDataChannel .

Verouderd naar standaard metrische gegevenstoewijzing

Deze mapping is bedoeld om ontwikkelaars te helpen bepalen welke oude statistiek overeenkomt met welke standaardstatistiek. Houd er echter rekening mee dat de overeenkomstige statistiek verschillende eenheden kan gebruiken of kan worden uitgedrukt als een totaalteller in plaats van een momentane waarde. Raadpleeg de specificatie voor metrische definities.
De standaard-API geeft er de voorkeur aan totaaltellers weer te geven in plaats van tarieven. Dit betekent dat om de overeenkomstige snelheid (bijvoorbeeld bitrate) te krijgen, zoals in de oude API, de app de gemiddelde snelheid moet berekenen door de delta tussen twee getStats() aanroepen te nemen. Bijvoorbeeld:

// 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;

Het op deze manier zelf berekenen van tarieven en gemiddelden lijkt misschien een omslachtige extra stap, maar het heeft het voordeel dat u gemiddelden kunt krijgen over elk gewenst tijdsinterval. Het minder vaak aanroepen van de standaard API dan u anders met de oudere API zou hebben gedaan, heeft enkele prestatievoordelen.

Verouderde statistiek
googCertificate
Standaard correspondentie
certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
Verouderde statistiek
googComponent
Standaard correspondentie
transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
Verouderde statistiek
localcandidate
Standaard correspondentie
local-candidate of candidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (reverse lookup 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
Verouderde statistiek
remotecandidate
Standaard correspondentie
remote-candidate
Hetzelfde als localcandidate hierboven. Hetzelfde als local-candidate hierboven.
Verouderde statistiek
googCandidatePair
Standaard correspondentie
candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(zoek remote-candidate op via
candidate-pair.remoteCandidateId )
.googReadable googReadable is een booleaanse waarde die aangeeft of we onlangs candidate-pair.requestsReceived of candidate-pair.responsesReceived hebben verhoogd of niet
.googLocalAddress local-candidate.address
( local-candidate opzoeken via
candidate-pair.localCandidateId )
.consentRequestsSent candidate-pair.consentRequestsSent
.googTransportType Hetzelfde als local-candidate.protocol en remote-candidate.protocol .
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable is een booleaanse waarde die aangeeft of we onlangs candidate-pair.responsesReceived
.googRemoteAddress remote-candidate.address
.googRtt candidate-pair.currentRoundTripTime
.googActiveConnection De actieve verbinding verwijst naar het kandidaatpaar dat momenteel door het transport is geselecteerd, bijvoorbeeld waarbij 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
Verouderde statistiek
ssrc
Standaard correspondentie
inbound-rtp , outbound-rtp , media-source
.audioInputLevel media-source.audioLevel . De oude metriek ligt binnen het bereik [0..32768], maar de standaard metriek ligt binnen het bereik [0..1].
.audioOutputLevel
inbound-rtp.audioLevel . De oude metriek ligt binnen het bereik [0..32768], maar de standaard metriek ligt binnen het bereik [0..1].
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier voor lokale MediaStreamTrack en inbound-rtp.trackIdentifier voor externe MediaStreamTrack
.googRtt remote-inbound-rtp.roundTripTime (zie outbound-rtp.remoteId )
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName De codecnaam is het subtype van het mimetype "type/subtype", codec.mimeType (zie inbound-rtp.codecId en outbound-rtp.codecId )
.transportId inbound-rtp.transportId en outbound-rtp.transportId
.mediaType inbound-rtp.kind en outbound-rtp.kind media-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergy en media-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDuration en media-source.totalSamplesDuration
.ssrc inbound-rtp.ssrc en outbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentType en outbound-rtp.contentType
.googFrameWidthInput media-source.width
.googFrameHeightInput media-source.height
.googFrameRateInput media-source.framesPerSecond
.googFrameWidthSent outbound-rtp.frameWidth
.googFrameHeightSent outbound-rtp.frameHeight
.googFrameRateSent
Hoewel de verzend-FPS de veranderingssnelheid van outbound-rtp.framesSent is, wordt dit feitelijk geïmplementeerd als outbound-rtp.framesPerSecond , dat FPS codeert.
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
De wijzigingssnelheid van inbound-rtp.framesDecoded
.googFrameRateOutput
De mate van verandering van inbound-rtp.framesDecoded - inbound-rtp.framesDropped
.hugeFramesSent outbound-rtp.hugeFramesSent
.qpSum

inbound-rtp.qpSum en outbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime / outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementation en outbound-rtp.encoderImplementation

.googCpuLimitedResolution
Waar als outbound-rtp.qualityLimitationReason == "cpu"
.googBandwidthLimitedResolution
Waar als outbound-rtp.qualityLimitationReason == "bandwidth"
.googAdaptationChanges
De oude statistiek telt het aantal keren dat de resolutie of framesnelheid is gewijzigd om redenen die verband houden met qualityLimitationReason . Dit kan worden afgeleid uit andere statistieken (bijvoorbeeld dat de verzendresolutie of framesnelheid verschilt van de bronresolutie of framesnelheid), maar de duur dat we beperkt zijn, outbound-rtp.qualityLimitationDurations , kan nuttiger zijn dan hoe vaak resolutie of framesnelheid gewijzigd, is opnieuw geconfigureerd.
.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
De recente verhouding van pakketten met foutcorrectie: 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
De recente verhouding van verborgen voorbeelden: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate De recente verhouding van verborgen monsters terwijl de stream niet stil was: of ( inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples
.googAccelerateRate De recente verhouding van samples die zijn weggegooid om de afspeelsnelheid te versnellen: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
De recente verhouding van samples die zijn gesynthetiseerd om de afspeelsnelheid te vertragen: 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
De enige overgebleven Google-statistiek. inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
Verouderde statistiek
VideoBwe
Standaard correspondentie
outbound-rtp en candidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate als een momentane waarde of outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded als een gemiddelde
.googActualEncBitrate De door de encoder geproduceerde bytes zijn de payload-bytes, met uitzondering van hertransmissies: de veranderingssnelheid van outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay / outbound-rtp.packetsSent
.googTransmitBitrate De wijzigingssnelheid van outbound-rtp.headerBytesSent + outbound-rtp.bytesSent voor bitrate per RTP-stream, candidate-pair.bytesSent voor kandidaat-bitrate per ICE of transport.bytesSent voor bitrate per transport
.googRetransmitBitrate Het wijzigingsbereik van outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

De standaard API is simulcast-bewust

Als u simulcast gebruikt, is het u misschien opgevallen dat de oude API slechts één enkele SSRC rapporteert, zelfs als u simulcast gebruikt om (bijvoorbeeld) drie RTP-streams over drie afzonderlijke SSRC's te verzenden.

De standaard-API deelt deze beperking niet en retourneert drie outbound-rtp statistiekobjecten, één voor elk van de SSRC's. Dit betekent dat u elke RTP-stream afzonderlijk kunt analyseren, maar het betekent ook dat u, om de totale bitsnelheid van alle RTP-verzendstreams te verkrijgen, deze zelf moet aggregeren.

SVC-streams of RTP-streams met meerdere ruimtelijke lagen geconfigureerd via de scalabilityMode API verschijnen daarentegen nog steeds als een enkele outbound-rtp omdat deze via een enkele SSRC worden verzonden.

Als u meer tijd nodig heeft voor de migratie

Wanneer de oude API in Chrome 117 wordt verwijderd, genereert het gebruik ervan een uitzondering. Als u uw code niet op tijd kunt migreren, geeft de oorspronkelijke proefversie van de RTCPeerConnection callback-gebaseerde getStats() API geregistreerde websites meer tijd om te migreren. Met een origin-proeftoken kan de oude getStats() API blijven worden gebruikt tot Chrome 121.