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 di chuyển sang API chuẩn. Bài viết này giải thích cách di chuyển mã và những 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 API getStats() WebRTC cạnh tranh với nhau. API getStats() cũ, có trước quá trình chuẩn hoá và lấy một đối số gọi lại, cũng như API được chuẩn hoá và được hỗ trợ rộng rãi, trả về một lời hứa.

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

Kể từ Chrome 117, API getStats() cũ sẽ gửi một ngoại lệ trong kênh phát hành ổn định (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 đổi sang API chuẩn.

Loại số liệu thống kê cũ so với loại số liệu thống kê 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 quy cách. Thông tin này bao gồm định nghĩa từ điển số liệu thống kê mô tả các chỉ số được thu thập cho từng loại.

Tất cả đối tượng số liệu thống kê đều có một thuộc tính mã nhận dạng giúp xác định riêng đối tượng cơ bản trên 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 được gọi. Điều này hữu ích cho việc tính tốc độ thay đổi của các chỉ số (có ví dụ trong phần tiếp theo). Mã nhận dạng cũng tạo thành mối quan hệ của các tệp đối 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ẽ có một biểu đồ.

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


Loại cũ

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


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

Thiếu trong API cũ

Các loại số liệu thống kê này đã được thêm vào API chuẩn không có loại cũ tương ứng:
  • codec: 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 của các bộ mã hoá và giải mã đã được thương lượng trong SDP.
  • remote-inbound-rtp: Luồng RTP đến của một đ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 lường 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 một đ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 tại đ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ề việc 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 chỉ số cũ với chỉ số chuẩn

Mục đích của việc liên kết này là giúp nhà phát triển tìm ra chỉ số cũ tương ứng với chỉ số chuẩn nào, nhưng 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ì. Tham khảo quy cách để biết định nghĩa của các chỉ số.
API tiêu chuẩn ưu tiên hiển thị tổng số bộ đếm thay vì tốc độ. Điều này có nghĩa 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 tự tính toán giá và giá trung bình như vậy có vẻ như là một bước bổ sung rườm rà, nhưng nó có ưu điểm là cho phép bạn lấy giá trung bình trong bất kỳ khoảng thời gian nào mong muốn. Việc gọi API chuẩn ít thường xuyên hơn so với API cũ có một số lợi ích về hiệu suất.

Chỉ số cũ
googCertificate
Thư từ thông thường
certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
Chỉ số cũ
googComponent
Thư từ thông thường
transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
Chỉ số cũ
localcandidate
Thư từ thông thường
local-candidate hoặc candidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (truy vấn ngược candidate-pair thông 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ừ 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ừ thông thường
candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(tra cứu remote-candidate thông qua
candidate-pair.remoteCandidateId)
.googReadable googReadable là một 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 thông 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à một boolean cho biết liệu 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 mà phương thức truyền tải hiện đang chọn, chẳng hạn như vị trí 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ừ thông thường
inbound-rtp, outbound-rtp, media-source
.audioInputLevel media-source.audioLevel. Chỉ số cũ nằm trong khoảng [0..32768] nhưng chỉ số chuẩn nằm trong khoảng [0..1].
.audioOutputLevel
inbound-rtp.audioLevel. Chỉ số cũ nằm trong khoảng [0..32768] nhưng chỉ số chuẩn nằm trong khoảng [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" (loại/loại phụ), 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 là tốc độ thay đổi của outbound-rtp.framesSent, nhưng thực tế thì tốc độ này được triển khai dưới dạng outbound-rtp.framesPerSecond, tức là 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ũ này đếm 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. Bạn có thể suy ra điều này 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 nguồn), nhưng thời lượng mà chúng tôi 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 chứa tính năng 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ệ gần đây của các mẫu bị che khuất: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate Tỷ lệ gần đây của các mẫu bị che khuất trong khi luồng không im lặng: (inbound-rtp.concealedSamplesinbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate Tỷ lệ gần đây của các mẫu bị loại bỏ để tăng tốc độ phát: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
Tỷ lệ gần đây của các mẫu được tổng hợp để làm chậ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
Chỉ số goog duy nhất còn lại. inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
Chỉ số cũ
VideoBwe
Thư từ thông thường
outbound-rtpcandidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate dưới dạng giá trị tức thì 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à byte tải trọng, không bao gồm các lần truyền lại: tốc độ thay đổi của outbound-rtp.bytesSentoutbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay/outbound-rtp.packetsSent
.googTransmitBitrate Tốc độ thay đổi của outbound-rtp.headerBytesSent + outbound-rtp.bytesSent đối với tốc độ bit của luồng RTP, candidate-pair.bytesSent đối với tốc độ bit của đề xuất ICE hoặc transport.bytesSent đối với tốc độ bit của phương thức truyền
.googRetransmitBitrate Phạm vi thay đổi của outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API chuẩn có khả năng nhận biết truyền đồng thời

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

API chuẩn không có 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 từng luồng RTP riêng lẻ, nhưng cũng có nghĩa là để lấy tổng tốc độ bit của tất cả luồng gửi RTP, bạn cần tự tổng hợp các luồng đó.

Mặt khác, cá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 xuất hiện dưới dạng một outbound-rtp duy nhất vì các 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, việc sử dụng API đó sẽ tạo ra một ngoại lệ. Nếu bạn không thể di chuyển mã kịp thời, thì bản dùng thử gốc cho API getStats() dựa trên lệnh gọi lại RTCPeerConnection sẽ cho phé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, bạn có thể tiếp tục sử dụng API getStats() cũ cho đến Chrome 121.