WebRTC: راهنمای انتقال Legacy getStats().

هنریک بوستروم
Henrik Boström

API قدیمی getStats() WebRTC در Chrome 117 حذف می‌شود، بنابراین برنامه‌هایی که از آن استفاده می‌کنند باید به API استاندارد مهاجرت کنند. این مقاله نحوه انتقال کد خود را توضیح می دهد و اگر برای انجام این تغییر به زمان بیشتری نیاز دارید، چه کاری باید انجام دهید.

از لحاظ تاریخی دو نسخه رقیب از WebRTC getStats() API وجود داشته است. API قدیمی getStats () که پیش از فرآیند استانداردسازی است و آرگومان برگشتی را می گیرد و API استاندارد شده و به طور گسترده پشتیبانی می شود که یک وعده را برمی گرداند.

API استاندارد دارای ویژگی‌های غنی‌تر است و معیارهای کاملاً مشخصی دارد که به‌طور عمومی در شناسه‌های مشخصات W3C برای WebRTC's Statistics API مستند شده‌اند. این مشخصات شامل توضیحات هر معیار ذکر شده در این راهنما و بسیاری موارد دیگر است.

از Chrome 117، API قدیمی getStats() یک استثنا در کانال انتشار پایدار ایجاد می کند (پرتاب استثنا به تدریج منتشر می شود). برای سهولت انتقال خود به API استاندارد، این راهنما را دنبال کنید.

میراث در مقابل انواع آمار استاندارد

فهرست کامل انواع استانداردهای آماری را می توان با نگاه کردن به فهرست RTCStatsType در مشخصات پیدا کرد. این شامل تعریف فرهنگ لغت آماری است که معیارهای جمع آوری شده برای هر نوع را توصیف می کند.

اشیاء stats همگی دارای یک ویژگی 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() محاسبه کند. مثلا:

// 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
تنها goog-metric باقی مانده است. 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 استفاده می کنید، ممکن است متوجه شده باشید که API قدیمی فقط یک SSRC منفرد را گزارش می کند، حتی زمانی که از simulcast برای ارسال (به عنوان مثال) سه جریان RTP روی سه SSRC جداگانه استفاده می کنید.

API استاندارد این محدودیت را ندارد و سه شیء آماری outbound-rtp را برمی گرداند، یکی برای هر یک از SSRC ها. این بدان معنی است که شما می توانید هر جریان RTP را به صورت جداگانه تجزیه و تحلیل کنید، اما همچنین به این معنی است که برای به دست آوردن کل بیت ریت تمام جریان های ارسال RTP باید خودتان آنها را جمع آوری کنید.

از سوی دیگر، جریان‌های SVC یا جریان‌های RTP با لایه‌های فضایی متعددی که از طریق API scalabilityMode پیکربندی شده‌اند، همچنان به‌عنوان یک outbound-rtp واحد نشان داده می‌شوند، زیرا اینها از طریق یک SSRC منفرد ارسال می‌شوند.

اگر به زمان بیشتری برای مهاجرت نیاز دارید

هنگامی که API قدیمی در Chrome 117 حذف می‌شود، استفاده از آن یک استثنا ایجاد می‌کند. اگر نمی‌توانید کد خود را به موقع منتقل کنید، آزمایش اصلی برای API مبتنی بر تماس RTCPeerConnection getStats() به وب‌سایت‌های ثبت‌شده زمان بیشتری برای مهاجرت می‌دهد. با کد آزمایشی اصلی، API قدیمی getStats() ممکن است تا Chrome 121 استفاده شود.