DocumentationUser GuideTipsStatistical Analysis

Statistical Analysis

This page has not been translated yet.

SkyWay の getStats() API について

getStats() API を利用することで、API を呼び出した時点での、WebRTC 通信の統計情報を取得できます。

現時点(2023 年 6 月 20 日)では、getStats() API は 試験的に提供しています。この API のインタフェースは今後変更される可能性があります。

JavaScript SDK では v1.0.0 より、iOS / Android SDKでは v1.2.0 より提供しています。

JavaScript SDK の getStats() API について

getStats() API の返り値は、 WebRTCStats オブジェクトです。API の詳細は API リファレンスを参照してください。

WebRTCStats は複数の RTCStats 型から派生するディクショナリで構成されます。

Ƭ WebRTCStats: { [key: string]: any; id: string ; type: string }[]

RTCStatsType 型の type メンバーは RTCStats 派生オブジェクトの型を示します。

dictionary RTCStats { required DOMHighResTimeStamp timestamp; required RTCStatsType type; required DOMString id; };

RTCStats の詳細仕様についてはこちらを参照ください。

RTCStatsType 型は以下の通り定義されています。

enum RTCStatsType { "codec", "inbound-rtp", "outbound-rtp", "remote-inbound-rtp", "remote-outbound-rtp", "media-source", "media-playout", "peer-connection", "data-channel", "stream", "track", "transport", "candidate-pair", "local-candidate", "remote-candidate", "certificate" };

RTCStatsType の詳細仕様についてはこちらを参照ください。

RTCStatsType と、RTCStats 派生オブジェクトは以下の通り紐付きます。

RTCStatsTypeRTCStats 派生オブジェクト
codecRTCCodecStats
inbound-rtpRTCInboundRtpStreamStats
outbound-rtpRTCOutboundRtpStreamStats
remote-inbound-rtpRTCRemoteInboundRtpStreamStats
remote-outbound-rtpRTCRemoteOutboundRtpStreamStats.
media-sourceRTCAudioSourceStats or RTCVideoSourceStats
media-playoutRTCAudioPlayoutStats
peer-connectionRTCPeerConnectionStats
data-channelRTCDataChannelStats
streamRTCMediaStreamStats
trackRTCMediaStreamTrackStats
transportRTCTransportStats
candidate-pairRTCIceCandidatePairStats
local-candidateRTCIceCandidateStats
remote-candidateRTCIceCandidateStats
certificateRTCCertificateStats

*) 仕様で定義されている物が全てブラウザで実装されているわけではないので、注意が必要です。

RTCStats 派生オブジェクトによって持つ情報が異なるため、RTCStatsType の値に応じた処理を行う必要があります。

一例として、RTCCodecStats オブジェクトは以下の構造になっています。

dictionary RTCCodecStats : RTCStats { required unsigned long payloadType; required DOMString transportId; required DOMString mimeType; unsigned long clockRate; unsigned long channels; DOMString sdpFmtpLine; };

サンプルコード

