クライアントの観測可能性:アンドロイド
Vonage Video SDKは、ほとんどのユースケースで推奨される高レベルの統計APIを通じて、詳細なストリーム品質メトリクスを公開します。このAPIは、音声、ビデオ、ネットワーク、および送信者側の統計を、ピア接続の遷移をまたいで安定したまま、統一されたセッション認識形式で提供します。高度なデバッグのために、SDKは未処理のピア接続データを反映する生のWebRTC統計レポートへのアクセスも提供します。
音声・ビデオ統計API
Vonage Video Android SDKは、パブリッシャーとサブスクライバーの両方に対して、オーディオとビデオのネットワーク統計を定期的に送信します。これらには、パケット数、ビットレート、フレームレートデータ、一時停止/フリーズメトリクス、コーデック情報、およびオプションの送信側ネットワーク推定が含まれます。
統計は以下の方法で配信される:
PublisherKit.NetworkStatsListener- パブリッシャー側の統計SubscriberKit.NetworkStatsListener- 加入者側の統計
それを受信するには、パブリッシャーまたはサブスクライバーで適切なリスナーを 有効にしてください。
パブリッシャー向け統計の有効化
パブリッシャー統計用のリスナーを添付する:
publisher.setNetworkStatsListener(new PublisherKit.NetworkStatsListener() {
@Override
public void onVideoStats(PublisherKit publisher, PublisherKit.PublisherVideoStats[] statsArray) {
if (statsArray != null && statsArray.length > 0) {
// For routed sessions, first element is sufficient.
// For relayed sessions, iterate all statsArray elements to get per-subscriber info.
PublisherKit.PublisherVideoStats stats = statsArray[0];
String connectionId = (stats.connectionId != null && !stats.connectionId.isEmpty())
? stats.connectionId
: "<none>";
String subscriberId = (stats.subscriberId != null && !stats.subscriberId.isEmpty())
? stats.subscriberId
: "<none>";
Log.d("VideoStats", "Publisher Video Stats for connectionId: " + connectionId
+ ", subscriberId: " + subscriberId);
Log.d("VideoStats", "Video bytes sent: " + stats.videoBytesSent);
Log.d("VideoStats", "Video packets sent: " + stats.videoPacketsSent);
Log.d("VideoStats", "Video packets lost: " + stats.videoPacketsLost);
Log.d("VideoStats", "Stats timestamp: " + stats.timeStamp + " ms");
if (stats.videoLayers != null) {
for (PublisherKit.VideoLayerStats layer : stats.videoLayers) {
Log.d("VideoStats", "Layer: " + layer.width + "x" + layer.height);
Log.d("VideoStats", " Encoded FPS: " + layer.encodedFrameRate);
Log.d("VideoStats", " Bitrate: " + layer.bitrate + " bps");
Log.d("VideoStats", " Total bitrate (incl. RTP overhead): " + layer.totalBitrate + " bps");
Log.d("VideoStats", " Codec: " + (layer.codec != null ? layer.codec : "unknown"));
Log.d("VideoStats", " Scalability mode: " + (layer.scalabilityMode != null ? layer.scalabilityMode : "none"));
Log.d("VideoStats", " Quality limitation: " + layer.qualityLimitationReason);
}
}
if (stats.transport != null) {
Log.d("VideoStats", "Estimated uplink bandwidth: " + stats.transport.getConnectionEstimatedBandwidth() + " bps");
}
}
}
@Override
public void onAudioStats(PublisherKit publisher, PublisherKit.PublisherAudioStats[] statsArray) {
if (statsArray != null && statsArray.length > 0) {
// For routed sessions, first element is sufficient.
// For relayed sessions, iterate all statsArray elements to get per-subscriber info.
PublisherKit.PublisherAudioStats stats = statsArray[0];
String connectionId = (stats.connectionId != null && !stats.connectionId.isEmpty())
? stats.connectionId
: "<none>";
String subscriberId = (stats.subscriberId != null && !stats.subscriberId.isEmpty())
? stats.subscriberId
: "<none>";
Log.d("AudioStats", "Publisher Audio Stats for connectionId: " + connectionId
+ ", subscriberId: " + subscriberId);
Log.d("AudioStats", "Audio bytes sent: " + stats.audioBytesSent);
Log.d("AudioStats", "Audio packets sent: " + stats.audioPacketsSent);
Log.d("AudioStats", "Audio packets lost: " + stats.audioPacketsLost);
Log.d("AudioStats", "Stats timestamp: " + stats.timeStamp + " ms");
if (stats.transport != null) {
Log.d("AudioStats", "Estimated uplink bandwidth: " + stats.transport.getConnectionEstimatedBandwidth() + " bps");
}
}
}
});
ルーティングされたセッション( ビデオ・メディア・ルーター), の統計情報を定義する1つのオブジェクトが含まれます。 の統計情報を定義します。 中継セッションの場合、stats 配列には公開ストリームの加入者ごとのオブジェクトが含まれます。 オブジェクトが含まれます。
パブリッシャーでのビデオ品質イベントの受信
ビデオ画質のイベントの場合は、実施する:
@Override
public void onPublisherVideoQualityChanged(PublisherKit.PublisherVideoStats stats, String reason) {
Log.d("Stats", "Publisher video quality event: " + reason);
}
購読者の統計を有効にする
を実装したリスナーをアタッチする。 SubscriberKit.SubscriberKitNetworkStatsListener:
Subscriber subscriber = new Subscriber(stream);
subscriber.setNetworkStatsListener(new SubscriberKit.SubscriberKitNetworkStatsListener() {
@Override
public void onSubscriberVideoStatsUpdated(SubscriberKit.SubscriberVideoStats stats) {
Log.d("Stats", "Video bytes received: " + stats.videoBytesReceived);
}
@Override
public void onSubscriberAudioStatsUpdated(SubscriberKit.SubscriberAudioStats stats) {
Log.d("Stats", "Audio packets received: " + stats.audioPacketsReceived);
}
});
加入者のビデオ品質イベントの受信
ビデオ画質のイベントの場合は、実施する:
@Override
public void onSubscriberVideoQualityChanged(SubscriberKit.SubscriberVideoStats stats, String reason) {
Log.d("Stats", "Subscriber video quality event: " + reason);
}
統計データ構造
このセクションでは、Android のオーディオおよびビデオ統計 API が提供する構造体とプロパティの概要を説明します。すべての Video SDK プラットフォームが同じ統計情報セットを公開していますが、各プラットフォームで個々のフィールドの構造や名前の付け方に若干の違いがある場合があります。これらの違いは、基本的なメトリクスの違いではなく、プラットフォーム固有の SDK 設計規約を反映しています。
利用可能な統計とそれが表すものについてのプラットフォームに依存しない説明については、以下を参照のこと。 顧客の観測可能性の概要.
TransportStats
共有トランスポートレベルの推定を表す。
connectionEstimatedBandwidth- 推定利用可能アップリンク接続帯域幅(bps)。
PublisherKit.PublisherVideoStats
パブリッシャーのビデオトラックに関する統計を提供します。これには以下が含まれます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。videoPacketsLost- 失われたビデオパケットの推定値。videoPacketsSent- ビデオパケットの送信。videoBytesSent- ビデオバイトが送信された。timeStamp- 統計情報が収集されたミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。videoLayers- ビデオレイヤーの統計情報の配列 (OTPublisherKitVideoLayerStats).transport- 運輸統計
PublisherKit.PublisherAudioStats
パブリッシャーのオーディオトラックに関する統計を提供します。以下を含みます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。audioPacketsLost- 失われたパケットの推定値。audioPacketsSent- オーディオパケットを送信。audioBytesSent- 送信されたオーディオ・バイト。timeStamp- ミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。transport- 運輸統計
PublisherKit.VideoLayerStats
1つのサイマルキャスト・レイヤーまたはSVCレイヤーを表す。
width- エンコードされたフレーム幅。height- エンコードされたフレームの高さ。encodedFrameRate- エンコードされた1秒あたりのフレーム数。bitrate- レイヤーのビットレート(bps)。totalBitrate- RTPオーバーヘッドを含むレイヤービットレート(bps)。scalabilityMode- SVC/スケーラビリティ記述子(例えば "L3T3")。qualityLimitationReason- 品質制限の理由(帯域幅、CPU、コーデック、解像度、レイヤーの変更)。codec- このビデオレイヤーが使用するコーデック。
SubscriberKit.SenderStats
送信側の推定メトリクス(オーディオとビデオの両方に反映される)。
connectionMaxAllocatedBitrate- 送信側接続で推定される最大ビットレート。connectionEstimatedBandwidth- 現在の推定帯域幅(bps)。
SubscriberKit.SubscriberVideoStats
加入者のビデオトラックに関する統計情報を提供します。これには以下が含まれます:
videoPacketsLost- 失われたビデオパケットの推定値。videoPacketsReceived- ビデオパケットを受信。videoBytesReceived- 受信したビデオバイト。timeStamp- 統計情報が収集されたミリ秒単位のUnixタイムスタンプ。senderStats- 送信側のメトリクス(オプション)。width- デコードされたフレーム幅(ピクセル)。height- デコードされたフレームの高さ(ピクセル)。decodedFrameRate- デコードされたフレーム/秒。bitrate- ビデオ・ビットレート(bps)。totalBitrate- RTPオーバーヘッドを含むビットレート(bps)。pauseCount- ポーズ(最後のフレームから5秒以上)の数。意図的な無効化とオーディオフォールバックの場合を含む。totalPausesDuration- 全休止時間(ms)。freezeCount- フリーズカウント(WebRTC定義のフリーズイベント)。totalFreezesDuration- 合計フリーズ時間(ms)。codec- 現在のデコーダーコーデック。
SubscriberKit.SubscriberAudioStats
加入者のオーディオトラックに関する統計情報を提供します。これには以下が含まれます:
audioPacketsLost- 失われたパケットの推定値。audioPacketsReceived- パケットを受信した。audioBytesReceived- 受信したバイト数。timeStamp- ミリ秒単位のUnixタイムスタンプ。senderStats- 送信側のメトリクス(オプション)。
送信側統計
参照 送信側統計の概要.
送信側統計の有効化
送信者側の統計情報は、購読者が受け取る。送信者側の統計を受け取るには、ストリームのパブリッシャーで senderStatisticsTrack プロパティ true パブリッシャーを構築する際に
Publisher publisher = new Publisher.Builder(context)
.senderStatsTrack(true) // Enable sender-side stats
.build();
もし senderStatsTrack が有効でない場合、このパブリッシャーに対して送信者統計チャンネルは発行されません。デフォルト値は false.
送信側統計の購読
サブスクライバーが自動的に送信者統計を受け取るのは、パブリッシャーが送信者統計 を有効にしていて、サブスクライバーがネットワーク統計イベントのリスナーを登録している 場合だけである。
統計イベントの受信
送信側の統計は SubscriberKit.VideoStatsListener そして SubscriberKit.AudioStatsListener ビデオとオーディオのコールバック。その SubscriberKit.SubscriberVideoStats そして SubscriberKit.SubscriberAudioStats クラスはそれぞれこれらのプロパティを含んでいる:
connectionMaxAllocatedBitrate- 接続時に推定可能な最大ビットレートconnectionEstimatedBandwidth- 現在の推定ビットレート
これらの2つのメトリクスは、オーディオ・ビデオ・バンドルごとに計算されるため、ビデオとオーディオの両方の統計に同じ値が表示されます。個々のトラックではなくトランスポートを反映するため、メトリクスはオーディオとビデオの両方で共有されます。
について stats オブジェクトには、オプションの senderStats フィールドは、送信者側の統計情報を提供する。例えば SubscriberKit.setVideoStatsListener()その stats パラメータは SubscriberKit.SubscriberVideoStats オブジェクトがある:
subscriber.setVideoStatsListener((subscriber, stats) -> {
if (stats.senderStats != null) {
Log.d(TAG, "Connection max allocated bitrate: " + stats.senderStats.connectionMaxAllocatedBitrate);
Log.d(TAG, "Connection current estimated bandwidth: " + stats.senderStats.connectionEstimatedBandwidth);
} else {
Log.d(TAG, "Sender stats not available yet.");
}
});
を使ったオーディオ統計も同様です。 SubscriberKit.AudioStatsListener.
RTC統計レポート
パブリッシャーの低レベルのピア接続統計を取得するには PublisherKit.getRtcStatsReport() メソッドを使用します。これはメディアストリームのRTC統計レポートを提供する。これは非同期操作である。これは非同期操作である。 PublisherKit.setRtcStatsReportListener(PublisherKit.PublisherRtcStatsReportListener listener) メソッドを実装し PublisherKit.PublisherRtcStatsReportListener.onRtcStatsReport(PublisherKit publisher, PublisherKit.PublisherRtcStats[] stats) メソッドを呼び出す前に PublisherKit.getRtcStatsReport().
統計が利用可能な場合、実装の PublisherKit.PublisherRtcStatsReportListener.onRtcStatsReport(PublisherKit publisher, PublisherKit.PublisherRtcStats[] stats) メソッドが呼び出される。
の配列。 PublisherRtcStats オブジェクトがそのメソッドに渡される。その PublisherRtcStats オブジェクトには jsonArrayOfReports プロパティを使用します。これはRTC統計レポートのJSON配列で、ウェブ・ブラウザで実装されているRtcStatsReportオブジェクトのフォーマットに似ている( Mozillaのドキュメント).
サブスクライバの低レベルのピア接続統計を取得するには SubscriberKit.getRtcStatsReport() メソッドを使用します。これはメディアストリームのRTC統計レポートを提供する。
これは非同期操作である。これは非同期操作である。 SubscriberKit.setRtcStatsReportListener(SubscriberKit.SubscriberRtcStatsReportListener listener) メソッドを実装し SubscriberKit.SubscriberRtcStatsReportListener.onRtcStatsReport(SubscriberKit subscriber, java.lang.String jsonArrayOfReports) メソッドを呼び出す前に SubscriberKit.getRtcStatsReport().
統計が利用可能な場合、実装の SubscriberKit.SubscriberRtcStatsReportListener.onRtcStatsReport(SubscriberKit subscriber, java.lang.String jsonArrayOfReports) メソッドが呼び出される。この jsonArrayOfReports これは、ウェブブラウザで実装されているRtcStatsReportオブジェクトのフォーマットに似ています。 Mozillaのドキュメント).
こちらも参照 このW3Cドキュメント.