WebRTC: Panduan migrasi getStats() lama

Henrik Boström
Henrik Boström

WebRTC API getStats() lama akan dihapus di Chrome 117, sehingga aplikasi yang menggunakannya harus dimigrasikan ke API standar. Artikel ini menjelaskan cara memigrasikan kode dan apa yang harus dilakukan jika Anda memerlukan lebih banyak waktu untuk melakukan perubahan ini.

Secara historis, ada dua versi WebRTC getStats() API yang bersaing. API getStats() lama, yang mendahului proses standardisasi dan mengambil argumen callback, serta API yang telah distandardisasi dan didukung secara luas yang menampilkan promise.

API standar lebih kaya fitur dan memiliki metrik yang terdefinisi dengan baik yang didokumentasikan secara publik dalam spesifikasi W3C Identifiers for WebRTC's Statistics API. Spesifikasi mencakup deskripsi setiap metrik yang tercantum dalam panduan ini dan lainnya.

Mulai Chrome 117, getStats() API lama akan menampilkan pengecualian di saluran rilis Stabil (pengecualian yang ditampilkan akan diluncurkan secara bertahap). Ikuti panduan ini untuk memudahkan transisi ke API standar.

Jenis statistik lama versus standar

Daftar lengkap jenis statistik standar dapat ditemukan dengan melihat enum RTCStatsType di spesifikasi. Hal ini termasuk definisi kamus statistik mana yang menjelaskan metrik yang dikumpulkan untuk setiap jenis.

Semua objek statistik memiliki atribut id yang secara unik mengidentifikasi objek dasar di beberapa panggilan getStats(). Objek yang sama akan memiliki ID yang sama setiap kali metode dipanggil. Hal ini berguna untuk menghitung tingkat perubahan metrik (ada contohnya di bagian berikutnya). ID juga membentuk hubungan referensi. Misalnya, objek statistik outbound-rtp mereferensikan objek statistik media-source yang terkait melalui atribut outbound-rtp.mediaSourceId. Jika Anda menggambar semua hubungan ...Id, Anda akan mendapatkan grafik.

API lama memiliki jenis statistik berikut, sesuai dengan jenis standar sebagai berikut:


Jenis lama

Jenis standar
ssrc
Mewakili aliran RTP dan metrik tentang MediaStreamTrack terkait.


Jenis standar untuk ini adalah inbound-rtp (untuk menerima streaming RTP dan MediaStreamTrack jarak jauh terkait), outbound-rtp (untuk mengirim streaming RTP), dan media-source (untuk metrik MediaStreamTrack lokal yang terkait dengan streaming RTP kirim). Metrik streaming RTP juga berisi informasi tentang encoder atau decoder yang digunakan oleh streaming RTP.
VideoBwe
Metrik estimasi bandwidth, kecepatan bit target, kecepatan bit encoder, dan kecepatan bit sebenarnya. Jenis metrik ini adalah bagian dari metrik RTP (outbound-rtp dan inbound-rtp) dan metrik pasangan kandidat ICE (candidate-pair).
googComponent
Menunjukkan transport (ICE dan DTLS). Versi standarnya adalah transport.
localcandidate and remotecandidate
Mewakili kandidat ICE. Versi standar adalah local-candidate dan remote-candidate.
googCandidatePair
Mewakili pasangan kandidat ICE, yang merupakan pasangan kandidat lokal dan jarak jauh. Versi standarnya adalah candidate-pair.
googCertificate
Menunjukkan sertifikat yang digunakan oleh transpor DTLS. Versi standarnya adalah certificate.
googLibjingleSession
Menampilkan RTCPeerConnection. Meskipun kontennya tidak dipetakan ke apa pun dalam standar, standar tersebut memiliki jenis yang terkait dengan RTCPeerConnection: peer-connection.

Tidak ada di API lama