setInterval(async () => { const stats = await publication.getStats(subscriber); // stats is [{},{},{},...] stats.forEach((report) => { // When report is `RTCCodecStats` Object. if(report.type == "codec") { console.log(report.clockRate); // 90000 } }); }, 1000);

iOS SDK の getStats() API について

RTCStatsType と、RTCStats 派生オブジェクトに関しては JavaScript と同様です。上記のセクションをご確認ください。

サンプルコード

DispatchQueue.main.async { Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in let stats = publication.getStats(memberId: subscriberId) stats?.reports.forEach({ report in if report.type == "codec" { if let clockRate = report.params["clockRate"] as? NSNumber { print(clockRate) // 90000 } } }) } }

独自に SKWWebRTCStats 型を定義しており、reports にアクセスし、forループなどで type をチェックしてください。

RTCStats 派生オブジェクトの value (上記の例だと report.params["clockRate"] )が取りうる値の型は NSString NSNumber NSDataです。

Bool は NSNumber(0 or 1) で表現されます。

配列・オブジェクトの場合、JSON 文字列を NSData で返します。

Android SDK の getStats() API について

RTCStatsType と、RTCStats 派生オブジェクトに関しては JavaScript と同様です。上記のセクションをご確認ください。

サンプルコード

val handler = Handler(Looper.getMainLooper()) handler.post(object : Runnable { override fun run() { publication.getStats(subscriberId)?.let { stats -> stats.reports.filter { it.id.contains("RTCCodec") }.forEach { Log.d("app", "clockRate: " + it.params["clockRate"].toString()) } } handler.postDelayed(this, 1000) } })

独自に WebRTCStats 型を定義しており、reportsにアクセスし、forループなどで type をチェックしてください。

RTCStats 派生オブジェクトの value は Gson の JsonElement として取得します。

通信品質を判断する上で主要な項目

取得できる統計情報は、ブラウザとブラウザバージョンによって異なりますが、多くのブラウザで共通して取得でき、通話品質に大きく関係するものをいくつか説明します。

種別定義使い方
コーデックRTCCodecStats.codecコーデックによっては CPU 使用率が高いものや特有のバグがあるものがあります
遅延RTCIceCandidatePairStats.currentRoundTripTime遅延が大きい(300ms 以上)と体感品質が下がると言われています
パケットロスRTCReceivedRtpStreamStats.packetsLostパケットロスが発生すると、音声や映像が途切れ途切れになります。パケロス率が 10%を超えていると体感品質が下がると言われています
ジッタRTCReceivedRtpStreamStats.jitterジッタの値が高い場合、通信経路のどこかで輻輳が起きていることが想定され、WebRTC はより低い解像度やフレームレートでの送信を試みます。試みたにも関わらず、ジッタが発生し続ける場合には、映像や音声の送信(受信)を止める必要があります
映像のフレームレートRTCMediaStreamTrackStats.framesPerSecond映像のフレームレートが低いことを検知できます
映像の解像度RTCMediaStreamTrackStats.frameWidth /RTCMediaStreamTrackStats.frameHeight映像の解像度が低いことを検知できます
音声の音量RTCMediaStreamTrackStats.audioLevel音声の音量が低いことを検知できます
通信経路の種別RTCIceCandidateStats.candidateType自身および相手が TURN を利用しているかを判別できます(relay の場合)
IP アドレスRTCIceCandidateStats.ip自身および相手の IP アドレスが把握できます。位置情報と組み合わせることで自身と相手の距離を把握することができます
TURN サーバーとの通信プロトコルRTCIceCandidateStats.relayProtocol自身が TURN サーバーと UDP と TCP のどちらで通信しているかが把握できます。TCP の場合は、遅延が発生しやすいです。
送信帯域幅RTCIceCandidatePairStats.availableOutgoingBitrate自身が送信可能な帯域幅が把握できます。
エンコード時間RTCOutboundRtpStreamStats.totalEncodeTimeメディアのエンコードにどれだけ時間がかかっているかを把握できます。エンコードに時間が掛かっている場合は、CPU に負荷が掛かっているため、負荷を下げる工夫(映像を切るなど)が必要になります
デコード時間RTCInboundRtpStreamStats.totalDecodeTimeメディアのデコードにどれだけ時間がかかっているかを把握できます。デコードに時間が掛かっている場合は、CPU に負荷が掛かっているため、負荷を下げる工夫(映像を切るなど)が必要になります

より詳しい情報は、こちらを参照してください。

定期的な情報取得と蓄積

ネットワーク状況は刻一刻と変化するのに対して、getStats() API では、API を叩いた時点の統計情報を取得します。 短い間通話不具合が発生したとしても、SkyWay は映像の品質を下げたり、再接続を行うことで通話を復旧させます。そのため、通話状況を適切に測るためには、通話中に複数回品質情報を取得し、一瞬の不具合に惑わされないようにする必要があります。 SkyWay では 5 秒に一度、長くても 30 秒に一度程度品質情報を取得することを推奨しています。

また、多くの顧客は通話中に不具合が発生してもその場で問い合わせを行うわけではなく、通話終了後にサポートに問い合わせるケースが多いため、取得した品質情報をサーバーに蓄積し、通話後に分析できる状態にしておくことも推奨しています。 通話が終了し、サポートが問い合わせを受けタイミングで品質情報を参照できるようにしておくことで、顧客を待たせず、正確なサポートを行うことが可能となります。