הגרסה הקודמת של WebRTC API עם getStats()
תוסר מ-Chrome 117, ולכן אפליקציות שמשתמשות בו יצטרכו לעבור ל-API הרגיל. במאמר הזה נסביר איך להעביר את הקוד ומה צריך לעשות אם נדרש זמן נוסף לביצוע השינוי.
בעבר היו שתי גרסאות מתחרות של WebRTC getStats()
API. ה-API הקודם של getStats() , שמעדכן את תהליך הסטנדרטיזציה ומקבל ארגומנט קריאה חוזרת, ואת ה-API הסטנדרטי שנתמך בתפוצה רחבה שמחזיר הבטחה.
ה-API הסטנדרטי הוא יותר עשיר בתכונות, ויש בו מדדים מוגדרים היטב המתועדים באופן ציבורי במפרט W3C מזהים עבור Statistics API של WebRTC. המפרט כולל תיאורים של כל מדד שמופיע במדריך הזה, והרבה נושאים נוספים.
החל מגרסה 117 של Chrome, ה-API הקודם של getStats()
יגרום לחריגה בערוץ ההפצה היציבה (הזרקה החריגה תושק בהדרגה). המדריך הזה יעזור לכם לעבור בקלות ל-API הרגיל.
נתונים סטטיסטיים מדור קודם לעומת נתונים סטטיסטיים רגילים
הרשימה המלאה של סוגי נתונים סטטיסטיים סטנדרטיים זמינה במפרט RTCStatsType במפרט. כולל אילו הגדרות מילון של נתונים סטטיסטיים מתארות את המדדים שנאספו עבור כל סוג.
לכל האובייקטים של הנתונים הסטטיסטיים יש מאפיין מזהה שמזהה באופן ייחודי את האובייקט הבסיסי בכמה קריאות של getStats()
. לאותו אובייקט יהיה אותו מזהה בכל קריאה ל-method. האפשרות הזו שימושית לחישוב שיעור שינוי המדדים (דוגמה לכך בקטע הבא). המזהים גם יוצרים קשרי גומלין בין קובצי עזר. לדוגמה, אובייקט הנתונים הסטטיסטיים 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 הרגיל שאין להם סוג תואם מדור קודם:
|
מיפוי המדדים הקודמים למדדים רגילים
המיפוי הזה נועד לעזור למפתחים לגלות איזה מדד מדור קודם תואם לכל מדד סטנדרטי, אבל חשוב לזכור שהמדד התואם עשוי להשתמש ביחידות שונות או לבטא אותו כמונה כולל ולא כערך מיידי. יש לעיין במפרט להגדרות המדדים.
ב-API הרגיל עדיף לחשוף ספירות כוללים במקום תעריפים. כלומר, כדי לקבל את הקצב התואם (למשל, קצב העברת הנתונים) כמו ב-API הקודם, האפליקציה צריכה לחשב את הקצב הממוצע על ידי בדיקת דלתא בין שתי קריאות של getStats()
. לדוגמה:
// 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, 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
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.googCpuLimitedResolution
|
True אם outbound-rtp.qualityLimitationReason == "cpu" |
.googBandwidthLimitedResolution
|
True אם 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
|
הבייטים שהמקודד מפיק הם הבייטים של המטען הייעודי (Payload), לא כולל העברות חוזרות: קצב השינוי של 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, יכול להיות שתשימו לב שה-API הקודם מדווח רק על SSRC אחד, גם כשאתם משתמשים בסימולטנות כדי לשלוח (לדוגמה) שלושה זרמי RTP עם שלושה זרמי SSRC נפרדים.
ה-API הרגיל לא חולק את המגבלה הזו, והוא יחזיר שלושה אובייקטים של נתונים סטטיסטיים מסוג outbound-rtp
, אחד לכל אחד מה-SSRC. המשמעות היא שאתם יכולים לנתח כל שידור RTP בנפרד, אבל המשמעות היא גם שכדי לקבל את קצב העברת הנתונים הכולל של כל שידורי RTP, תצטרכו לצבור אותם בעצמכם.
סטרימינג של SVC או שידורי RTP עם כמה שכבות מרחביות שהוגדרו באמצעות ה-API של scalabilityMode
עדיין מופיעים כ-outbound-rtp
יחיד כי הם נשלחים דרך SSRC יחיד.
אם נדרש לכם עוד זמן להעברה
כשמסירים את ה-API הקודם מ-Chrome 117, השימוש בו יגרום לחריגה. אם לא תוכלו להעביר את הקוד בזמן, גרסת המקור לניסיון של API getStats() של RTCPeerConnection מבוססת קריאה חוזרת מעניקה לאתרים רשומים זמן נוסף לביצוע ההעברה. עם אסימון מקור לניסיון, ניתן להמשיך להשתמש ב-API הקודם של getStats() עד Chrome 121.