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 tindakan yang harus dilakukan jika Anda memerlukan lebih banyak waktu untuk melakukan perubahan ini.

Secara historis, ada dua versi WebRTC getStats() API yang bersaing. GetStats() API lama sebelum proses standardisasi menggunakan argumen callback, serta API yang 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 Anda ke API standar.

Jenis statistik lama versus jenis statistik standar

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

Semua objek statistik memiliki atribut ID yang mengidentifikasi objek dasar secara unik di beberapa panggilan getStats(). Objek yang sama akan memiliki ID yang sama setiap kali metode dipanggil. Hal ini berguna untuk menghitung laju perubahan metrik (ada contohnya di bagian berikutnya). ID juga membentuk hubungan referensi. Misalnya, objek statistik outbound-rtp mereferensikan objek statistik media-source terkait melalui atribut outbound-rtp.mediaSourceId. Jika 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
Merepresentasikan aliran dan metrik RTP tentang MediaStreamTrack yang terkait.


Jenis standar untuk hal ini adalah inbound-rtp (untuk menerima aliran RTP dan MediaStreamTrack jarak jauh yang terkait), outbound-rtp (untuk aliran RTP pengiriman), dan media-source (untuk metrik MediaStreamTrack lokal yang terkait dengan aliran RTP pengiriman). 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 aktual. Jenis metrik ini adalah bagian dari metrik RTP (outbound-rtp dan inbound-rtp) dan metrik pasangan kandidat ICE (candidate-pair).
googComponent
Mewakili transpor (ICE dan DTLS). Versi standarnya adalah transport.
localcandidate and remotecandidate
Mewakili kandidat ICE. Versi standar adalah local-candidate dan remote-candidate.
googCandidatePair
Merepresentasikan pasangan kandidat ICE, yang merupakan pasangan kandidat lokal dan jarak jauh. Versi standarnya adalah candidate-pair.
googCertificate
Mewakili sertifikat yang digunakan oleh transpor DTLS. Versi standarnya adalah certificate.
googLibjingleSession
Merepresentasikan RTCPeerConnection. Meskipun kontennya tidak dipetakan ke apa pun dalam standar, standar 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 terkait:
  • codec: Codec yang saat ini digunakan oleh streaming RTP, baik untuk encoding maupun decoding. Ini adalah subset codec yang telah dinegosiasikan dalam SDP.
  • remote-inbound-rtp: Aliran RTP masuk endpoint jarak jauh yang sesuai dengan aliran RTP keluar yang dikirim oleh endpoint ini (outbound-rtp). Hal ini diukur di endpoint 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). Aliran ini diukur di endpoint jarak jauh dan dilaporkan dalam Laporan Pengirim RTCP (SR).
  • media-playout: Metrik tentang pemutaran MediaStreamTrack jarak jauh yang terkait dengan aliran RTP masuk (inbound-rtp).
  • data-channel: Menampilkan RTCDataChannel.

Pemetaan metrik lama ke standar

Pemetaan ini ditujukan untuk membantu developer menemukan metrik lama yang sesuai dengan metrik standar. Namun, perhatikan bahwa metrik yang terkait dapat menggunakan unit yang berbeda atau dinyatakan sebagai penghitung total, bukan nilai instan. Lihat spesifikasi untuk definisi metrik.
API standar lebih memilih mengekspos penghitung total daripada tarif. Artinya, untuk mendapatkan kecepatan 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 mungkin tampak seperti langkah tambahan yang rumit, tetapi sisi baiknya adalah Anda dapat memperoleh rata-rata selama interval waktu yang diinginkan. Memanggil API standar lebih jarang dibandingkan yang biasanya 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 terbalik 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 menunjukkan 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 menunjukkan 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 transport, 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 metrc standar berada dalam rentang [0..1].
.audioOutputLevel
inbound-rtp.audioLevel Metrik lama berada dalam rentang [0..32768], tetapi metrc 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 dari jenis mime "jenis/subjenis", 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 laju perubahan outbound-rtp.framesSent, hal ini sebenarnya diimplementasikan 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 untuk alasan terkait qualityLimitationReason. Hal ini dapat disimpulkan dari metrik lain (misalnya, resolusi pengiriman atau kecepatan frame yang berbeda dengan resolusi sumber atau kecepatan frame), tetapi durasi yang telah dibatasi, outbound-rtp.qualityLimitationDurations, mungkin lebih berguna daripada seberapa sering resolusi atau kecepatan frame berubah yang 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 perbaikan 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 tersembunyi: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Rasio terbaru dari sampel tersembunyi saat streaming tidak senyap: dari (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate Rasio sampel terbaru yang dihapus untuk mempercepat kecepatan playout: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Rasio sampel terbaru 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.totalPlayoutDelay
.googDecodeMs inbound-rtp.totalDecodeTime/inbound-rtp.framesDecoded
.googTimingFrameInfo
Satu-satunya metrik goog 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: laju perubahan outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Laju 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 transportasi
.googRetransmitBitrate Rentang perubahan outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API standar peka terhadap simulcast

Jika menggunakan simulcast, Anda mungkin memperhatikan bahwa API lama hanya melaporkan satu SSRC bahkan saat Anda menggunakan simulcast untuk mengirim (misalnya) tiga aliran RTP melalui tiga SSRC terpisah.

API standar tidak membagikan batasan ini dan akan menampilkan tiga objek statistik outbound-rtp, satu untuk setiap SSRC. Artinya, Anda dapat menganalisis setiap streaming RTP secara terpisah, tetapi ini juga berarti bahwa untuk mendapatkan total kecepatan bit dari semua streaming pengiriman RTP, Anda harus menggabungkannya sendiri.

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

Jika Anda memerlukan lebih banyak waktu untuk migrasi

Saat API lama dihapus di Chrome 117, penggunaannya akan membuat pengecualian. Jika Anda tidak dapat memigrasikan kode secara 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, getStats() API lama dapat terus digunakan hingga Chrome 121.