従来の getStats()
WebRTC API は Chrome 117 で削除されるため、この API を使用しているアプリは標準 API に移行する必要があります。この記事では、コードを移行する方法と、この変更に時間が必要な場合の対処方法について説明します。
これまで、WebRTC getStats()
API には 2 つのバージョンが競合していました。標準化プロセスより前から存在し、コールバック引数を受け取る以前の getStats() API と、Promise を返す標準化された広くサポートされている API。
標準 API は機能が豊富で、W3C 仕様の WebRTC の 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 に追加され、対応するレガシー タイプはありません。
|
従来の指標と標準指標のマッピング
このマッピングは、どの以前の指標がどの標準指標に対応しているかを簡単に特定できるようにすることを目的としていますが、対応する指標では異なる単位が使用されていたり、瞬間値ではなく合計カウンタとして表されたりする場合があります。指標の定義については、仕様をご覧ください。
標準 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
|
残りの 1 つの 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
|
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 は同時対応モデルです。
同時配信を使用している場合、(たとえば)3 つの RTP ストリームを 3 つの異なる SSRC で送信するために従来の API が報告するのは 1 つの SSRC のみであることにお気づきかもしれません。
標準 API はこの制限を共有しておらず、SSRC ごとに 1 つずつ、3 つの outbound-rtp
統計情報オブジェクトを返します。つまり、各 RTP ストリームを個別に分析できますが、すべての RTP 送信ストリームの合計ビットレートを取得するには、自分で集計する必要があります。
一方、scalabilityMode
API を介して構成された複数の空間レイヤを含む SVC ストリームまたは RTP ストリームは、単一の SSRC を介して送信されるため、引き続き単一の outbound-rtp
として表示されます。
移行に時間が必要な場合
Chrome 117 で以前の API が削除された場合、それを使用すると例外が生成されます。コードを期限内に移行できない場合、RTCPeerConnection コールバック ベースの getStats() API のオリジン トライアルを利用すると、登録済みのウェブサイトの移行期間を延長できます。オリジン トライアル トークンについては、Chrome 121 まで以前の getStats() API を引き続き使用できます。