WebRTC: Hướng dẫn di chuyển getStats() cũ

Henrik Boström
Henrik Boström

API WebRTC getStats() cũ sẽ bị xoá trong Chrome 117. Do đó, các ứng dụng sử dụng API này sẽ cần chuyển sang API tiêu chuẩn. Bài viết này giải thích cách di chuyển mã và những việc bạn cần làm nếu cần thêm thời gian để thực hiện thay đổi này.

Trước đây, có hai phiên bản cạnh tranh của API WebRTC getStats(). API getStats() cũ có thể xử lý trước quá trình chuẩn hoá và lấy đối số gọi lại, cũng như API được chuẩn hoá và được hỗ trợ rộng rãi có khả năng trả về một lời hứa.

API tiêu chuẩn có nhiều tính năng phong phú hơn và có các chỉ số được xác định rõ ràng được ghi lại công khai trong Giá trị nhận dạng cho API thống kê của WebRTC trong thông số kỹ thuật của W3C. Thông số kỹ thuật bao gồm mô tả của từng chỉ số được liệt kê trong hướng dẫn này và nhiều nội dung khác.

Từ Chrome 117, API getStats() cũ sẽ gửi một ngoại lệ vào Kênh phát hành chính thức (việc gửi ngoại lệ sẽ dần được triển khai). Hãy làm theo hướng dẫn này để dễ dàng chuyển đổi sang API tiêu chuẩn.

Loại thống kê cũ so với chuẩn

Bạn có thể xem danh sách đầy đủ các loại số liệu thống kê chuẩn bằng cách xem enum RTCStatsType trong phần thông số kỹ thuật. Điều này bao gồm định nghĩa từ điển thống kê mô tả các chỉ số được thu thập cho từng loại.

Các đối tượng thống kê đều có một thuộc tính mã nhận dạng duy nhất nhận dạng duy nhất đối tượng cơ bản trong nhiều lệnh gọi getStats(). Cùng một đối tượng sẽ có cùng một mã nhận dạng mỗi khi phương thức này được gọi. Điều này rất hữu ích khi tính toán tốc độ thay đổi của các chỉ số (bạn sẽ thấy ví dụ trong phần tiếp theo). Các mã này cũng hình thành mối quan hệ của các tệp tham chiếu. Ví dụ: đối tượng số liệu thống kê outbound-rtp tham chiếu đến đối tượng số liệu thống kê media-source được liên kết qua thuộc tính outbound-rtp.mediaSourceId. Nếu vẽ tất cả mối quan hệ ...Id, bạn sẽ nhận được một biểu đồ.

API cũ có các loại số liệu thống kê sau, tương ứng với các loại tiêu chuẩn như sau:


Loại cũ

Loại chuẩn
ssrc
Đại diện cho một luồng RTP và các chỉ số về MediaStreamTrack liên kết.


Các loại tiêu chuẩn cho chế độ này là inbound-rtp (để nhận luồng RTP và MediaStreamTrack từ xa liên kết với luồng RTP), outbound-rtp (để gửi luồng RTP) và media-source (dành cho các chỉ số MediaStreamTrack cục bộ được liên kết với luồng RTP gửi). Các chỉ số của luồng RTP cũng chứa thông tin về bộ mã hoá hoặc bộ giải mã mà luồng RTP sử dụng.
VideoBwe
Các chỉ số ước tính băng thông, tốc độ bit mục tiêu, tốc độ bit của bộ mã hoá và tốc độ bit thực tế. Các loại chỉ số này là một phần trong chỉ số RTP (outbound-rtpinbound-rtp) và chỉ số cặp ứng viên ICE (candidate-pair).
googComponent
Đại diện cho phương thức truyền tải (ICE và DTLS). Phiên bản chuẩn là transport.
localcandidate and remotecandidate
Đại diện cho một ứng cử viên của ICE. Phiên bản chuẩn là local-candidateremote-candidate.
googCandidatePair
Đại diện cho một cặp ứng cử viên ICE, tức là cặp một ứng cử viên địa phương và một ứng cử viên từ xa. Phiên bản chuẩn là candidate-pair.
googCertificate
Đại diện cho một chứng chỉ mà phương thức truyền tải DTLS sử dụng. Phiên bản chuẩn là certificate.
googLibjingleSession
Đại diện cho RTCPeerConnection. Mặc dù nội dung của lớp này không liên kết với bất kỳ nội dung nào trong tiêu chuẩn, nhưng tiêu chuẩn này có một loại dữ liệu liên kết với RTCPeerConnection: peer-connection.

Thiếu API cũ

