通信状態の統計的分析
getStats
API は試験的に提供していましたが、非推奨となりました。通信状態の統計的分析にはAnalyticsをご利用ください。
SkyWay の getStats()
API について
getStats()
API を利用することで、API を呼び出した時点での、WebRTC 通信の統計情報を取得できます。
JavaScript SDK の getStats()
API について
getStats()
API の返り値は、 WebRTCStats
オブジェクトです。API の詳細は 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
派生オブジェクトは以下の通り紐付きます。
RTCStatsType | RTCStats 派生オブジェクト |
---|---|
codec | RTCCodecStats |
inbound-rtp | RTCInboundRtpStreamStats |
outbound-rtp | RTCOutboundRtpStreamStats |
remote-inbound-rtp | RTCRemoteInboundRtpStreamStats |
remote-outbound-rtp | RTCRemoteOutboundRtpStreamStats. |
media-source | RTCAudioSourceStats or RTCVideoSourceStats |
media-playout | RTCAudioPlayoutStats |
peer-connection | RTCPeerConnectionStats |
data-channel | RTCDataChannelStats |
stream | RTCMediaStreamStats |
track | RTCMediaStreamTrackStats |
transport | RTCTransportStats |
candidate-pair | RTCIceCandidatePairStats |
local-candidate | RTCIceCandidateStats |
remote-candidate | RTCIceCandidateStats |
certificate | RTCCertificateStats |
*) 仕様で定義されている物が全てブラウザで実装されているわけではないので、注意が必要です。
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 について
- 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 について
- 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 秒に一度程度品質情報を取得することを推奨しています。
また、多くの顧客は通話中に不具合が発生してもその場で問い合わせを行うわけではなく、通話終了後にサポートに問い合わせるケースが多いため、取得した品質情報をサーバーに蓄積し、通話後に分析できる状態にしておくことも推奨しています。 通話が終了し、サポートが問い合わせを受けタイミングで品質情報を参照できるようにしておくことで、顧客を待たせず、正確なサポートを行うことが可能となります。