WebRTC: คำแนะนำในการย้ายข้อมูล getStats() เดิม

Henrik Boström
Henrik Boström

WebRTC API เดิมของ getStats() จะถูกนำออกจาก Chrome 117 ดังนั้นแอปที่ใช้ WebRTC API เดิมจะต้องย้ายข้อมูลไปยัง API มาตรฐาน บทความนี้อธิบายวิธีย้ายข้อมูลโค้ด และสิ่งที่ต้องทำหากต้องการเวลาเพิ่มเติมเพื่อทำการเปลี่ยนแปลงนี้

ที่ผ่านมา WebRTC getStats() API มี 2 เวอร์ชันที่แข่งขันกัน getStats() API เดิมที่สร้างก่อนวันที่กระบวนการกำหนดมาตรฐานและใช้อาร์กิวเมนต์ Callback รวมถึง API ที่เป็นมาตรฐานและได้รับการสนับสนุนอย่างกว้างขวางซึ่งให้คำมั่นสัญญา

API มาตรฐานมีฟีเจอร์มากกว่าและมีเมตริกที่กำหนดไว้อย่างชัดเจนซึ่งเผยแพร่ไว้ในข้อกำหนดเฉพาะของ W3C ตัวระบุสำหรับ Statistics API ของ WebRTC ข้อกำหนดนี้ประกอบด้วยคำอธิบายของแต่ละเมตริกที่ระบุไว้ในคู่มือนี้และอื่นๆ อีกมากมาย

ตั้งแต่ Chrome 117 เป็นต้นไป API ของ getStats() เวอร์ชันเดิมจะมีข้อยกเว้นในเวอร์ชันการเผยแพร่แบบเสถียร (ระบบจะทยอยเปิดตัวข้อยกเว้นการเปิดตัว) ทำตามคู่มือนี้เพื่อให้การเปลี่ยนไปใช้ API มาตรฐานเป็นไปอย่างง่ายดาย

ประเภทสถิติเดิมเทียบกับมาตรฐาน

คุณสามารถดูรายการประเภทสถิติมาตรฐานทั้งหมดได้ที่ Enum RTCStatsType ในข้อกำหนด ซึ่งรวมถึงคำจำกัดความในพจนานุกรมสถิติที่อธิบายถึงเมตริกที่เก็บรวบรวมสำหรับแต่ละประเภท

ออบเจ็กต์สถิติทั้งหมดมีแอตทริบิวต์รหัส ซึ่งระบุออบเจ็กต์ที่สำคัญโดยไม่ซ้ำกันในการเรียก getStats() หลายครั้ง ออบเจ็กต์เดียวกันจะมีรหัสเดียวกันทุกครั้งที่มีการเรียกเมธอด ซึ่งมีประโยชน์สำหรับการคำนวณอัตราการเปลี่ยนแปลงของเมตริก (มีตัวอย่างในส่วนถัดไป) นอกจากนี้ รหัสยังสร้างความสัมพันธ์ของข้อมูลอ้างอิงด้วย ตัวอย่างเช่น ออบเจ็กต์สถิติ outbound-rtp อ้างอิงออบเจ็กต์สถิติ media-source ที่เชื่อมโยงผ่านแอตทริบิวต์ outbound-rtp.mediaSourceId หากคุณวาดความสัมพันธ์...Idทั้งหมด คุณจะเห็นกราฟ

API เดิมมีประเภทสถิติต่อไปนี้ ซึ่งสอดคล้องกับประเภทมาตรฐานดังนี้


ประเภทเดิม

ประเภทมาตรฐาน
ssrc
แสดงสตรีม RTP และเมตริกเกี่ยวกับ MediaStreamTrack ที่เชื่อมโยง


