Starszy interfejs getStats()
WebRTC API zostanie usunięty w Chrome 117, dlatego korzystające z niego aplikacje 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 rywalizujące wersje interfejsu API WebRTC getStats()
. Starsza wersja interfejsu API getStats(), która jest znana przed procesem standaryzacji i przyjmuje argument wywołania zwrotnego, oraz standardowy i powszechnie obsługiwany interfejs API, który zwraca obietnicę.
Standardowy interfejs API ma więcej funkcji i ma dobrze zdefiniowane dane publicznie udokumentowane w identyfikatorze interfejsu API WebRTC specyfikacji W3C. Specyfikacja zawiera opisy wszystkich wskaźników wymienionych w tym przewodniku i wiele innych.
Od wersji Chrome 117 starsza wersja interfejsu API getStats()
będzie zgłaszać wyjątek w kanale wersji stabilnej (zrzucanie wyjątków będzie wdrażane stopniowo). Ten przewodnik ułatwi Ci przejście na standardowy interfejs API.
Starsze i standardowe typy statystyk
Pełną listę standardowych typów statystyk można znaleźć na wyliczeniu RTCStatsType w specyfikacji. Obejmuje to definicja słownika statystyk opisująca dane zbierane dla poszczególnych typów.
Wszystkie obiekty statystyczne mają atrybut id, który jednoznacznie identyfikuje bazowy obiekt w wielu wywołaniach getStats()
. Przy każdym wywołaniu metody ten sam obiekt będzie miał ten sam identyfikator. Przydaje się to do obliczania częstotliwości zmian danych (przykład znajdziesz w następnej sekcji). Identyfikatory tworzą także relacje między odwołaniami. 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 typu ...Id
, otrzymasz wykres.
Starszy interfejs API ma 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 to inbound-rtp (do odbierania strumieni RTP i powiązanych z nimi zdalnych MediaStreamTrack ), outbound-rtp (do wysyłania strumieni RTP) i media-source (w przypadku lokalnych danych MediaStreamTrack powiązanych ze strumieniem RTP wysyłania). Dane strumienia RTP zawierają też informacje o koderze lub dekoderze używanym przez strumień RTP. |
VideoBwe
|
Dane o szacowaniu przepustowości, docelowej i rzeczywistej szybkości transmisji bitów. Te rodzaje danych są częścią danych RTP ( outbound-rtp i inbound-rtp ) oraz danych pary kandydatów ICE (candidate-pair ). |
googComponent
|
Reprezentuje transport (ICE i DTLS). Wersja standardowa to transport . |
localcandidate and remotecandidate
|
Reprezentuje kandydata do ICE. Wersja standardowa to local-candidate i remote-candidate . |
googCandidatePair
|
Reprezentuje parę kandydatów z ICE, czyli parę kandydatów lokalnych i zdalnych. Wersja standardowa to candidate-pair . |
googCertificate
|
Reprezentuje certyfikat używany przez transport DTLS. Wersja standardowa to certificate . |
googLibjingleSession
|
Reprezentuje obiekt RTCPeerConnection . Choć jego treść nie odpowiada żadnemu elementowi standardu, ma on jednak przypisany do niego typ (RTCPeerConnection ): peer-connection . |
Brak w starszej wersji interfejsu API |
Te typy statystyk zostały dodane do standardowego interfejsu API, który nie ma odpowiadającego mu starszego typu:
|
Mapowanie danych ze starszej wersji na standardowe
Mapowanie ma pomóc deweloperom w znalezieniu, które starsze dane odpowiadają określonym standardowym danym. Pamiętaj jednak, że odpowiednie dane mogą mieć inne jednostki lub być wyrażone jako licznik sumy, a nie wartość błyskawiczna. Definicje danych znajdziesz w specyfikacji.
Standardowy interfejs API preferuje ujawnianie sumy liczników zamiast współczynników. Oznacza to, że aby uzyskać odpowiednią szybkość (np. szybkość transmisji bitów) jak w starszym interfejsie API, aplikacja musi obliczyć średnią szybkość, uwzględniają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;
Konieczność samodzielnego obliczania współczynników i średnich może wydawać się uciążliwa, jednak w takiej sytuacji umożliwia uzyskanie średnich wartości w dowolnym przedziale czasu. Wywołując standardowy interfejs API rzadziej niż w przypadku starszego interfejsu API ma to pewne zalety w zakresie wydajności.
Starszy wskaźnik
googCertificate |
Standardowa korespondencja
certificate |
---|---|
.googFingerprint
|
.fingerprint
|
.googFingerprintAlgorithm
|
.fingerprintAlgorithm
|
.googDerBase64
|
.base64Certificate
|
Starszy wskaźnik
googComponent |
Standardowa korespondencja
transport |
---|---|
.localCertificateId
|
.localCertificateId
|
.remoteCertificateId
|
.remoteCertificateId
|
.selectedCandidatePairId
|
.selectedCandidatePairId
|
.dtlsCipher
|
.dtlsCipher
|
.srtpCipher
|
.srtpCipher
|
Starszy wskaźnik
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 wskaźnik
remotecandidate |
Standardowa korespondencja
remote-candidate |
---|---|
Taka sama jak w tabeli localcandidate powyżej. |
Taka sama jak w tabeli local-candidate powyżej. |
Starszy wskaźnik
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 liczbę candidate-pair.requestsReceived lub candidate-pair.responsesReceived
|
.googLocalAddress
|
local-candidate.address (wyszukiwanie local-candidate przez candidate-pair.localCandidateId ) |
.consentRequestsSent
|
candidate-pair.consentRequestsSent
|
.googTransportType
|
Taka sama funkcja jak w przypadku 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ększyliśmy liczbę 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, na przykład gdzie 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 wskaźnik
ssrc |
Standardowa korespondencja
inbound-rtp , outbound-rtp , media-source |
---|---|
.audioInputLevel
|
media-source.audioLevel . Starsza wartość mieści się w zakresie [0..32768], ale standardowy obszar miejski mieści się w zakresie [0..1]. |
.audioOutputLevel
|
inbound-rtp.audioLevel Starsza wartość mieści się w zakresie [0..32768], ale standardowy obszar miejski mieści się 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 (zobacz outbound-rtp.remoteId ) |
.googEchoCancellationReturnLossEnhancement
|
inbound-rtp.echoReturnLossEnhancement
|
.googCodecName
|
Nazwa kodeka to podtyp MIME typu „typ/podtyp”, codec.mimeType (patrz 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
|
FPS przy wysyłaniu to szybkość zmian wartości outbound-rtp.framesSent , ale w rzeczywistości ta wartość jest zaimplementowane jako outbound-rtp.framesPerSecond , która koduje FPS. |
.googFrameWidthReceived
|
inbound-rtp.frameWidth
|
.googFrameHeightReceived
|
inbound-rtp.frameHeight
|
.googFrameRateDecoded
|
Tempo zmian wartości inbound-rtp.framesDecoded |
.googFrameRateOutput
|
Tempo zmian wartości z okresu 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ą liczbę zmian rozdzielczości lub liczby klatek z qualityLimitationReason powodów. Można to usunąć z innych danych (np. rozdzielczość wysyłania lub liczba klatek różni się od rozdzielczości źródła lub liczby klatek), ale okres, w którym wprowadziliśmy 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 z poprawką błędów: inbound-rtp.fecPacketsReceived –inbound-rtp.fecPacketsDiscarded |
.packetsReceived
|
inbound-rtp.packetsReceived
|
.googJitterBufferMs
|
inbound-rtp.jitterBufferDelay / inbound-rtp.jitterBufferEmittedCount
|
.googTargetDelayMs (film) |
inbound-rtp.jitterBufferTargetDelay / inbound-rtp.jitterBufferEmittedCount
|
.googPreferredJitterBufferMs (dźwięk) |
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 wyświetlania: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived |
.googPreemptiveExpandRate
|
Ostatni współczynnik próbek zsyntetyzowanych w celu spowolnienia odtwarzania: inbound-rtp.insertedSamplesForDeceleration / inbound-rtp.totalSamplesReceived |
.googSecondaryDiscardedRate
|
inbound-rtp.fecPacketsDiscarded
|
.bytesReceived
|
inbound-rtp.bytesReceived
|
s.googCurrentDelayMs
|
inbound-rtp.jitterBufferDelay + media-playout.totalPlayoutOpóźnienie
|
.googDecodeMs
|
inbound-rtp.totalDecodeTime / inbound-rtp.framesDecoded
|
.googTimingFrameInfo
|
Jedyne pozostałe dane dotyczące goog. inbound-rtp.googTimingFrameInfo |
.framesDecoded
|
inbound-rtp.framesDecoded
|
Starszy wskaźnik
VideoBwe |
Standardowa korespondencja
outbound-rtp i candidate-pair |
---|---|
.googTargetEncBitrate
|
outbound-rtp.targetBitrate jako wartość chwilową lub outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded jako wartość średnią. |
.googActualEncBitrate
|
Bajty wygenerowane przez koder to bajty ładunku, z wyłączeniem ponownych transmisji – szybkość zmian z przedziału outbound-rtp.bytesSent –outbound-rtp.retransmittedBytesSent |
.googBucketDelay
|
outbound-rtp.totalPacketSendDelay / outbound-rtp.packetsSent
|
.googTransmitBitrate
|
Szybkość zmiany szybkości transmisji bitów (outbound-rtp.headerBytesSent + outbound-rtp.bytesSent ) na szybkość transmisji bitów strumienia (RTP), candidate-pair.bytesSent – szybkość transmisji bitów kandydującej na ICE lub transport.bytesSent dla szybkości transmisji bitów na transport |
.googRetransmitBitrate
|
Zakres zmian wartości outbound-rtp.retransmittedBytesSent |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
Standardowy interfejs API jest wykorzystujący funkcję simulcast
Jeśli używasz narzędzia simulcast, możesz zauważyć, że starsza wersja interfejsu API zgłasza tylko jeden kod SSRC, nawet jeśli używasz tej metody do wysyłania (np.) 3 strumieni RTP za pomocą 3 osobnych kodów SSRC.
Standardowy interfejs API nie ma tego ograniczenia i zwraca 3 obiekty statystyk outbound-rtp
, po jednym dla każdego kodu SSRC. Oznacza to, że możesz analizować każdy strumień RTP oddzielnie, ale oznacza to również, że aby uzyskać łączną szybkość transmisji bitów wszystkich strumieni RTP, musisz je zagregować samodzielnie.
Strumienie SVC lub RTP z wieloma warstwami przestrzennymi skonfigurowanymi za pomocą interfejsu API scalabilityMode
z drugiej strony nadal wyświetlają się jako pojedynczy element outbound-rtp
, ponieważ są one wysyłane przez pojedynczy kod SSRC.
Jeśli potrzebujesz więcej czasu na migrację
Po usunięciu starszej wersji interfejsu API w Chrome 117 użycie go spowoduje wygenerowanie wyjątku. Jeśli nie możesz przeprowadzić migracji kodu na czas, okres próbny źródła dla interfejsu API getStats() opartego na wywołaniach zwrotnych RTCPeerConnection daje zarejestrowanych witrynom więcej czasu na migrację. W przypadku tokena próbnego origin starszy interfejs API getStats() może być nadal używany do wersji Chrome 121.