WebRTC: 기존 getStats() 이전 가이드

Henrik Boström
Henrik Boström

기존 getStats() WebRTC API가 Chrome 117에서 삭제될 예정이므로 이를 사용하는 앱을 표준 API로 이전해야 합니다. 이 도움말에서는 코드를 이전하는 방법과 이 변경사항을 적용하는 데 시간이 더 필요한 경우 취해야 할 조치를 설명합니다.

이전에 WebRTC getStats() API는 서로 경쟁하는 두 가지 버전이 있었습니다. 표준화 프로세스 전에 사용되어 콜백 인수를 취하는 기존의 getStats() API와 프라미스를 반환하는 표준화되고 광범위하게 지원되는 API.

표준 API는 기능이 더 풍부하며 W3C 사양 WebRTC의 Statistics API를 위한 식별자에 공개적으로 나와 있는 잘 정의된 측정항목이 있습니다. 사양에는 이 가이드에 나열된 각 측정항목에 대한 설명과 기타 여러 항목이 포함되어 있습니다.

Chrome 117부터 기존 getStats() API는 안정화 버전 출시 채널에서 예외를 발생시킵니다 (예외 발생은 점진적으로 출시됨). 이 가이드를 따라 보다 쉽게 표준 API로 전환할 수 있습니다.

기존 통계 및 표준 통계 유형

표준 통계 유형의 전체 목록은 사양의 RTCStatsType enum에서 확인할 수 있습니다. 여기에는 각 유형에 대해 수집된 측정항목을 설명하는 통계 사전 정의가 포함됩니다.

통계 객체에는 모두 여러 getStats() 호출에서 기본 객체를 고유하게 식별하는 ID 속성이 있습니다. 동일한 객체는 메서드가 호출될 때마다 같은 ID를 가집니다. 이는 측정항목의 변화율을 계산하는 데 유용합니다 (다음 섹션에 예시가 있음). 또한 ID는 참조의 관계를 형성합니다. 예를 들어 outbound-rtp 통계 객체는 outbound-rtp.mediaSourceId 속성을 통해 연결된 media-source 통계 객체를 참조합니다. ...Id 관계를 모두 그리면 그래프가 표시됩니다.

기존 API에는 다음과 같은 표준 유형에 해당하는 통계 유형이 있습니다.


기존 유형

표준 유형
ssrc
RTP 스트림 및 연결된 MediaStreamTrack에 대한 측정항목을 나타냅니다.


표준 유형은 inbound-rtp (수신 RTP 스트림 및 연결된 원격 MediaStreamTrack용), outbound-rtp (RTP 스트림 전송용) 및 media-source (전송 RTP 스트림과 연결된 로컬 MediaStreamTrack 측정항목용)입니다. RTP 스트림 측정항목에는 RTP 스트림에서 사용하는 인코더 또는 디코더에 관한 정보도 포함됩니다.
VideoBwe
대역폭 추정 측정항목, 타겟 비트 전송률, 인코더 비트 전송률 및 실제 비트 전송률. 이러한 유형의 측정항목은 RTP 측정항목 (outbound-rtpinbound-rtp)과 ICE 후보 쌍 측정항목 (candidate-pair)에 포함됩니다.
googComponent
전송 (ICE 및 DTLS)을 나타냅니다. 표준 버전은 transport입니다.
localcandidate and remotecandidate
ICE 후보를 나타냅니다. 표준 버전은 local-candidateremote-candidate입니다.
googCandidatePair
로컬 및 원격 후보의 쌍인 ICE 후보 쌍을 나타냅니다. 표준 버전은 candidate-pair입니다.
googCertificate
DTLS 전송에 사용되는 인증서를 나타냅니다. 표준 버전은 certificate입니다.
googLibjingleSession
RTCPeerConnection를 나타냅니다. 그 내용은 표준의 어떤 항목에도 매핑되지 않지만, 표준에는 RTCPeerConnection: peer-connection와 연결된 유형이 있습니다.

기존 API에서 누락

다음 통계 유형이 해당 기존 유형이 없는 표준 API에 추가되었습니다.
<ph type="x-smartling-placeholder">
    </ph>
  • codec: 현재 RTP 스트림에서 인코딩 또는 디코딩에 사용 중인 코덱입니다. SDP에서 협상된 코덱의 하위 집합입니다.
  • remote-inbound-rtp: 이 엔드포인트에서 전송하는 아웃바운드 RTP 스트림 (outbound-rtp)에 해당하는 원격 엔드포인트의 인바운드 RTP 스트림입니다. 이는 원격 엔드포인트에서 측정되고 RTCP Receiver Report (RR) 또는 RTCP Extended Report (XR)를 통해 보고됩니다.
  • remote-outbound-rtp: 이 엔드포인트의 수신 RTP 스트림 (inbound-rtp)에 해당하는 원격 엔드포인트의 아웃바운드 RTP 스트림입니다. 이는 원격 엔드포인트에서 측정되고 RTCP 발신자 보고서 (SR)에 보고됩니다.
  • media-playout: 인바운드 RTP 스트림 (inbound-rtp)과 연결된 원격 MediaStreamTrack의 재생에 대한 측정항목입니다.
  • 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.localCandidateId에서 candidate-pair 역방향 조회)