ประเภทมาตรฐานในกรณีนี้คือ inbound-rtp (สำหรับสตรีม RTP และ MediaStreamTrack ระยะไกลที่เชื่อมโยง), outbound-rtp (สำหรับส่งสตรีม RTP) และ media-source (สำหรับเมตริก MediaStreamTrack ในเครื่องที่เชื่อมโยงกับสตรีม RTP ที่ส่ง) นอกจากนี้ เมตริกของสตรีม RTP ยังมีข้อมูลเกี่ยวกับโปรแกรมเปลี่ยนไฟล์หรือตัวถอดรหัสที่ใช้โดยสตรีม RTP
VideoBwe
เมตริกการประมาณแบนด์วิดท์ อัตราบิตเป้าหมาย อัตราบิตของโปรแกรมเปลี่ยนไฟล์ และอัตราบิตจริง เมตริกประเภทเหล่านี้เป็นส่วนหนึ่งของเมตริก RTP (outbound-rtp และ inbound-rtp) และเมตริกคู่ของตัวเลือก ICE (candidate-pair)
googComponent
แสดงการรับส่งข้อมูล (ICE และ DTLS) เวอร์ชันมาตรฐานคือ transport
localcandidate and remotecandidate
แสดงถึงผู้สมัคร ICE เวอร์ชันมาตรฐานคือ local-candidate และ remote-candidate
googCandidatePair
แสดงคู่ผู้สมัคร ICE ซึ่งเป็นคู่ของผู้สมัครในพื้นที่และผู้สมัครระยะไกล เวอร์ชันมาตรฐานคือ candidate-pair
googCertificate
แสดงใบรับรองที่ใช้โดยการส่ง DTLS เวอร์ชันมาตรฐานคือ certificate
googLibjingleSession
แสดง RTCPeerConnection แม้ว่าเนื้อหาจะไม่เชื่อมโยงกับสิ่งใดในมาตรฐาน แต่มาตรฐานมีประเภทที่เชื่อมโยงกับ RTCPeerConnection: peer-connection

ไม่มีอยู่ใน API เดิม

ระบบได้เพิ่มประเภทสถิติเหล่านี้ลงใน API มาตรฐานที่ไม่มีประเภทเดิมที่เกี่ยวข้องแล้ว:
  • codec: ตัวแปลงรหัสที่สตรีม RTP ใช้อยู่ ทั้งสำหรับการเข้ารหัสหรือถอดรหัส นี่คือชุดย่อยของตัวแปลงรหัสที่มีการเจรจาต่อรองใน SDP
  • remote-inbound-rtp: สตรีม RTP ขาเข้าของปลายทางระยะไกลที่สอดคล้องกับสตรีม RTP ขาออกที่ปลายทางนี้กำลังส่ง (outbound-rtp) โดยจะวัดที่ปลายทางระยะไกลและรายงานในรายงานตัวรับ RTCP (RR) หรือ RTCP Extended Report (XR)
  • remote-outbound-rtp: สตรีม RTP ขาออกของปลายทางระยะไกลที่สอดคล้องกับสตรีม RTP ขาเข้าที่ปลายทางนี้รับอยู่ (inbound-rtp) โดยจะวัดที่ปลายทางระยะไกลและรายงานในรายงานผู้ส่ง RTCP (SR)
  • media-playout: เมตริกเกี่ยวกับการเล่นของ MediaStreamTrack ระยะไกลที่เชื่อมโยงกับสตรีม RTP ขาเข้า (inbound-rtp)
  • data-channel: แสดงถึง RTCDataChannel

การแมปเมตริกเดิมกับมาตรฐาน

การแมปนี้มีจุดมุ่งหมายเพื่อช่วยให้นักพัฒนาแอปค้นหาว่าเมตริกเดิมใดสอดคล้องกับเมตริกมาตรฐานใด แต่โปรดทราบว่าเมตริกที่เกี่ยวข้องอาจใช้หน่วยที่แตกต่างกันหรือแสดงเป็นตัวนับรวมแทนค่าที่ปรากฏทันที โปรดดูข้อมูลจำเพาะของเมตริก
API มาตรฐานต้องการแสดงตัวนับทั้งหมดแทนอัตรา ซึ่งหมายความว่าเพื่อให้ได้อัตราที่สอดคล้องกัน (เช่น อัตราบิต) เหมือนกับใน API เดิม แอปต้องคำนวณอัตราเฉลี่ยโดยใช้เดลต้าระหว่างการเรียกใช้ getStats() 2 ครั้ง เช่น

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

