Starsza wersja interfejsu WebRTC API getStats()
zostanie usunięta w Chrome 117, dlatego aplikacje korzystające z niego będą musiały zostać przeniesione do standardowego interfejsu API. Z tego artykułu dowiesz się, jak przenieść kod i co zrobić, jeśli potrzebujesz więcej czasu na wprowadzenie tej zmiany.
Wcześniej istniały 2 konkurujące wersje interfejsu WebRTC getStats()
API. Starsza wersja interfejsu API getStats(), która jest wcześniejszym procesem standaryzacji i przyjmuje argument wywołania zwrotnego, oraz ustandaryzowany i szeroko obsługiwany interfejs API, który zwraca obietnicę.
Standardowy interfejs API jest bardziej rozbudowany i zawiera dobrze zdefiniowane wskaźniki, które zostały publicznie udokumentowane w specyfikacji W3C w sekcji Identifiers for WebRTC's Statistics API. Specyfikacja zawiera opisy poszczególnych danych wymienionych w tym przewodniku i wielu innych.
Od Chrome 117 starszy interfejs API getStats()
zgłosi wyjątek w wersji stabilnej (wyjątki będą wdrażane stopniowo). Z tego przewodnika dowiesz się, jak łatwo przejść na standardowy interfejs API.
Porównanie starszych i standardowych typów statystyk
Pełną listę standardowych typów statystyk znajdziesz w wyliczeniu RTCStatsType w specyfikacji. Obejmuje to definicję słownika statystyk, która opisuje wskaźniki zebrane dla każdego typu.
Wszystkie obiekty statystyk mają atrybut id, który jednoznacznie identyfikuje bazowy obiekt w wielu wywołaniach getStats()
. Ten sam obiekt będzie mieć taki sam identyfikator przy każdym wywołaniu metody. Jest to przydatne przy obliczaniu tempa zmian danych (przykład znajdziesz w następnej sekcji). Identyfikatory tworzą również relacje odwołań. Na przykład obiekt statystyk outbound-rtp
odwołuje się za pomocą atrybutu outbound-rtp.mediaSourceId
do powiązanego obiektu statystyk media-source
. Jeśli narysujesz wszystkie relacje typu ...Id
, pojawi się wykres.
Starsza wersja interfejsu API zawiera następujące typy statystyk odpowiadające typom standardowym:
Starszy typ |
Typ standardowy |
---|---|
ssrc
|
Reprezentuje strumień RTP i dane dotyczące powiązanego elementu MediaStreamTrack .Standardowe typy tego typu to inbound-rtp (dla odbieranych strumieni RTP i powiązanych z nimi zdalnych MediaStreamTrack ), outbound-rtp (do wysyłania strumieni RTP) oraz media-source (lokalne dane MediaStreamTrack związane ze strumieniem RTP wysyłającym). Wskaźniki strumienia RTP zawierają też informacje o koderze lub dekoderze używanym przez strumień RTP. |
VideoBwe
|
Wskaźniki szacowanej przepustowości, docelowej szybkości transmisji bitów, kodera i rzeczywistej szybkości transmisji bitów. Te rodzaje danych są częścią wskaźników RTP ( outbound-rtp i inbound-rtp ) oraz wskaźników pary kandydatów ICE (candidate-pair ). |
googComponent
|
Reprezentuje transport (ICE i DTLS). Wersja standardowa to transport . |
localcandidate and remotecandidate
|
Reprezentuje kandydata ICE. Wersja standardowa to local-candidate i remote-candidate . |
googCandidatePair
|
Reprezentuje parę kandydatów ICE, czyli połączenie kandydata lokalnego i kandydata zdalnego. Wersja standardowa to candidate-pair . |
googCertificate
|
Reprezentuje certyfikat używany przez transport DTLS. Wersja standardowa to certificate . |
googLibjingleSession
|
Reprezentuje element RTCPeerConnection . Chociaż treść standardu nie jest zmapowana na jakiś standard, ma on typ powiązany z elementem RTCPeerConnection : peer-connection . |
Brak w starszym interfejsie API |
Te typy statystyk zostały dodane do standardowego interfejsu API, które nie mają odpowiedniego starszego typu:
|
Mapowanie danych starszego typu na standardowe
To mapowanie ma pomagać deweloperom w znalezieniu starszych danych odpowiadających poszczególnym standardowym danym. Pamiętaj jednak, że odpowiednie dane mogą używać innych jednostek lub być wyrażone w postaci licznika, a nie natychmiastowej wartości. Definicje danych znajdziesz w specyfikacji.
Standardowy interfejs API preferuje ujawnianie łącznej liczby liczników niż współczynniki. Oznacza to, że aby uzyskać odpowiednią szybkość (np. szybkość transmisji bitów) tak jak w starszym interfejsie API, aplikacja musi obliczyć średnią wartość, wykorzystując różnicę między 2 wywołaniami getStats()
. Na przykład:
// 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;
Samodzielne obliczanie stawek i średnich może wydawać się dodatkowym uciążliwym zadaniem, a dodatkowo w końcu pojawia się możliwość uzyskania średnich wartości w dowolnym przedziale czasu. Wywołanie standardowego interfejsu API rzadziej niż w przypadku starszej wersji interfejsu API ma pewną poprawę wydajności.
Starsze dane
, googCertificate |
Standardowa korespondencja
, certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Starsze dane
, googComponent |
Standardowa korespondencja
, transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Starsze dane
, localcandidate |
Standardowa korespondencja
+ local-candidate lub candidate-pair |
---|---|
.stunKeepaliveRequestsSent
|
candidate-pair.requestsSent (odwrotne wyszukiwanie candidate-pair przez 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
|
Starsze dane
, remotecandidate |
Standardowa korespondencja
, remote-candidate |
---|---|
Tak samo jak w przypadku powyższego localcandidate . |
Tak samo jak w przypadku powyższego local-candidate . |
Starsze dane
, googCandidatePair |
Standardowa korespondencja
, candidate-pair |
---|---|
.responsesSent
|
candidate-pair.responsesSent
|
.requestsReceived
|
candidate-pair.requestsReceived
|
.googRemoteCandidateType
|
remote-candidate.candidateType (wyszukiwanie remote-candidate przez candidate-pair.remoteCandidateId ) |
.googReadable
|
googReadable to wartość logiczna wskazująca, czy ostatnio zwiększyliśmy wartość candidate-pair.requestsReceived lub candidate-pair.responsesReceived .
|
.googLocalAddress
|
local-candidate.address (wyszukiwanie local-candidate przez candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Tak samo jak w local-candidate.protocol i remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable to wartość logiczna, która wskazuje, czy ostatnio zwiększyliśmy wartość candidate-pair.responsesReceived .
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
Aktywne połączenie odnosi się do pary kandydującej, która jest obecnie wybrana przez środki transportu, np. 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
|
Starsze dane
, ssrc |
Standardowa korespondencja
inbound-rtp , outbound-rtp , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . Starszy wskaźnik mieści się w zakresie [0..32768], ale standardowy metr jest w zakresie [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel Starszy wskaźnik mieści się w zakresie [0..32768], ale standardowy metr jest w zakresie [0..1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier dla lokalnych systemów MediaStreamTrack i inbound-rtp.trackIdentifier dla zdalnych MediaStreamTrack |
.googRtt
|
remote-inbound-rtp.roundTripTime (zobacz: outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Nazwa kodeka jest podtypem „typ/podtyp” typ MIME, codec.mimeType (zobacz inbound-rtp.codecId i outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId i outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind i outbound-rtp.kind lub media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
inbound-rtp.totalAudioEnergy i media-source.totalAudioEnergy
|
ssrc.totalSamplesDuration
|
inbound-rtp.totalSamplesDuration i media-source.totalSamplesDuration
|
.ssrc
|
inbound-rtp.ssrc i outbound-rtp.ssrc
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType i outbound-rtp.contentType |
.googFrameWidthInput
|
media-source.width
|
.googFrameHeightInput
|
media-source.height
|
.googFrameRateInput
|
media-source.framesPerSecond
|
.googFrameWidthSent
|
outbound-rtp.frameWidth
|
.googFrameHeightSent
|
outbound-rtp.frameHeight
|
.googFrameRateSent
|
Chociaż liczba klatek na sekundę podczas wysyłania to szybkość zmian elementu outbound-rtp.framesSent , w rzeczywistości ta wartość jest zaimplementowana jako outbound-rtp.framesPerSecond , co oznacza kodowanie klatek na sekundę. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Tempo zmian wartości inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Tempo zmian wartości inbound-rtp.framesDecoded –inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
Prawda, jeśli outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
Prawda, jeśli outbound-rtp.qualityLimitationReason == "bandwidth" |
.googAdaptationChanges
|
Starsze dane zliczają zmiany rozdzielczości lub liczby klatek z qualityLimitationReason przyczyn. Można wywnioskować to na podstawie innych danych (np. rozdzielczość wysyłania lub liczba klatek różnią się od rozdzielczości źródłowej czy liczby klatek), ale czas trwania ograniczenia (outbound-rtp.qualityLimitationDurations ) może być bardziej przydatny niż częstotliwość zmiany rozdzielczości lub liczby klatek. |
.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
|
Ostatni współczynnik pakietów zawierających korekcję błędów: inbound-rtp.fecPacketsReceived –inbound-rtp.fecPacketsDiscarded |
.packetsReceived
|
inbound-rtp.packetsReceived
|
.googJitterBufferMs
|
inbound-rtp.jitterBufferDelay /inbound-rtp.jitterBufferEmittedCount
|
.googTargetDelayMs (wideo) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googPreferredJitterBufferMs (audio) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googExpandRate
|
Ostatni współczynnik ukrytych próbek: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Ostatni współczynnik ukrytych próbek, gdy strumień nie był wyciszony: z (inbound-rtp.concealedSamples – inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Ostatni współczynnik próbek, które zostały odrzucone w celu przyspieszenia odtwarzania: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Ostatni współczynnik próbek, które zostały zsyntetyzowane w celu zmniejszenia prędkości odtwarzania: 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
|
Jedyny pozostały wskaźnik goog. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Starsze dane
, VideoBwe |
Standardowa korespondencja
outbound-rtp i candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate jako wartość chwilowa lub outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded jako średnią |
.googActualEncBitrate
|
Bajty utworzone przez koder to bajty ładunku, z wyłączeniem retransmisji: szybkość zmian outbound-rtp.bytesSent –outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Szybkość zmiany: outbound-rtp.headerBytesSent + outbound-rtp.bytesSent w przypadku transmisji bitów w formacie RTP, candidate-pair.bytesSent – szybkość transmisji kandydującej ICE lub transport.bytesSent – szybkość transmisji bitów na transport |
.googRetransmitBitrate
|
Zakres zmiany outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
Standardowy interfejs API obsługuje technologię Simulcast.
Jeśli korzystasz z simulcast, możesz zauważyć, że starszy interfejs API zgłasza tylko 1 SSRC, nawet jeśli używasz tej funkcji do wysyłania (np.) 3 strumieni RTP do 3 osobnych SSRC.
Standardowy interfejs API nie udostępnia tego ograniczenia i zwraca 3 obiekty statystyk outbound-rtp
, po jednym dla każdego SSRC. Oznacza to, że każdy strumień RTP możesz analizować z osobna, ale aby uzyskać całkowitą szybkość transmisji bitów wszystkich wysyłanych strumieni RTP, musisz je zagregować samodzielnie.
Strumienie SVC lub strumienie RTP z wieloma warstwami przestrzennymi skonfigurowanymi przez interfejs scalabilityMode
API są nadal wyświetlane jako pojedynczy element outbound-rtp
, ponieważ są przesyłane przez jeden SSRC.
Jeśli potrzebujesz więcej czasu na migrację
Jeśli starszy interfejs API zostanie usunięty w Chrome 117, użycie go spowoduje wygenerowanie wyjątku. Jeśli nie uda Ci się przenieść kodu na czas, testy origin dla interfejsu API getStats() opartego na wywołaniach zwrotnych RTCPeerConnection zapewnią zarejestrowanym witrynom więcej czasu na migrację. Jeśli korzystasz z tokenu testowego origin, możesz korzystać ze starszej wersji interfejsu API getStats() do wersji Chrome 121.