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 đang dùng API này sẽ cần chuyển sang API chuẩn. Bài viết này giải thích cách di chuyển mã và việc cần làm nếu bạn 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ũ, chạy trước quy trình chuẩn hoá và nhận đối số gọi lại, cũng như API được chuẩn hoá và hỗ trợ rộng rãi sẽ trả về một kết quả hứa hẹn.

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 thông số kỹ thuật W3C. Đặc tả bao gồm phần mô tả của từng chỉ số được liệt kê trong hướng dẫn này và nhiều chỉ số 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ẽ được triển khai dần). Hãy làm theo hướng dẫn này để dễ dàng chuyển sang API tiêu chuẩn.

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

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

Tất cả các đối tượng thống kê đều có thuộc tính mã 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ã 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ố (có ví dụ trong phần tiếp theo). Các mã nhận dạng này cũng hình thành mối quan hệ 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 thông qua thuộc tính outbound-rtp.mediaSourceId. Nếu vẽ tất cả cá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
Biểu thị luồng RTP và các chỉ số về MediaStreamTrack liên kết.


Các kiểu tiêu chuẩn cho chế độ này là inbound-rtp (để nhận luồng RTP và MediaStreamTrack từ xa được liên kết), outbound-rtp (để gửi luồng RTP) và media-source (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
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ế. Những loại chỉ số này là một phần của 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 ICE. Phiên bản chuẩn là local-candidateremote-candidate.
googCandidatePair
Đại diện cho cặp ứng viên ICE, là một cặp giữa một ứng viên cục bộ và một ứng 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 tiêu chuẩn 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 có một loại liên kết với RTCPeerConnection: peer-connection.

Thiếu trong API cũ

Những loại số liệu thống kê này đã được thêm vào API chuẩn mà không có loại cũ tương ứng nào:
  • 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). Nó được đo ở đ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). Nó được đo ở điểm cuối từ xa và được báo cáo trong Báo cáo người gửi (SR) RTCP.
  • media-playout: Các chỉ số về quá trình phát một MediaStreamTrack từ xa được liên kết với luồng RTP đến (inbound-rtp).
  • data-channel: Đại diện cho RTCDataChannel.

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

Việc liên kết này nhằm giúp 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ể 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ời. Hãy tham khảo quy cách để biết định nghĩa về các chỉ số.
API tiêu chuẩn ưu tiên hiển thị tổng số bộ đếm thay vì giá. Tức là để có đượ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 thực hiện delta giữa 2 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 toán tốc độ và tính trung bình như thế này có vẻ là một bước bổ sung rườm rà, nhưng nó có ưu điểm là giúp bạn có được số liệu 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 việc bạn phải 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ừ tiêu chuẩn certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
Chỉ số cũ googComponent
Thư từ tiêu chuẩn transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
Chỉ số cũ localcandidate
Thư từ 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ừ tiêu chuẩn remote-candidate
Tương tự như localcandidate ở trên. Tương tự như local-candidate ở trên.
Chỉ số cũ googCandidatePair
Thư từ tiêu chuẩn 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à 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 Tương tự như local-candidate.protocolremote-candidate.protocol.
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable là 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 Active connection (Kết nối đang hoạt động) đề cập đến cặp ứng viên hiện đang được mạng truyền tải chọn, chẳng hạn như khi 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ừ 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 métrc 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 Merc 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/loại phụ" loại mime, 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 gửi đi là tốc độ thay đổi của outbound-rtp.framesSent, nhưng điều này thực sự được triển khai dưới dạng outbound-rtp.framesPerSecond đang mã hoá FPS.
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
Tốc độ thay đổi inbound-rtp.framesDecoded
.googFrameRateOutput
Tốc độ thay đổi 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 gửi khác với độ phân giải hoặc tốc độ khung hình của nguồn). Tuy nhiên, khoảng thời gian mà chúng ta bị giới hạn (outbound-rtp.qualityLimitationDurations) có thể hữu ích hơn so với 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 bản 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 được che giấu gần đây: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Tỷ lệ gần đây của các mẫu được ẩn đi trong khi luồng không ở trạng thái im lặng: trong số (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 video: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Tỷ lệ các mẫu được tổng hợp gần đây để giảm tốc tốc độ thi đấu: 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
Chỉ số goog-chỉ còn lại. inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
Chỉ số cũ VideoBwe
Thư từ tiêu chuẩn
outbound-rtpcandidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate là giá trị tức thời hoặc outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded là 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 truyền tải lại: tốc độ thay đổi outbound-rtp.bytesSentoutbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Tốc độ thay đổi outbound-rtp.headerBytesSent + outbound-rtp.bytesSent đối với tốc độ bit của mỗi luồng dữ liệu RTP, candidate-pair.bytesSent đối với tốc độ bit trên mỗi ICE hoặc transport.bytesSent đối với tốc độ bit của mỗi phương tiện giao thông
.googRetransmitBitrate Phạm vi thay đổi của outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API tiêu chuẩn có thể nhận biết bằng mô phỏng

Nếu sử dụng simulcast, bạn có thể nhận thấy rằng 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 số liệu 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ả các luồng gửi RTP, bạn cần tự tổng hợp các luồ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.

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

Khi API cũ bị xoá trong Chrome 117, việc sử dụng API này sẽ tạo ra một trường hợp ngoại lệ. Nếu bạn không thể di chuyển mã kịp thời, 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. Khi sử dụng mã thông báo dùng thử theo nguyên gốc, bạn có thể tiếp tục sử dụng API getStats() cũ cho đến Chrome 121.