Các loại số liệu thống kê sau đã được thêm vào API tiêu chuẩn không có bất kỳ loại số liệu thống kê cũ nào tương ứng:
  • codec: Một bộ mã hoá và giải mã hiện đang được luồng RTP sử dụng để mã hoá hoặc giải mã. Đây là một tập hợp con bộ mã hoá và giải mã đã được thương lượng trong SDP.
  • remote-inbound-rtp: Luồng RTP đến của điểm cuối từ xa tương ứng với luồng RTP đi mà điểm cuối này đang gửi (outbound-rtp). Luồng này được đo tại điểm cuối từ xa và được báo cáo trong Báo cáo bộ thu RTCP (RR) hoặc Báo cáo mở rộng RTCP (XR).
  • remote-outbound-rtp: Luồng RTP đi của điểm cuối từ xa tương ứng với luồng RTP đến mà điểm cuối này đang nhận (inbound-rtp). Luồng này được đo ở điểm cuối từ xa và được báo cáo trong Báo cáo người gửi RTCP (SR).
  • media-playout: Chỉ số về phát lại một MediaStreamTrack từ xa liên kết với luồng RTP đầu vào (inbound-rtp).
  • data-channel: Đại diện cho RTCDataChannel.

Liên kết chỉ số cũ sang chỉ số chuẩn

Việc liên kết này nhằm giúp các nhà phát triển tìm ra chỉ số cũ tương ứng với chỉ số chuẩn nào. Tuy nhiên, xin lưu ý rằng chỉ số tương ứng có thể sử dụng các đơn vị khác nhau hoặc được biểu thị dưới dạng bộ đếm tổng thay vì giá trị tức thì. Hãy tham khảo quy cách để biết định nghĩa các chỉ số.
API tiêu chuẩn muốn hiển thị tổng bộ đếm thay vì giá. Tức là để nhận được tốc độ tương ứng (ví dụ: tốc độ bit) như trong API cũ, ứng dụng phải tính tốc độ trung bình bằng cách lấy delta giữa hai lệnh gọi getStats(). Ví dụ:

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

Việc phải tự tính giá và mức trung bình như thế này có vẻ giống như một bước bổ sung rườm rà, nhưng nó có lợi thế là cho phép bạn có được mức trung bình trong bất kỳ khoảng thời gian mong muốn nào. Việc gọi API chuẩn ít thường xuyên hơn so với cách bạn có thể đã thực hiện với API cũ có một số lợi ích về hiệu suất.

