Stary interfejs API WebRTC getStats()
zostanie usunięty w Chrome 117, dlatego aplikacje, które z niego korzystają, będą musiały przejść na standardowy interfejs API. Z tego artykułu dowiesz się, jak przenieść kod i co zrobić, jeśli potrzebujesz więcej czasu na wprowadzenie tej zmiany.
W przeszłości istniały 2 konkurujące wersje interfejsu API WebRTC getStats()
. starszy interfejs API getStats(), który powstał przed procesem standaryzacji i przyjmuje argument funkcji wywołania zwrotnego, oraz znormalizowany i powszechnie obsługiwany interfejs API, który zwraca obietnicę.
Standardowy interfejs API jest bogatszy w funkcje i posiada dobrze zdefiniowane dane, które są publicznie udokumentowane w specyfikacji W3C Identyfikatory interfejsu Statistics API dla WebRTC. Specyfikacja zawiera opisy wszystkich danych wymienionych w tym przewodniku oraz wiele innych.
Od Chrome 117 starszy interfejs API getStats()
będzie zgłaszać wyjątek na kanale stabilnym (wyjątki będą wprowadzane stopniowo). Aby ułatwić sobie przejście na standardowy interfejs API, skorzystaj z tego przewodnika.
Stare i standardowe typy statystyk
Pełną listę standardowych typów statystyk znajdziesz w specyfikacji w enumeracji RTCStatsType. Obejmuje to definicję słownika statystyk, która opisuje dane zbierane dla każdego typu.
Wszystkie obiekty stats mają atrybut id, który jednoznacznie identyfikuje obiekt bazowy w wielu wywołaniach getStats()
. Ten sam obiekt będzie miał ten sam identyfikator za każdym razem, gdy wywołasz metodę. Jest to przydatne do obliczania szybkości zmian danych (w następnej sekcji znajdziesz przykład). Identyfikatory tworzą też relacje odsyłaczy. Na przykład obiekt statystyk outbound-rtp
odwołuje się do powiązanego obiektu statystyk media-source
za pomocą atrybutu outbound-rtp.mediaSourceId
. Jeśli narysujesz wszystkie relacje ...Id
, otrzymasz wykres.
Starszy interfejs API ma te typy statystyk, które odpowiadają standardowym typom:
Typ starszy |
Typ standardowy |
---|---|
ssrc
|
Reprezentuje strumień RTP i dane dotyczące powiązanego MediaStreamTrack .Standardowe typy to inbound-rtp (do odbierania strumieni RTP i powiązanych z nimi zdalnych MediaStreamTrack ), outbound-rtp (do wysyłania strumieni RTP) i media-source (do lokalnych danych MediaStreamTrack powiązanych z wysyłaniem strumienia RTP). Dane strumienia RTP zawierają też informacje o kodierze lub dekoderze używanym przez ten strumień. |
VideoBwe
|
Dane dotyczące szacowania przepustowości, docelowej szybkości transmisji bitów, szybkości transmisji bitów kodera i rzeczywistej szybkości transmisji bitów. Te typy danych są częścią danych RTP ( outbound-rtp i inbound-rtp ) oraz danych par 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 parę kandydatów lokalnych i zdalnych. Wersja standardowa to candidate-pair . |
googCertificate
|
Przedstawia certyfikat używany przez transport DTLS. Wersja standardowa to certificate . |
googLibjingleSession
|
Reprezentuje RTCPeerConnection . Chociaż jego zawartość nie jest mapowana na nic w standardzie, standard ma typ powiązany z RTCPeerConnection : peer-connection . |
Brak w starszym interfejsie API |
Te typy statystyk zostały dodane do standardowego interfejsu API i nie mają odpowiadających im starszych typów:
|
Mapowanie starszych danych na standardowe
Mapowanie to ma pomóc deweloperom w określaniu, które dane starsze odpowiadają danym standardowym. Pamiętaj jednak, że odpowiadające dane mogą używać innych jednostek lub być wyrażone jako całkowity licznik, a nie wartość chwilowa. Definicje danych znajdziesz w specyfikacji.
Standardowy interfejs API preferuje wyświetlanie łącznych wartości zliczników zamiast współczynników. Oznacza to, że aby uzyskać odpowiednią szybkość (np. bitrate) jak w starszym interfejsie API, aplikacja musi obliczyć średnią szybkość, biorąc pod uwagę różnicę między 2 wywołaniami funkcji 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;
Wymaganie samodzielnego obliczania stawek i średni może wydawać się uciążliwym dodatkowym krokiem, ale ma tę zaletę, że pozwala uzyskać średnie w dowolnym wybranym przedziale czasowym. Wywoływanie standardowego interfejsu API rzadziej niż w przypadku starszego interfejsu API przynosi pewne korzyści w zakresie wydajności.
Starszy typ danych
googCertificate |
Standardowa korespondencja
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Starszy typ danych
googComponent |
Standardowa korespondencja
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Starszy typ danych
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
|
Starszy typ danych
remotecandidate |
Standardowa korespondencja
remote-candidate |
---|---|
Jak localcandidate powyżej. |
Jak local-candidate powyżej. |
Starszy typ danych
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
|
To samo dotyczy local-candidate.protocol i remote-candidate.protocol . |
.googChannelId
|
candidate-pair.transportId
|
.googLocalCandidateType
|
local-candidate.candidateType
|
.googWritable
|
googWritable to wartość logiczna wskazująca, czy ostatnio zwiększono wartość parametru candidate-pair.responsesReceived .
|
.googRemoteAddress
|
remote-candidate.address
|
.googRtt
|
candidate-pair.currentRoundTripTime
|
.googActiveConnection
|
Aktywne połączenie odnosi się do pary kandydatów, która jest obecnie wybrana przez transport, 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
|
Starszy typ danych
ssrc |
Standardowa korespondencja
inbound-rtp , outbound-rtp , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . Stara wersja danych mieści się w zakresie [0,32768], a nowa – w zakresie [0,1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel . Stara wersja danych mieści się w zakresie [0,32768], a nowa – w zakresie [0,1]. |
.packetsLost
|
inbound-rtp.packetsLost
|
.googTrackId
|
media-source.trackIdentifier dla lokalnych MediaStreamTrack i inbound-rtp.trackIdentifier dla zdalnych MediaStreamTrack |
.googRtt
|
remote-inbound-rtp.roundTripTime (patrz: outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Nazwa kodeka to podtyp typu MIME „type/subtype”, 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ż FPS wysyłania to szybkość zmiany outbound-rtp.framesSent , jest ona faktycznie implementowana jako outbound-rtp.framesPerSecond , czyli FPS kodowania. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Szybkość zmian inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Skok 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
|
Stary rodzaj danych zlicza liczbę zmian rozdzielczości lub liczby klatek z powodu qualityLimitationReason . Można to wywnioskować z innych danych (np. rozdzielczość wysyłania lub częstotliwość klatek różni się od rozdzielczości źródłowej lub częstotliwości klatek), ale czas, przez który mieliśmy ograniczenie (outbound-rtp.qualityLimitationDurations ), może być bardziej przydatny niż częstotliwość zmiany rozdzielczości lub częstotliwości 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
|
Ostatnia wartość współczynnika 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 (dźwięk) |
inbound-rtp.jitterBufferTargetDelay /inbound-rtp.jitterBufferEmittedCount
|
.googExpandRate
|
Ostatnie proporcje ukrytych próbek: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived |
.googSpeechExpandRate
|
Ostatni współczynnik ukrytych próbek, gdy transmisja nie była bezdźwięczna: (inbound-rtp.concealedSamples – inbound-rtp.silentConcealedSamples ) / inbound-rtp.concealedSamples |
.googAccelerateRate
|
Ostatni stosunek próbek, które zostały odrzucone w celu przyspieszenia szybkości odtwarzania: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Ostatnia liczba próbek, które zostały zsyntetyzowane w celu spowolnienia szybkoś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
|
Jedyna pozostała goog-metric. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Starszy typ danych
VideoBwe |
Standardowa korespondencja
outbound-rtp i candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate jako wartość chwilowa lub outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded jako średnia |
.googActualEncBitrate
|
Bajty wygenerowane przez koder to bajty danych, z wyjątkiem retransmisji: szybkość zmiany outbound-rtp.bytesSent – outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay /outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Szybkość zmiany outbound-rtp.headerBytesSent + outbound-rtp.bytesSent w przypadku szybkości transmisji bitów strumienia RTP, candidate-pair.bytesSent w przypadku szybkości transmisji bitów kandydata ICE lub transport.bytesSent w przypadku szybkości transmisji bitów transportu. |
.googRetransmitBitrate
|
Zakres zmian outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
Standardowy interfejs API obsługuje transmisję symultaniczną.
Jeśli korzystasz z simultanicznej transmisji, możesz zauważyć, że starszy interfejs API raportuje tylko jeden SSRC, nawet jeśli używasz tej funkcji do wysyłania (np.) 3 strumieni RTP za pomocą 3 oddzielnych SSRC.
Standardowy interfejs API nie ma tego ograniczenia i zwraca 3 obiekty statystyk outbound-rtp
, po jednym dla każdego źródła danych SRC. Oznacza to, że możesz analizować każdy strumień RTP osobno, ale też, że aby uzyskać łączną szybkość transmisji bitów wszystkich strumieni wysyłania RTP, musisz je samodzielnie zsumować.
Z drugiej strony strumienie SVC lub RTP z wieloma warstwami przestrzennymi skonfigurowanymi za pomocą interfejsu scalabilityMode
API nadal wyświetlają się jako pojedyncze outbound-rtp
, ponieważ są wysyłane za pomocą jednego SSRC.
Jeśli potrzebujesz więcej czasu na migrację
Gdy starszy interfejs API zostanie usunięty w Chrome 117, jego użycie spowoduje wygenerowanie wyjątku. Jeśli nie możesz w czasie przenieść kodu, próbna wersja interfejsu RTCPeerConnection getStats() API daje zarejestrowanym witrynom więcej czasu na migrację. Dzięki tokenowi testowania origin interfejsu API getStats() można nadal używać do wersji Chrome 121.