.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.protocolremote-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] 범위 내에 있지만 표준 MErc는 [0..1] 범위 내에 있습니다.
.audioOutputLevel
inbound-rtp.audioLevel입니다. 기존 측정항목은 [0..32768] 범위 내에 있지만 표준 MErc는 [0..1] 범위 내에 있습니다.
.packetsLost inbound-rtp.packetsLost
.googTrackId 로컬 MediaStreamTrack의 경우 media-source.trackIdentifier, 원격 MediaStreamTrack의 경우 inbound-rtp.trackIdentifier
.googRtt remote-inbound-rtp.roundTripTime (outbound-rtp.remoteId 참고)
.googEchoCancellationReturnLossEnhancement inbound-rtp.echoReturnLossEnhancement
.googCodecName 코덱 이름은 '유형/하위 유형'의 하위유형임 MIME 유형, codec.mimeType (inbound-rtp.codecIdoutbound-rtp.codecId 참고)
.transportId inbound-rtp.transportIdoutbound-rtp.transportId
.mediaType inbound-rtp.kindoutbound-rtp.kind 또는 media-source.kind
.googEchoCancellationReturnLoss inbound-rtp.echoReturnLoss
.totalAudioEnergy inbound-rtp.totalAudioEnergymedia-source.totalAudioEnergy
ssrc.totalSamplesDuration inbound-rtp.totalSamplesDurationmedia-source.totalSamplesDuration
.ssrc inbound-rtp.ssrcoutbound-rtp.ssrc
.googJitterReceived inbound-rtp.jitter
.packetsSent outbound-rtp.packetsSent
.bytesSent outbound-rtp.bytesSent
.googContentType inbound-rtp.contentTypeoutbound-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의 변경 속도이지만 실제로는 FPS를 인코딩하는 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

inbound-rtp.qpSumoutbound-rtp.qpSum

.framesEncoded outbound-rtp.framesEncoded
.googAvgEncodeMs

outbound-rtp.totalEncodeTime/outbound-rtp.framesEncoded

.codecImplementationName

inbound-rtp.decoderImplementationoutbound-rtp.encoderImplementation

.googCpuLimitedResolution
outbound-rtp.qualityLimitationReason == "cpu"인 경우 true
.googBandwidthLimitedResolution
outbound-rtp.qualityLimitationReason == "bandwidth"인 경우 true
.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-rtpcandidate-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 + RTP 스트림 비트 전송률의 경우 outbound-rtp.bytesSent의 변경 속도, ICE당 후보 비트 전송률의 경우 candidate-pair.bytesSent, 전송별 비트 전송률의 경우 transport.bytesSent
.googRetransmitBitrate outbound-rtp.retransmittedBytesSent의 변경 범위
.googAvailableSendBandwidth candidate-pair.availableOutgoingBitrate
.googAvailableReceiveBandwidth candidate-pair.availableIncomingBitrate

표준 API는 동시캐스트 인식

동시캐스트를 사용하는 경우 동시캐스트를 사용하여 세 개의 개별 SSRC를 통해 세 개의 RTP 스트림을 전송하는 경우에도 기존 API는 단일 SSRC만 보고한다는 사실을 알 수 있습니다.

표준 API는 이러한 제한을 공유하지 않으며 SSRC마다 하나씩 세 개의 outbound-rtp 통계 객체를 반환합니다. 즉, 각 RTP 스트림을 개별적으로 분석할 수 있지만 모든 RTP 전송 스트림의 총 비트 전송률을 얻으려면 이를 직접 집계해야 합니다.

반면에 scalabilityMode API를 통해 구성된 여러 공간 레이어가 있는 SVC 스트림 또는 RTP 스트림은 단일 SSRC를 통해 전송되기 때문에 여전히 단일 outbound-rtp로 표시됩니다.

이전하는 데 시간이 더 필요한 경우

Chrome 117에서 기존 API가 삭제되면 이를 사용하면 예외가 생성됩니다. 시간 내에 코드를 이전할 수 없는 경우 RTCPeerConnection 콜백 기반 getStats() API 오리진 트라이얼을 통해 등록된 웹사이트의 이전 기간을 연장할 수 있습니다. 오리진 트라이얼 토큰이 있으면 Chrome 121까지 기존 getStats() API를 계속 사용할 수 있습니다.