ستتم إزالة واجهة برمجة التطبيقات getStats()
WebRTC API القديمة في الإصدار 117 من Chrome، لذا على التطبيقات التي تستخدمها نقل بياناتها إلى واجهة برمجة التطبيقات العادية. توضّح هذه المقالة كيفية نقل الرمز البرمجي، وما يجب فعله إذا كنت بحاجة إلى مزيد من الوقت لإجراء هذا التغيير.
في السابق، كان هناك إصداران متنافسان من واجهة برمجة التطبيقات WebRTC getStats()
. واجهة برمجة التطبيقات القديمة getStats() التي تعود إلى ما قبل عملية وضع المعايير وتستخدِم مَعلمة لإجراء معاودة الاتصال، وواجهة برمجة التطبيقات المتوافقة على نطاق واسع والمتوافقة مع المعايير والتي تعرض وعدًا
توفّر واجهة برمجة التطبيقات العادية ميزات أكثر، كما تتضمّن مقاييس محدّدة جيدًا وموثّقة بشكل علني في مواصفات W3C المعرّفات لواجهة برمجة تطبيقات إحصاءات WebRTC. تتضمّن المواصفة أوصافًا لكل مقياس مُدرَج في هذا الدليل وغيرها الكثير.
اعتبارًا من الإصدار 117 من Chrome، ستُعرِض واجهة برمجة التطبيقات getStats()
القديمة استثناءً في قناة الإصدار الثابت (سيتم طرح الاستثناء تدريجيًا). اتّبِع هذا الدليل لتسهيل عملية الانتقال إلى واجهة برمجة التطبيقات العادية.
أنواع الإحصاءات القديمة مقابل أنواع الإحصاءات العادية
يمكن العثور على القائمة الكاملة بأنواع الإحصاءات العادية من خلال الاطّلاع على التعداد RTCStatsType في المواصفات. ويشمل ذلك تعريف قاموس الإحصاءات الذي يصف المقاييس التي يتم جمعها لكل نوع.
تحتوي جميع عناصر الإحصاءات على سمة id التي تحدّد العنصر الأساسي بشكل فريد في طلبات getStats()
المتعددة. سيحتوي العنصر نفسه على المعرّف نفسه في كل مرة يتم فيها استدعاء الطريقة. وهذا مفيد لاحتساب معدّل تغيُّر المقاييس (يتوفر مثال في القسم التالي). تشكل الأرقام التعريفية أيضًا علاقات بين المراجع. على سبيل المثال، يشير عنصر الإحصاءات outbound-rtp
إلى عنصر الإحصاءات media-source
المرتبط به من خلال السمة outbound-rtp.mediaSourceId
. إذا رسمت جميع علاقات ...Id
، ستحصل على رسم بياني.
تتضمّن واجهة برمجة التطبيقات القديمة أنواع الإحصاءات التالية، والتي تتوافق مع الأنواع العادية على النحو التالي:
النوع القديم |
النوع العادي |
---|---|
ssrc
|
يمثّل بثًا عبر بروتوكول RTP ومقاييس عن MediaStreamTrack المرتبط به.الأنواع العادية لهذا النوع هي inbound-rtp (لتلقّي أحداث بث بروتوكول RTP والمقاييس البعيدة المرتبطة بها MediaStreamTrack )، وoutbound-rtp (لإرسال أحداث بث بروتوكول RTP) وmedia-source (لمقاييس MediaStreamTrack المحلية المرتبطة ببث بروتوكول RTP). تحتوي مقاييس مصادر بيانات RTP أيضًا على معلومات عن برنامج الترميز أو فك الترميز المستخدَمَين في مصدر بيانات RTP. |
VideoBwe
|
مقاييس تقدير معدل نقل البيانات ومعدل نقل البيانات المستهدَف ومعدل نقل البيانات في برنامج الترميز ومعدل نقل البيانات الفعلي تشكّل هذه الأنواع من المقاييس جزءًا من مقاييس بروتوكول النقل في الوقت الفعلي ( 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 . |
غير متوفّر في واجهة برمجة التطبيقات القديمة |
تمّت إضافة أنواع الإحصاءات هذه إلى واجهة برمجة التطبيقات العادية التي لا تتضمّن أيّ نوع قديم مناظر:
|
ربط المقاييس القديمة بالمقاييس العادية
يهدف هذا الربط إلى مساعدة المطوّرين في العثور على المقياس القديم الذي يتوافق مع المقياس العادي، ولكن يُرجى العِلم أنّ المقياس المقابل قد يستخدم وحدات مختلفة أو يتم التعبير عنه كعداد إجمالي بدلاً من قيمة فورية. يُرجى الرجوع إلى المواصفات لمعرفة تعريفات المقاييس.
تفضّل واجهة برمجة التطبيقات العادية عرض إجمالي العدّادات بدلاً من المعدّلات. وهذا يعني أنّه للحصول على معدّل البث المقابل (مثل معدل نقل البيانات) كما هو الحال في واجهة برمجة التطبيقات القديمة، على التطبيق احتساب متوسّط معدّل البث من خلال احتساب الفرق بين طلبَي 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;
قد يبدو لك أنّ احتساب الأسعار والمتوسّطات بنفسك بهذه الطريقة هو خطوة إضافية مزعجة، ولكنّ لها ميزة تتيح لك الحصول على متوسّطات خلال أيّ فاصل زمني مطلوب. إنّ استدعاء واجهة برمجة التطبيقات العادية بمعدّل أقلّ من معدّل استدعاء واجهة برمجة التطبيقات القديمة قد يحقّق بعض المزايا في الأداء.
المقياس القديم
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
|
على الرغم من أنّ عدد اللقطات في الثانية المُرسَلة هو معدّل تغيير outbound-rtp.framesSent ، يتم تنفيذ ذلك في الواقع على أنّه outbound-rtp.framesPerSecond الذي يُعدّ ترميز عدد اللقطات في الثانية. |
.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
|
صحيح إذا 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
|
واجهة برمجة التطبيقات العادية متوافقة مع البث المباشر المتزامن
في حال استخدام البث المتزامن، قد تلاحظ أنّ واجهة برمجة التطبيقات القديمة لا تسجِّل سوى مصدر مسؤولية بث واحد حتى في حال استخدام البث المتزامن لإرسال (على سبيل المثال) ثلاثة أحداث بث RTP عبر ثلاثة مصادر مسؤولية بث منفصلة.
لا تفرض واجهة برمجة التطبيقات العادية هذا القيد، وستُرجع ثلاثة عناصر إحصاءات outbound-rtp
، واحد لكلّ من معرّفات SSRC. وهذا يعني أنّه يمكنك تحليل كلّ بثّ RTP بشكلٍ فردي، ولكنّه يعني أيضًا أنّه للحصول على إجمالي معدّل نقل البيانات لجميع أحداث إرسال RTP، عليك تجميعها بنفسك.
من ناحية أخرى، لا تزال أحداث بث SVC أو أحداث بث RTP التي تتضمّن عدة طبقات مكانية تم ضبطها من خلال واجهة برمجة التطبيقات scalabilityMode
تظهر كحدث بث outbound-rtp
واحد لأنّه يتم إرسالها عبر مصدر مسؤولية بث واحد.
إذا كنت بحاجة إلى مزيد من الوقت لنقل البيانات
عند إزالة واجهة برمجة التطبيقات القديمة في الإصدار 117 من Chrome، سيؤدي استخدامها إلى حدوث استثناء. إذا لم تتمكّن من نقل الرمز في الوقت المناسب، تمنحك فترة تجريبية لمصدر واجهة برمجة التطبيقات getStats() المستندة إلى طلب إعادة الاتصال RTCPeerConnection المزيد من الوقت لنقل البيانات إلى الإصدار الجديد. باستخدام رمز مميّز لمرحلة التجربة والتقييم، يمكن مواصلة استخدام واجهة برمجة التطبيقات القديمة getStats() حتى الإصدار 121 من Chrome.