WebRTC: Panduan migrasi getStats() lama

Henrik Boström
Henrik Boström

getStats() WebRTC API 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. API getStats() lama, yang sudah ada sebelum proses standardisasi dan menggunakan argumen callback, serta API standar yang didukung secara luas dan menampilkan promise.

API standar memiliki lebih banyak fitur dan memiliki metrik yang ditentukan dengan baik dan didokumentasikan secara publik dalam spesifikasi W3C ID untuk Statistics API WebRTC. Spesifikasi ini mencakup deskripsi setiap metrik yang tercantum dalam panduan ini dan banyak lagi.

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

Jenis statistik lama versus 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 pokok 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 contoh 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 Anda menggambar semua hubungan ...Id, Anda akan mendapatkan grafik.

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


Jenis lama

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


Jenis standar untuk ini adalah inbound-rtp (untuk menerima aliran data RTP dan MediaStreamTrack jarak jauh terkait), outbound-rtp (untuk mengirim aliran data RTP) dan media-source (untuk metrik MediaStreamTrack lokal yang terkait dengan aliran data RTP pengiriman). Metrik aliran data RTP juga berisi informasi tentang encoder atau decoder yang digunakan oleh aliran data 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
Merepresentasikan transpor (ICE dan DTLS). Versi standarnya adalah transport.
localcandidate and remotecandidate
Merepresentasikan kandidat ICE. Versi standarnya 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
Merepresentasikan sertifikat yang digunakan oleh transpor DTLS. Versi standarnya adalah certificate.
googLibjingleSession
Merepresentasikan 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 digunakan oleh streaming RTP, baik untuk encoding maupun decoding. Ini adalah subkumpulan codec yang telah dinegosiasikan di SDP.
  • remote-inbound-rtp: Streaming RTP masuk endpoint jarak jauh yang sesuai dengan streaming RTP keluar yang dikirim endpoint ini (outbound-rtp). Streaming ini diukur di endpoint jarak jauh dan dilaporkan dalam Laporan Penerima RTCP (RR) atau Laporan RTCP yang Diperluas (XR).
  • remote-outbound-rtp: Streaming RTP keluar endpoint jarak jauh yang sesuai dengan streaming RTP masuk yang diterima endpoint ini (inbound-rtp). Streaming ini diukur di endpoint jarak jauh dan dilaporkan dalam Laporan Pengirim RTCP (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 bertujuan untuk membantu developer menemukan metrik lama yang sesuai dengan metrik standar, tetapi perlu diperhatikan bahwa metrik yang sesuai dapat menggunakan satuan yang berbeda atau dinyatakan sebagai penghitung total, bukan nilai instan. Lihat spesifikasi untuk mengetahui definisi metrik.
API standar lebih memilih untuk menampilkan penghitung total, bukan rasio. Artinya, untuk mendapatkan kecepatan yang sesuai (misalnya, kecepatan bit) seperti pada API lama, aplikasi harus menghitung kecepatan rata-rata dengan mengambil delta 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 merepotkan, tetapi memiliki sisi positif karena memungkinkan Anda mendapatkan rata-rata selama interval waktu yang diinginkan. Memanggil API standar lebih jarang daripada yang mungkin 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 (penelusuran 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
(lookup 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 atau tidak
.googLocalAddress local-candidate.address
(lookup 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 metrik standar berada dalam rentang [0..1].
.audioOutputLevel
inbound-rtp.audioLevel. Metrik lama berada dalam rentang [0..32768], tetapi metrik 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 jenis mime "type/subtype", 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, hal 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 frekuensi perubahan resolusi atau kecepatan frame karena alasan terkait qualityLimitationReason. Hal ini dapat disimpulkan dari metrik lain (misalnya, resolusi atau kecepatan frame pengiriman berbeda dari resolusi atau kecepatan frame sumber), tetapi durasi yang telah kami batasi, outbound-rtp.qualityLimitationDurations, mungkin lebih berguna daripada frekuensi perubahan resolusi atau kecepatan frame 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 sampel tersembunyi terbaru: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Rasio terbaru sampel yang disembunyikan saat streaming tidak diam: (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 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: rasio perubahan outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Rasio perubahan outbound-rtp.headerBytesSent + outbound-rtp.bytesSent untuk kecepatan bit per streaming RTP, candidate-pair.bytesSent untuk kecepatan bit per kandidat 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 mendukung simulcast

Jika menggunakan siaran simultan, Anda mungkin telah melihat bahwa API lama hanya melaporkan satu SSRC meskipun Anda menggunakan siaran simultan untuk mengirim (misalnya) tiga aliran RTP melalui tiga SSRC terpisah.

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

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

Jika Anda memerlukan lebih banyak waktu untuk migrasi

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