Устаревший API getStats()
WebRTC будет удален в Chrome 117, поэтому приложениям, использующим его, необходимо будет перейти на стандартный API. В этой статье объясняется, как перенести код и что делать, если вам нужно больше времени для внесения этого изменения.
Исторически существовало две конкурирующие версии API WebRTC getStats()
. Устаревший API getStats(), который предшествует процессу стандартизации и принимает аргумент обратного вызова, а также стандартизированный и широко поддерживаемый API, который возвращает обещание.
Стандартный API более функционален и имеет четко определенные метрики, публично задокументированные в спецификации W3C « Идентификаторы для API статистики WebRTC» . Спецификация включает описания каждой метрики, перечисленной в этом руководстве, и многих других.
Начиная с Chrome 117, устаревший API getStats()
будет генерировать исключение в канале стабильной версии (выдача исключений будет постепенно внедряться). Следуйте этому руководству, чтобы облегчить переход на стандартный API.
Устаревшие и стандартные типы статистики
Полный список стандартных типов статистики можно найти, просмотрев перечисление 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, у которого нет соответствующего устаревшего типа:
|
Сопоставление устаревших и стандартных метрик
Это сопоставление призвано помочь разработчикам определить, какая устаревшая метрика соответствует какой стандартной метрике, но учтите, что соответствующая метрика может использовать другие единицы измерения или выражаться в виде общего счетчика, а не мгновенного значения. Определения метрик см. в спецификации.
Стандартный 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 | |
.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 | Недавнее соотношение скрытых выборок, пока поток не молчал: of ( 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 | Единственная оставшаяся гугл-метрика. 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 поддерживает одновременную передачу
Если вы используете одновременную рассылку, вы, возможно, заметили, что устаревший 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.