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

Henrik Boström
Henrik Boström

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

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

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

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

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

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

ออบเจ็กต์สถิติทั้งหมดมีแอตทริบิวต์ id ที่ระบุออบเจ็กต์พื้นฐานที่ไม่ซ้ำกันในการเรียกใช้ 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] แต่เมตริกมาตรฐานอยู่ในช่วง [0..1]
.audioOutputLevel
inbound-rtp.audioLevel เมตริกเดิมอยู่ในช่วง [0..32768] แต่เมตริกมาตรฐานอยู่ในช่วง [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 "type/subtype" 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
Google เมตริกที่เหลือเพียงชุดเดียว 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

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

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

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

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

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