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-rtp và inbound-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-candidate và remote-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:
|
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.protocol và remote-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.codecId và outbound-rtp.codecId ) |
.transportId
|
inbound-rtp.transportId và outbound-rtp.transportId |
.mediaType
|
inbound-rtp.kind và outbound-rtp.kind hoặc media-source.kind
|
.googEchoCancellationReturnLoss
|
inbound-rtp.echoReturnLoss
|
.totalAudioEnergy
|
inbound-rtp.totalAudioEnergy và media-source.totalAudioEnergy
|
ssrc.totalSamplesDuration
|
inbound-rtp.totalSamplesDuration và media-source.totalSamplesDuration
|
.ssrc
|
inbound-rtp.ssrc và outbound-rtp.ssrc
|
.googJitterReceived
|
inbound-rtp.jitter
|
.packetsSent
|
outbound-rtp.packetsSent
|
.bytesSent
|
outbound-rtp.bytesSent
|
.googContentType
|
inbound-rtp.contentType và outbound-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.framesDecoded – inbound-rtp.framesDropped |
.hugeFramesSent
|
outbound-rtp.hugeFramesSent
|
.qpSum
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.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.fecPacketsReceived – inbound-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.concealedSamples – inbound-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-rtp và candidate-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.bytesSent – outbound-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.