Chỉ số cũ
googCertificate
Thư từ trao đổi thông thường
certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
Chỉ số cũ
googComponent
Thư từ trao đổi thông thường
transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
Chỉ số cũ
localcandidate
Thư tín tiêu chuẩn
local-candidate hoặc candidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (tra cứu ngược candidate-pair qua 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
Chỉ số cũ
remotecandidate
Thư từ trao đổi thông thường
remote-candidate
Tương tự như localcandidate ở trên. Tương tự như local-candidate ở trên.
Chỉ số cũ
googCandidatePair
Thư từ trao đổi thông thường
candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(tra cứu remote-candidate qua
candidate-pair.remoteCandidateId)
.googReadable googReadable là một giá trị boolean phản ánh việc gần đây chúng ta có tăng candidate-pair.requestsReceived hoặc candidate-pair.responsesReceived hay không
.googLocalAddress local-candidate.address
(tra cứu local-candidate qua
candidate-pair.localCandidateId)
.consentRequestsSent candidate-pair.consentRequestsSent
.googTransportType Giống như local-candidate.protocolremote-candidate.protocol.
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable là một giá trị boolean phản ánh việc gần đây chúng ta có tăng candidate-pair.responsesReceived hay không
.googRemoteAddress remote-candidate.address
.googRtt candidate-pair.currentRoundTripTime
.googActiveConnection Kết nối đang hoạt động đề cập đến cặp đề xuất hiện được chọn bởi công cụ truyền tải, chẳng hạn như trong trường hợp 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
Chỉ số cũ
ssrc
Thư tín tiêu chuẩn
inbound-rtp, outbound-rtp, media-source
.audioInputLevel media-source.audioLevel. Chỉ số cũ nằm trong phạm vi [0..32768] nhưng thước đo tiêu chuẩn nằm trong phạm vi [0..1].
.audioOutputLevel
inbound-rtp.audioLevel. Chỉ số cũ nằm trong phạm vi [0..32768] nhưng thước đo tiêu chuẩn nằm trong phạm vi [0..1].
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier cho MediaStreamTrack cục bộ và inbound-rtp.trackIdentifier cho MediaStreamTrack từ xa
.googRtt remote-inbound-rtp.roundTripTime (xem outbound-rtp.remoteId)
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName Tên bộ mã hoá và giải mã là loại phụ của loại mime "type/subtype", codec.mimeType (xem inbound-rtp.codecIdoutbound-rtp.codecId)
.transportId inbound-rtp.transportIdoutbound-rtp.transportId
.mediaType inbound-rtp.kindoutbound-rtp.kind hoặc media-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergymedia-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDurationmedia-source.totalSamplesDuration
.ssrc inbound-rtp.ssrcoutbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentTypeoutbound-rtp.contentType
.googFrameWidthInput media-source.width
.googFrameHeightInput media-source.height
.googFrameRateInput media-source.framesPerSecond
.googFrameWidthSent outbound-rtp.frameWidth
.googFrameHeightSent outbound-rtp.frameHeight
.googFrameRateSent
Mặc dù FPS khi gửi là tốc độ thay đổi của outbound-rtp.framesSent, nhưng trên thực tế, tốc độ này được triển khai dưới dạng outbound-rtp.framesPerSecond để mã hoá FPS.
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
Tốc độ thay đổi của inbound-rtp.framesDecoded
.googFrameRateOutput
Tốc độ thay đổi của inbound-rtp.framesDecodedinbound-rtp.framesDropped
.hugeFramesSent outbound-rtp.hugeFramesSent
.qpSum

inbound-rtp.qpSumoutbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime/outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementationoutbound-rtp.encoderImplementation

.googCpuLimitedResolution
Đúng nếu outbound-rtp.qualityLimitationReason == "cpu"
.googBandwidthLimitedResolution
Đúng nếu outbound-rtp.qualityLimitationReason == "bandwidth"
.googAdaptationChanges
Chỉ số cũ tính số lần độ phân giải hoặc tốc độ khung hình thay đổi vì các lý do liên quan đến qualityLimitationReason. Điều này có thể suy ra từ các chỉ số khác (ví dụ: độ phân giải hoặc tốc độ khung hình khi gửi khác với độ phân giải hoặc tốc độ khung hình của nguồn), nhưng thời lượng bị giới hạn (outbound-rtp.qualityLimitationDurations) có thể hữu ích hơn tần suất thay đổi độ phân giải hoặc tốc độ khung hình được định cấu hình lại.
.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
Tỷ lệ gần đây của các gói có chứa lỗi sửa lỗi: inbound-rtp.fecPacketsReceivedinbound-rtp.fecPacketsDiscarded
.packetsReceived inbound-rtp.packetsReceived
.googJitterBufferMs inbound-rtp.jitterBufferDelay/inbound-rtp.jitterBufferEmittedCount
.googTargetDelayMs (video) inbound-rtp.jitterBufferTargetDelay/inbound-rtp.jitterBufferEmittedCount
.googPreferredJitterBufferMs (âm thanh) inbound-rtp.jitterBufferTargetDelay/inbound-rtp.jitterBufferEmittedCount
.googExpandRate
Tỷ lệ mẫu bị ẩn gần đây: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Tỷ lệ gần đây về số mẫu bị ẩn khi luồng không ở chế độ im lặng: (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate Tỷ lệ mẫu đã bị loại bỏ gần đây để tăng tốc độ phát: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Tỷ lệ mẫu được tổng hợp gần đây để giảm tốc độ phát: 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
Các chỉ số còn lại duy nhất trên Google. inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
Chỉ số cũ
VideoBwe
Thư từ tiêu chuẩn
outbound-rtpcandidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate dưới dạng giá trị tức thời hoặc outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded dưới dạng giá trị trung bình
.googActualEncBitrate Các byte do bộ mã hoá tạo ra là các byte tải trọng, không bao gồm các dữ liệu truyền tải lại: tốc độ thay đổi từ outbound-rtp.bytesSent đến outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Tốc độ thay đổi outbound-rtp.headerBytesSent + outbound-rtp.bytesSent cho tốc độ bit luồng trên mỗi RRTP, candidate-pair.bytesSent cho tốc độ bit ứng viên trên mỗi ICE hoặc transport.bytesSent cho tốc độ bit trên mỗi phương tiện truyền tải
.googRetransmitBitrate Phạm vi thay đổi của outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API chuẩn nhận biết được simulcast

Nếu sử dụng simulcast, bạn có thể nhận thấy API cũ chỉ báo cáo một SSRC duy nhất ngay cả khi bạn đang sử dụng simulcast để gửi (ví dụ: 3 luồng RTP) qua 3 SSRC riêng biệt.

API tiêu chuẩn không có chung giới hạn này và sẽ trả về 3 đối tượng thống kê outbound-rtp, mỗi đối tượng cho một SSRC. Điều này có nghĩa là bạn có thể phân tích riêng từng luồng RTP, nhưng cũng có nghĩa là để có được tổng tốc độ bit của tất cả luồng gửi RTP, bạn cần phải tự tổng hợp chúng.

Mặt khác, luồng SVC hoặc luồng RTP có nhiều lớp không gian được định cấu hình thông qua API scalabilityMode vẫn hiển thị dưới dạng một outbound-rtp duy nhất vì những luồng này được gửi qua một SSRC duy nhất.

Nếu bạn cần thêm thời gian để di chuyển

Khi API cũ bị xoá trong Chrome 117, trường hợp ngoại lệ sẽ được tạo ra khi sử dụng API này. Nếu bạn không thể di chuyển mã kịp thời, thì bản dùng thử theo nguyên gốc cho API getStats() dựa trên lệnh gọi lại RTCPeerConnection sẽ giúp các trang web đã đăng ký có thêm thời gian di chuyển. Với mã thông báo dùng thử theo nguyên gốc, API getStats() cũ có thể tiếp tục được sử dụng cho đến Chrome 121.