Jenis statistik ini telah ditambahkan ke API standar yang tidak memiliki jenis lama yang sesuai:
  • codec: Codec yang saat ini sedang digunakan oleh streaming RTP, baik untuk encoding maupun decoding. Ini adalah bagian dari codec yang telah dinegosiasikan dalam SDP.
  • remote-inbound-rtp: Aliran RTP masuk endpoint jarak jauh yang sesuai dengan aliran RTP keluar yang dikirim endpoint ini (outbound-rtp). Ini diukur pada titik akhir jarak jauh dan dilaporkan dalam RTCP Receiver Report (RR) atau RTCP Extended Report (XR).
  • remote-outbound-rtp: Aliran RTP keluar endpoint jarak jauh yang sesuai dengan aliran RTP masuk yang diterima endpoint ini (inbound-rtp). Ini diukur di endpoint jarak jauh dan dilaporkan dalam RTCP Sender Report (SR).
  • media-playout: Metrik tentang pemutaran MediaStreamTrack jarak jauh yang terkait dengan streaming RTP masuk (inbound-rtp).
  • data-channel: Merepresentasikan RTCDataChannel.

Pemetaan metrik lama ke standar

Pemetaan ini ditujukan untuk membantu developer menemukan metrik lama yang sesuai dengan metrik standar. Namun, perhatikan bahwa metrik terkait mungkin menggunakan unit yang berbeda atau dinyatakan sebagai penghitung total, bukan nilai instan. Lihat spesifikasi untuk mengetahui definisi metrik.
API standar lebih memilih mengekspos penghitung total daripada tarif. Artinya, untuk mendapatkan rasio yang sesuai (misalnya, kecepatan bit) seperti di API lama, aplikasi harus menghitung tarif rata-rata dengan mengambil delta di antara dua panggilan getStats(). Contoh:

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

Menghitung tarif dan rata-rata sendiri seperti ini mungkin tampak seperti langkah tambahan yang rumit, tetapi ada baiknya Anda mendapatkan rata-rata dalam interval waktu yang diinginkan. Memanggil API standar lebih jarang daripada yang mungkin harus Anda lakukan dengan API lama memiliki beberapa manfaat performa.

