以前の getStats()
WebRTC API は Chrome 117 で削除されるため、この API を使用しているアプリは標準 API に移行する必要があります。この記事では、コードを移行する方法と、この変更にさらに時間が必要な場合の対処方法について説明します。
これまで、WebRTC getStats()
API には 2 つの競合するバージョンがありました。標準化プロセスより前から存在し、コールバック引数を取る以前の getStats() API と、Promise を返す標準化された幅広くサポートされている API
標準 API は機能が豊富で、明確に定義された指標が W3C 仕様の Identifiers for WebRTC's Statistics API で公開されています。仕様には、このガイドでリストされている各指標の説明など、多数の指標が含まれています。
Chrome 117 以降では、従来の getStats()
API は Stable リリース チャンネルで例外をスローします(例外のスローは段階的にリリースされます)。このガイドに従うと、標準 API に簡単に移行できます。
従来版と標準の統計情報タイプ
標準統計タイプの完全なリストは、仕様の RTCStatsType 列挙型で確認できます。これには、どの統計ディクショナリの定義が、タイプごとに収集される指標を記述しているかも含まれます。
統計オブジェクトはすべて、複数の 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-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 に追加されていますが、対応する以前のタイプはありません。 <ph type="x-smartling-placeholder">
|
以前の指標から標準の指標へのマッピング
このマッピングは、どの以前の指標がどの標準指標に対応しているかをデベロッパーが特定できるようにすることを目的としています。ただし、対応する指標は異なる単位を使用したり、瞬間値ではなく合計カウンタとして表されたりする場合があります。指標の定義については、仕様をご覧ください。
標準 API では、レートよりも合計カウンタを公開することをおすすめします。つまり、以前の API のように対応するレート(ビットレートなど)を取得するには、アプリで 2 つの 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 ( candidate-pair.remoteCandidateId で remote-candidate を検索) |
.googReadable
|
googReadable は、candidate-pair.requestsReceived または candidate-pair.responsesReceived が最近インクリメントされたかどうかを表すブール値です。
|
.googLocalAddress
|
local-candidate.address ( candidate-pair.localCandidateId で local-candidate を検索) |
.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] ですが、標準 metrc の範囲は [0..1] です。 |
.audioOutputLevel
|
inbound-rtp.audioLevel 。従来の指標は範囲 [0..32768] にありますが、標準 metrc は範囲 [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.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 の変化率ですが、これは 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
|
|
.framesEncoded
|
outbound-rtp.framesEncoded
|
.googAvgEncodeMs
|
|
.codecImplementationName
|
|
.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-metric は 1 つだけです。 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
|
RTP ストリームごとのビットレートの場合は outbound-rtp.headerBytesSent + outbound-rtp.bytesSent 、ICE ごとの候補ビットレートの場合は candidate-pair.bytesSent 、トランスポートごとのビットレートの場合は transport.bytesSent の変化率 |
.googRetransmitBitrate
|
outbound-rtp.retransmittedBytesSent の変化範囲 |
.googAvailableSendBandwidth
|
candidate-pair.availableOutgoingBitrate
|
.googAvailableReceiveBandwidth
|
candidate-pair.availableIncomingBitrate
|
標準 API は同時キャスト対応
サイマルキャストを使用している場合、以前の API では、サイマルキャストを使用して(たとえば 3 つの別々の SSRC に)3 つの RTP ストリームを送信している場合でも、1 つの SSRC しか報告されないことにお気づきかもしれません。
標準 API にはこの制限はなく、3 つの outbound-rtp
統計情報オブジェクト(SSRC ごとに 1 つずつ)が返されます。つまり、各 RTP ストリームを個別に分析できますが、すべての RTP 送信ストリームの合計ビットレートを取得するには、自分で集約する必要があります。
一方、scalabilityMode
API を介して複数の空間レイヤが設定された SVC ストリームまたは RTP ストリームは、単一の SSRC を介して送信されるため、単一の outbound-rtp
として表示されます。
移行に時間が必要な場合
Chrome 117 で以前の API が削除されると、この API を使用すると例外が発生します。コードを時間内に移行できない場合は、RTCPeerConnection コールバック ベースの getStats() API のオリジン トライアルを利用して、登録されているウェブサイトを移行する時間を確保してください。オリジン トライアル トークンを使用する場合、Chrome 121 までは以前の getStats() API を引き続き使用できます。