การต้องคำนวณอัตราและหาค่าเฉลี่ยด้วยตนเองเช่นนี้อาจดูเป็นขั้นตอนเพิ่มเติมที่ยุ่งยาก แต่ก็มีข้อดีที่ช่วยให้คุณได้รับค่าเฉลี่ยในช่วงเวลาที่ต้องการ การเรียกใช้ API มาตรฐานมีความถี่ในการเรียกใช้น้อยกว่าที่คุณเคยทำกับ API เดิมมีประโยชน์ด้านประสิทธิภาพบางประการ

เมตริกเดิม
googCertificate
การติดต่อมาตรฐาน
certificate
.googFingerprint .fingerprint
.googFingerprintAlgorithm .fingerprintAlgorithm
.googDerBase64 .base64Certificate
เมตริกเดิม
googComponent
การติดต่อมาตรฐาน
transport
.localCertificateId .localCertificateId
.remoteCertificateId .remoteCertificateId
.selectedCandidatePairId .selectedCandidatePairId
.dtlsCipher .dtlsCipher
.srtpCipher .srtpCipher
เมตริกเดิม
localcandidate
การติดต่อมาตรฐาน
local-candidate หรือ candidate-pair
.stunKeepaliveRequestsSent candidate-pair.requestsSent (การค้นหาแบบย้อนกลับ candidate-pair ผ่าน 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
เมตริกเดิม
remotecandidate
การติดต่อมาตรฐาน
remote-candidate
เหมือนกับ localcandidate ด้านบน เหมือนกับ local-candidate ด้านบน
เมตริกเดิม
googCandidatePair
การติดต่อมาตรฐาน
candidate-pair
.responsesSent candidate-pair.responsesSent
.requestsReceived candidate-pair.requestsReceived
.googRemoteCandidateType remote-candidate.candidateType
(ค้นหา remote-candidate ผ่าน
candidate-pair.remoteCandidateId)
.googReadable googReadable เป็นค่าบูลีนที่สะท้อนให้เห็นว่าเมื่อเร็วๆ นี้เราได้เพิ่มจำนวน candidate-pair.requestsReceived หรือ candidate-pair.responsesReceived หรือไม่
.googLocalAddress local-candidate.address
(ค้นหา local-candidate ผ่าน
candidate-pair.localCandidateId)
.consentRequestsSent candidate-pair.consentRequestsSent
.googTransportType ราคาเท่ากันกับ local-candidate.protocol และ remote-candidate.protocol
.googChannelId candidate-pair.transportId
.googLocalCandidateType local-candidate.candidateType
.googWritable googWritable เป็นค่าบูลีนที่สะท้อนให้เห็นว่าเราเพิ่งเพิ่ม candidate-pair.responsesReceived หรือไม่
.googRemoteAddress remote-candidate.address
.googRtt candidate-pair.currentRoundTripTime
.googActiveConnection การเชื่อมต่อที่ใช้งานอยู่หมายถึงคู่ตัวเลือกซึ่งเลือกโดยการรับส่งข้อมูลอยู่ในขณะนี้ เช่น โดยที่ 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
เมตริกเดิม
ssrc
การติดต่อมาตรฐาน
inbound-rtp outbound-rtp media-source
.audioInputLevel media-source.audioLevel เมตริกเดิมอยู่ในช่วง [0..32768] แต่ Meterc มาตรฐานอยู่ในช่วง [0..1]
.audioOutputLevel
inbound-rtp.audioLevel เมตริกเดิมอยู่ในช่วง [0..32768] แต่ Meterc มาตรฐานอยู่ในช่วง [0..1]
.packetsLost inbound-rtp.packetsLost
.googTrackId media-source.trackIdentifier สำหรับ MediaStreamTrack ในเครือข่าย และ inbound-rtp.trackIdentifier สำหรับ MediaStreamTrack ระยะไกล
.googRtt remote-inbound-rtp.roundTripTime (ดูoutbound-rtp.remoteId)
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName ชื่อตัวแปลงรหัสเป็นประเภทย่อยของ "ประเภท/ประเภทย่อย" ประเภท MIME codec.mimeType (ดู inbound-rtp.codecId และ outbound-rtp.codecId)
.transportId inbound-rtp.transportId และ outbound-rtp.transportId
.mediaType inbound-rtp.kind และ outbound-rtp.kind หรือ media-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergy และ media-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDuration และ media-source.totalSamplesDuration
.ssrc inbound-rtp.ssrc และ outbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentType และ outbound-rtp.contentType
.googFrameWidthInput media-source.width
.googFrameHeightInput media-source.height
.googFrameRateInput media-source.framesPerSecond
.googFrameWidthSent outbound-rtp.frameWidth
.googFrameHeightSent outbound-rtp.frameHeight
.googFrameRateSent
แม้ว่า FPS การส่งคืออัตราการเปลี่ยนแปลง outbound-rtp.framesSent แต่จริงๆ แล้วมีการใช้เป็น outbound-rtp.framesPerSecond ซึ่งเป็นการเข้ารหัส FPS
.googFrameWidthReceived inbound-rtp.frameWidth
.googFrameHeightReceived inbound-rtp.frameHeight
.googFrameRateDecoded
อัตราการเปลี่ยนแปลงของ inbound-rtp.framesDecoded
.googFrameRateOutput
อัตราการเปลี่ยนแปลงของ inbound-rtp.framesDecoded - inbound-rtp.framesDropped
.hugeFramesSent outbound-rtp.hugeFramesSent
.qpSum

inbound-rtp.qpSum และ outbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime / outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementation และ outbound-rtp.encoderImplementation

.googCpuLimitedResolution
จริงหาก outbound-rtp.qualityLimitationReason == "cpu"
.googBandwidthLimitedResolution
จริงหาก outbound-rtp.qualityLimitationReason == "bandwidth"
.googAdaptationChanges
เมตริกเดิมจะนับจำนวนครั้งที่ความละเอียดหรืออัตราเฟรมมีการเปลี่ยนแปลงด้วยเหตุผลที่เกี่ยวข้อง qualityLimitationReason ข้อ ซึ่งอาจอนุมานได้จากเมตริกอื่นๆ (เช่น ความละเอียดในการส่งหรืออัตราเฟรมแตกต่างจากความละเอียดของแหล่งที่มาหรืออัตราเฟรม) แต่ระยะเวลาที่เรามีจำกัด outbound-rtp.qualityLimitationDurations อาจมีประโยชน์มากกว่าความถี่ที่มีการเปลี่ยนแปลงความละเอียดหรืออัตราเฟรมใหม่
.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
อัตราส่วนล่าสุดของแพ็กเก็ตที่มีการแก้ไขข้อผิดพลาด: inbound-rtp.fecPacketsReceived - inbound-rtp.fecPacketsDiscarded
.packetsReceived inbound-rtp.packetsReceived
.googJitterBufferMs inbound-rtp.jitterBufferDelay / inbound-rtp.jitterBufferEmittedCount
.googTargetDelayMs (วิดีโอ) inbound-rtp.jitterBufferTargetDelay / inbound-rtp.jitterBufferEmittedCount
.googPreferredJitterBufferMs (เสียง) inbound-rtp.jitterBufferTargetDelay / inbound-rtp.jitterBufferEmittedCount
.googExpandRate
อัตราส่วนล่าสุดของตัวอย่างที่ซ่อนอยู่: inbound-rtp.concealedSamples / inbound-rtp.totalSamplesReceived
.googSpeechExpandRate อัตราส่วนล่าสุดของตัวอย่างที่ซ่อนอยู่ในขณะที่สตรีมไม่ได้ปิดเสียง: จาก (inbound-rtp.concealedSamples - inbound-rtp.silentConcealedSamples) / inbound-rtp.concealedSamples
.googAccelerateRate อัตราส่วนล่าสุดของตัวอย่างที่ถูกทิ้งเพื่อเร่งความเร็วในการเล่น: inbound-rtp.removedSamplesForAcceleration / inbound-rtp.totalSamplesReceived
.googPreemptiveExpandRate
อัตราส่วนล่าสุดของตัวอย่างที่ผ่านการสังเคราะห์เพื่อลดความเร็วในการเล่น: 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
เมตริก goog เดียวที่เหลืออยู่ วันที่ inbound-rtp.googTimingFrameInfo
.framesDecoded inbound-rtp.framesDecoded
เมตริกเดิม
VideoBwe
การติดต่อมาตรฐาน
outbound-rtp และ candidate-pair
.googTargetEncBitrate
outbound-rtp.targetBitrate เป็นค่าทันทีหรือ outbound-rtp.totalEncodedBytesTarget / outbound-rtp.framesEncoded เป็นค่าเฉลี่ย
.googActualEncBitrate ไบต์ที่เกิดจากโปรแกรมเปลี่ยนไฟล์คือไบต์เพย์โหลด ไม่รวมการส่งข้อมูลซ้ำ: อัตราการเปลี่ยนแปลงของ outbound-rtp.bytesSent - outbound-rtp.retransmittedBytesSent
.googBucketDelay outbound-rtp.totalPacketSendDelay / outbound-rtp.packetsSent
.googTransmitBitrate อัตราการเปลี่ยนแปลงของ outbound-rtp.headerBytesSent + outbound-rtp.bytesSent สำหรับอัตราบิตของสตรีมต่อ RTP, candidate-pair.bytesSent สำหรับอัตราบิตของตัวเลือกต่อ ICE หรือ transport.bytesSent สำหรับอัตราบิตต่อการขนส่ง
.googRetransmitBitrate ช่วงการเปลี่ยนแปลงของ outbound-rtp.retransmittedBytesSent
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

API มาตรฐานคือ simulcast-aware

หากใช้ simulcast คุณอาจสังเกตเห็นว่า API เดิมรายงาน SSRC เพียงครั้งเดียว แม้ว่าคุณกำลังใช้ simulcast เพื่อส่ง (ตัวอย่างเช่น) สตรีม RTP 3 รายการผ่าน SSRC 3 รายการแยกกัน

API มาตรฐานจะไม่แชร์ข้อจำกัดนี้และจะแสดงออบเจ็กต์สถิติ outbound-rtp 3 รายการ 1 รายการสำหรับ SSRC แต่ละรายการ นั่นหมายความว่าคุณสามารถวิเคราะห์สตรีม RTP แต่ละสตรีมได้แยกกัน แต่ก็หมายความว่าคุณจะต้องรวบรวมสตรีมดังกล่าวด้วยตนเองเพื่อให้ได้อัตราบิตรวมของสตรีม RTP ทั้งหมด

ในทางกลับกัน สตรีม SVC หรือ RTP ที่มีเลเยอร์เชิงพื้นที่หลายเลเยอร์ที่กำหนดค่าผ่าน API ของ scalabilityMode จะยังคงแสดงเป็น outbound-rtp เดียวเนื่องจากมีการส่งผ่าน SSRC รายการเดียว

หากต้องการเวลาเพิ่มเติมในการย้ายข้อมูล

เมื่อนํา API เดิมใน Chrome 117 ออก การใช้ API ดังกล่าวจะสร้างข้อยกเว้น หากย้ายข้อมูลโค้ดได้ทันเวลา ช่วงทดลองใช้ต้นทางสำหรับ getStats() API ที่อิงตาม RTCPeerConnection ที่ใช้ Callback จะทำให้เว็บไซต์ที่ลงทะเบียนมีเวลาในการย้ายข้อมูลมากขึ้น โทเค็น getStats() เดิมอาจใช้ต่อไปจนถึง Chrome 121 ด้วยโทเค็นการทดลองใช้จากต้นทาง