Metrik lama googCertificate
Korespondensi standar certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
Metrik lama googComponent
Korespondensi standar transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
Metrik lama localcandidate
Korespondensi standar
local-candidate atau candidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (pencarian balik candidate-pair melalui 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
Metrik lama remotecandidate
Korespondensi standar remote-candidate
Sama seperti localcandidate di atas. Sama seperti local-candidate di atas.
Metrik lama googCandidatePair
Korespondensi standar candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(cari remote-candidate melalui
candidate-pair.remoteCandidateId)
.googReadable googReadable adalah boolean yang mencerminkan apakah kita baru-baru ini menambahkan candidate-pair.requestsReceived atau candidate-pair.responsesReceived
.googLocalAddress local-candidate.address
(cari local-candidate melalui
candidate-pair.localCandidateId)
.consentRequestsSent candidate-pair.consentRequestsSent
.googTransportType Sama seperti local-candidate.protocol dan remote-candidate.protocol.
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable adalah boolean yang mencerminkan apakah kita baru-baru ini menambahkan candidate-pair.responsesReceived atau tidak
.googRemoteAddress remote-candidate.address
.googRtt candidate-pair.currentRoundTripTime
.googActiveConnection Koneksi aktif mengacu pada pasangan kandidat yang saat ini dipilih oleh transpor, seperti tempat 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
Metrik lama ssrc
Korespondensi standar
inbound-rtp, outbound-rtp, media-source
.audioInputLevel media-source.audioLevel. Metrik lama berada dalam rentang [0..32768] tetapi meter standar berada dalam rentang [0..1].
.audioOutputLevel
inbound-rtp.audioLevel. Metrik lama berada dalam rentang [0..32768] tetapi meter standar berada dalam rentang [0..1].
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier untuk MediaStreamTrack lokal dan inbound-rtp.trackIdentifier untuk MediaStreamTrack jarak jauh
.googRtt remote-inbound-rtp.roundTripTime (lihat outbound-rtp.remoteId)
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName Nama codec adalah subjenis "type/subtype" jenis mime, codec.mimeType (lihat inbound-rtp.codecId dan outbound-rtp.codecId)
.transportId inbound-rtp.transportId dan outbound-rtp.transportId
.mediaType inbound-rtp.kind dan outbound-rtp.kind atau media-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergy dan media-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDuration dan media-source.totalSamplesDuration
.ssrc inbound-rtp.ssrc dan outbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentType dan outbound-rtp.contentType
.googFrameWidthInput media-source.width
.googFrameHeightInput media-source.height
.googFrameRateInput media-source.framesPerSecond
.googFrameWidthSent outbound-rtp.frameWidth
.googFrameHeightSent outbound-rtp.frameHeight
.googFrameRateSent
Meskipun FPS pengiriman adalah kecepatan perubahan outbound-rtp.framesSent, ini sebenarnya diterapkan sebagai outbound-rtp.framesPerSecond yang mengenkode FPS.
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
Laju perubahan inbound-rtp.framesDecoded
.googFrameRateOutput
Laju perubahan inbound-rtp.framesDecoded - inbound-rtp.framesDropped
.hugeFramesSent outbound-rtp.hugeFramesSent
.qpSum

inbound-rtp.qpSum dan outbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime/outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementation dan outbound-rtp.encoderImplementation

.googCpuLimitedResolution
Benar jika outbound-rtp.qualityLimitationReason == "cpu"
.googBandwidthLimitedResolution
Benar jika outbound-rtp.qualityLimitationReason == "bandwidth"
.googAdaptationChanges
Metrik lama menghitung berapa kali resolusi atau kecepatan frame berubah karena alasan terkait qualityLimitationReason. Data ini dapat disimpulkan dari metrik lain (misalnya, resolusi pengiriman atau kecepatan frame yang berbeda dengan resolusi sumber atau kecepatan frame), tetapi durasi yang telah kita batasi, yaitu outbound-rtp.qualityLimitationDurations, mungkin lebih berguna daripada seberapa sering resolusi atau kecepatan frame diubah dikonfigurasi ulang.
.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
Rasio paket terbaru yang berisi koreksi error: 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
Rasio terbaru dari sampel yang disembunyikan: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Rasio terbaru dari sampel yang disembunyikan saat streaming tidak senyap: dari (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate Rasio terbaru sampel yang dihapus untuk mempercepat kecepatan pemutaran: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Rasio terbaru sampel yang disintesis untuk memperlambat kecepatan pemutaran: inbound-rtp.insertedSamplesForDeceleration / inbound-rtp.totalSamplesReceived
.googSecondaryDiscardedRate inbound-rtp.fecPacketsDiscarded
.bytesReceived inbound-rtp.bytesReceived
s.googCurrentDelayMs inbound-rtp.jitterBufferDelay + media-playout.totalPlayoutPenundaan
.googDecodeMs inbound-rtp.totalDecodeTime/inbound-rtp.framesDecoded
.googTimingFrameInfo
Satu-satunya metrik goog-metrik yang tersisa. inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
Metrik lama VideoBwe
Korespondensi standar
outbound-rtp dan candidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate sebagai nilai instan atau outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded sebagai rata-rata
.googActualEncBitrate Byte yang dihasilkan oleh encoder adalah byte payload, tidak termasuk transmisi ulang: tingkat perubahan outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Kecepatan perubahan outbound-rtp.headerBytesSent + outbound-rtp.bytesSent untuk kecepatan bit streaming per RTP, candidate-pair.bytesSent untuk kecepatan bit kandidat per ICE, atau transport.bytesSent untuk kecepatan bit per transpor
.googRetransmitBitrate Rentang perubahan outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API standar ini simulcast-aware

Jika Anda menggunakan {i>simulcast<i}, Anda mungkin telah memperhatikan bahwa API lama hanya melaporkan satu SSRC, bahkan saat Anda menggunakan simulcast untuk mengirim (misalnya) tiga streaming RTP melalui tiga SSRC yang terpisah.

API standar tidak memiliki batasan ini dan akan menampilkan tiga objek statistik outbound-rtp, satu untuk masing-masing SSRC. Ini berarti Anda dapat menganalisis setiap streaming RTP satu per satu, tetapi ini juga berarti bahwa untuk mendapatkan kecepatan bit total semua streaming pengiriman RTP, Anda harus menggabungkan sendiri.

Di sisi lain, streaming SVC atau streaming RTP dengan beberapa lapisan spasial yang dikonfigurasi melalui scalabilityMode API masih muncul sebagai outbound-rtp tunggal karena dikirim melalui satu SSRC.

Jika Anda membutuhkan lebih banyak waktu untuk migrasi

Saat API lama dihapus di Chrome 117, penggunaannya akan menghasilkan pengecualian. Jika Anda tidak dapat memigrasikan kode tepat waktu, uji coba origin untuk getStats() API berbasis callback RTCPeerConnection akan memberikan lebih banyak waktu bagi situs yang terdaftar untuk melakukan migrasi. Dengan token uji coba origin, API getStats() lama dapat terus digunakan hingga Chrome 121.