クライアントの可観測性 — iOS
OpenTok iOS SDK には、ビデオセッションにおけるリアルタイムのネットワークおよびメディア統計情報にアクセスするための関数が用意されています。これらの関数は、パケットロス、受信データ量、帯域幅などの詳細なストリーム品質指標を報告し、あらゆるパブリッシャーまたはサブスクライブされたストリームで利用できます。
OpenTok Video SDK は、高レベルな統計 API を通じて詳細なストリーム品質メトリクスを提供します。この API はほとんどのユースケースで推奨されており、音声、動画、ネットワーク、および送信者側の統計情報を、ピア接続の切り替え時にも安定した、セッションを意識した統一された形式で提供します。 高度なデバッグを行うために、この SDK では、未処理のピア接続データを反映した生の WebRTC 統計レポートへのアクセスも提供しています。
SDKはまた、パブリッシャーとサブスクライバーの両方に対して、接続の健全性をハイレベルで評価するネットワーク・コンディション・メトリクスを公開します。これらのメトリクスには、ネットワーク・コンディション・スコア、そのスコアの理由、およびサブスクライバについては、観察された問題の原因が接続のどちらにあるかを示すデグラデーション・ソースが含まれます。参照 ネットワークの状態と性能低下 詳細はこちら。
このガイドには、以下のセクションが含まれています:
オーディオ、ビデオ、およびメディアリンクの統計情報API
OpenTokのiOS SDKは、パブリッシャーとサブスクライバーの両方について、音声、動画、およびメディアリンクの統計情報を定期的に送信します。これには、パケット数、ビットレート、フレームレートデータ、一時停止/フリーズのメトリクス、コーデック情報、および帯域幅の推定値やネットワーク状態のスコアといったトランスポートレベルのネットワークメトリクスが含まれます。
統計は以下の方法で配信される:
-
OTPublisherKitNetworkStatsDelegate- パブリッシャー側の統計(オーディオ、ビデオ) -
OTSubscriberKitNetworkStatsDelegate- 加入者側の統計(オーディオ、ビデオ)
それを受け取るには、パブリッシャーかサブスクライバーで適切なデリゲートを有効にしてください。
パブリッシャー向け統計の有効化
OTPublisherKitNetworkStatsDelegate を採用したクラスをアタッチします:
@interface MyViewController () <OTPublisherKitDelegate, OTPublisherKitNetworkStatsDelegate>
@end
OTPublisher *publisher = [[OTPublisher alloc] initWithDelegate:self
settings:settings];
publisher.networkStatsDelegate = self;
コールバックを実装する:
- (void)publisher:(OTPublisherKit *)publisher
videoNetworkStatsUpdated:(NSArray<OTPublisherKitVideoNetworkStats *> *)statsArray {
OTPublisherKitVideoNetworkStats *stats = statsArray.firstObject;
if (!stats) return;
// For routed sessions, the first element is sufficient.
// For relayed sessions, iterate all elements if you want per-subscriber stats.
NSString *connectionId = stats.connectionId ?: @"<none>";
NSString *subscriberId = stats.subscriberId ?: @"<none>";
NSLog(@"Publisher Video Stats for connectionId: %@, subscriberId: %@", connectionId, subscriberId);
NSLog(@"Video bytes sent: %lld", stats.videoBytesSent);
NSLog(@"Video packets sent: %lld", stats.videoPacketsSent);
NSLog(@"Video packets lost: %lld", stats.videoPacketsLost);
NSLog(@"Stats timestamp: %f ms", stats.timestamp);
for (OTPublisherKitVideoLayerStats *layer in stats.videoLayers) {
NSLog(@"Layer: %dx%d", layer.width, layer.height);
NSLog(@" Encoded FPS: %f", layer.encodedFrameRate);
NSLog(@" Bitrate: %lld bps", layer.bitrate);
NSLog(@" Total bitrate (incl. RTP overhead): %lld bps", layer.totalBitrate);
NSLog(@" Codec: %@", layer.codec ?: @"unknown");
NSLog(@" Scalability mode: %@", layer.scalabilityMode ?: @"none");
NSLog(@" Quality limitation: %@", @(layer.qualityLimitationReason));
}
}
- (void)publisher:(OTPublisherKit *)publisher
audioNetworkStatsUpdated:(NSArray<OTPublisherKitAudioNetworkStats *> *)statsArray {
OTPublisherKitAudioNetworkStats *stats = statsArray.firstObject;
if (!stats) return;
// For routed sessions, the first element is sufficient.
// For relayed sessions, iterate all elements if you want per-subscriber stats.
NSString *connectionId = stats.connectionId ?: @"<none>";
NSString *subscriberId = stats.subscriberId ?: @"<none>";
NSLog(@"Publisher Audio Stats for connectionId: %@, subscriberId: %@", connectionId, subscriberId);
NSLog(@"Audio bytes sent: %lld", stats.audioBytesSent);
NSLog(@"Audio packets sent: %lld", stats.audioPacketsSent);
NSLog(@"Audio packets lost: %lld", stats.audioPacketsLost);
NSLog(@"Stats timestamp: %f ms", stats.timestamp);
}
- (void)publisher:(OTPublisherKit *)publisher
mediaLinkStatsUpdated:(NSArray<OTPublisherKitMediaLinkStats*>*)mediaLinkStats {
if (mediaLinkStats.count == 0) return;
OTPublisherKitMediaLinkStats *stats = mediaLinkStats.firstObject;
NSLog(@"Publisher uplink bandwidth: %lld bps", stats.transport.connectionEstimatedBandwidth);
NSLog(@"Network condition: %ld", (long)stats.transport.networkCondition);
NSLog(@"Condition reason: %ld", (long)stats.transport.networkConditionReason);
}
ルーティングされたセッション( ビデオ・メディア・ルーター, stats 配列には 1 つのオブジェクトが含まれており、Vonage Video Media Router に送信される 単一のオーディオまたはビデオメディアストリームの統計情報を定義しています。 中継セッションでは、stats 配列には、公開されたストリームの各加入者ごとに 1 つのオブジェクトが含まれます。
パブリッシャーでビデオ画質のイベントを受信する
ビデオ画質のイベントにも興味がある場合は、このコールバックを実装してください:
- (void)publisher:(OTPublisherKit *)publisher
videoQualityChanged:(OTPublisherKitVideoNetworkStats *)stats
reason:(OTPublisherVideoEventReason)reason {
NSLog(@"Publisher video quality event: %ld", (long)reason);
}
パブリッシャーでのネットワーク状態イベントの受信
パブリッシャーのネットワーク状態変更イベントを受け取るには publisher:networkConditionChanged:mediaLinkStats:reason: コールバック:
- (void)publisher:(OTPublisherKit *)publisher
networkConditionChanged:(OTPublisherKitMediaLinkStats *)mediaLinkStats
reason:(OTNetworkReason)reason {
NSLog(@"Publisher network condition changed: %ld", (long)mediaLinkStats.transport.networkCondition);
NSLog(@"Reason: %ld", (long)mediaLinkStats.transport.networkConditionReason);
}
このコールバックは、パブリッシャーに対するネットワーク状態の重大な変化が 検出されたときにトリガーされる。このコールバックには、トランスポートメトリックを含む現在のメディアリンク統計が含まれます。参照 ネットワークの状態と劣化の原因 ネットワーク・コンディション・スコアの解釈とその理由の詳細については、こちらをご覧ください。
加入者統計の有効化
を採用するクラスを付ける。 OTSubscriberKitNetworkStatsDelegate:
@interface MyViewController () <OTSubscriberKitDelegate, OTSubscriberKitNetworkStatsDelegate>
@end
OTSubscriber *subscriber = [[OTSubscriber alloc] initWithStream:stream
delegate:self];
subscriber.networkStatsDelegate = self;
[session subscribe:subscriber error:nil];
コールバックを実装する:
- (void)subscriber:(OTSubscriberKit *)subscriber
videoNetworkStatsUpdated:(OTSubscriberKitVideoNetworkStats *)stats {
NSLog(@"Video bytes received: %llu", stats.videoBytesReceived);
}
- (void)subscriber:(OTSubscriberKit *)subscriber
audioNetworkStatsUpdated:(OTSubscriberKitAudioNetworkStats *)stats {
NSLog(@"Audio packets received: %llu", stats.audioPacketsReceived);
}
- (void)subscriber:(OTSubscriberKit *)subscriber
mediaLinkStatsUpdated:(OTSubscriberKitMediaLinkStats *)mediaLinkStats {
NSLog(@"Local downlink bandwidth: %lld bps", mediaLinkStats.transport.connectionEstimatedBandwidth);
NSLog(@"Remote publisher uplink bandwidth: %lld bps", mediaLinkStats.remotePublisherTransport.connectionEstimatedBandwidth);
NSLog(@"Degradation source: %ld", (long)mediaLinkStats.networkDegradationSource);
}
加入者のビデオ品質イベントの受信
さらに、加入者のビデオ品質が変更されたイベントを処理する:
- (void)subscriber:(OTSubscriberKit *)subscriber
videoQualityChanged:(OTSubscriberKitVideoNetworkStats *)stats
reason:(OTSubscriberVideoEventReason)reason {
NSLog(@"Subscriber video quality event: %ld", (long)reason);
}
加入者側でのネットワーク状態イベントの受信
サブスクライバのネットワーク条件変更イベントを受信するには subscriber:networkConditionChanged:mediaLinkStats:reason: コールバック:
- (void)subscriber:(OTSubscriberKit *)subscriber
networkConditionChanged:(OTSubscriberKitMediaLinkStats *)mediaLinkStats
reason:(OTNetworkReason)reason {
NSLog(@"Local network condition: %ld", (long)mediaLinkStats.transport.networkCondition);
NSLog(@"Remote publisher network condition: %ld", (long)mediaLinkStats.remotePublisherTransport.networkCondition);
NSLog(@"Degradation source: %ld", (long)mediaLinkStats.networkDegradationSource);
}
このコールバックは、サブスクライバーまたはリモートパブリッシャーのネッ トワーク状態の重大な変化が検知されたときにトリガーされる。このコールバックは、ローカルおよびリモートのトランスポートメトリッ クと劣化ソースを含む、現在のメディアリンクの統計情報を含む。参照 ネットワークの状態と劣化の原因 ネットワーク・コンディション・スコアの解釈とその理由の詳細については、こちらをご覧ください。
統計データ構造
このセクションでは、iOS オーディオ/ビデオ統計 API が提供する構造体とプロパティの概要を説明します。すべての Video SDK プラットフォームが同じ統計情報セットを公開していますが、各プラットフォームで個々のフィールドの構造や名前の付け方に若干の違いがある場合があります。これらの違いは、基本的なメトリクスの違いではなく、プラットフォーム固有の SDK 設計規約を反映しています。
利用可能な統計とそれが表すものについてのプラットフォームに依存しない説明については、以下を参照のこと。 顧客の観測可能性の概要.
OTTransportStats
共有トランスポート・レベルのメトリクスを表します。
connectionEstimatedBandwidth- 利用可能な接続帯域幅の推定値(bps)。networkCondition- 現在のネットワーク・コンディション・スコアOTNetworkConditionUnknown,OTNetworkConditionCritical,OTNetworkConditionWarning,OTNetworkConditionFair,OTNetworkConditionGoodあるいはOTNetworkConditionExcellent).networkConditionReason- ネットワーク状況に影響を与える主な理由OTNetworkReasonNone,OTNetworkReasonUnknown,OTNetworkReasonBandwidth,OTNetworkReasonPacketLossあるいはOTNetworkReasonNetworkConditionChange).
OTPublisherKitVideoNetworkStats
パブリッシャーのビデオトラックに関する統計を提供します。これには以下が含まれます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。videoPacketsLost- 失われたビデオパケットの推定値。videoPacketsSent- ビデオパケットの送信。videoBytesSent- ビデオバイトが送信された。timestamp- 統計情報が収集されたミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。videoLayers- ビデオレイヤーの統計情報の配列 (OTPublisherKitVideoLayerStats).
OTPublisherKitAudioNetworkStats
パブリッシャーのオーディオトラックに関する統計を提供します。以下を含みます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。audioPacketsLost- 失われたパケットの推定値。audioPacketsSent- オーディオパケットを送信。audioBytesSent- 送信されたオーディオ・バイト。timestamp- ミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。
OTPublisherKitVideoLayerStats
1つのサイマルキャスト・レイヤーまたはSVCレイヤーを表す。
width- エンコードされたフレーム幅。height- エンコードされたフレームの高さ。encodedFrameRate- エンコードされた1秒あたりのフレーム数。bitrate- レイヤーのビットレート(bps)。totalBitrate- RTPオーバーヘッドを含むレイヤービットレート(bps)。scalabilityMode- SVC/スケーラビリティ記述子(例えば "L3T3")。qualityLimitationReason- 品質制限の理由(帯域幅、CPU、コーデック、解像度、レイヤーの変更)。codec- このビデオレイヤーが使用するコーデック。
OTSenderStats
送信側の推定メトリクス(オーディオとビデオの両方に反映される)。
connectionMaxAllocatedBitrate- 送信側接続で推定される最大ビットレート。connectionEstimatedBandwidth- 現在の推定帯域幅(bps)。
OTSubscriberKitVideoNetworkStats
加入者のビデオトラックに関する統計情報を提供します。これには以下が含まれます:
videoPacketsLost- 失われたビデオパケットの推定値。videoPacketsReceived- ビデオパケットを受信。videoBytesReceived- 受信したビデオバイト。timestamp- 統計情報が収集されたミリ秒単位のUnixタイムスタンプ。senderStats- 送信側のメトリクス(オプション)。width- デコードされたフレーム幅(ピクセル)。height- デコードされたフレームの高さ(ピクセル)。decodedFrameRate- デコードされたフレーム/秒。bitrate- ビデオ・ビットレート(bps)。totalBitrate- RTPオーバーヘッドを含むビットレート(bps)。pauseCount- ポーズ(最後のフレームから5秒以上)の数。意図的な無効化とオーディオフォールバックの場合を含む。totalPausesDuration- 全休止時間(ms)。freezeCount- フリーズカウント(WebRTC定義のフリーズイベント)。totalFreezesDuration- 合計フリーズ時間(ms)。codec- 現在のデコーダーコーデック。
OTSubscriberKitAudioNetworkStats
加入者のオーディオトラックに関する統計情報を提供します。これには以下が含まれます:
audioPacketsLost- 失われたパケットの推定値。audioPacketsReceived- パケットを受信した。audioBytesReceived- 受信したバイト数。timestamp- ミリ秒単位のUnixタイムスタンプ。senderStats- 送信側のメトリクス(オプション)。
OTPublisherKitMediaLinkStats
パブリッシャー接続のトランスポートレベルの統計情報を提供します。
transport- この出版社の輸送統計OTTransportStats)
OTSubscriberKitMediaLinkStats
リモートパブリッシャーのネットワークパフォーマンスの可視性を含む、サブスクライバーの接続のトランスポートレベルの統計情報を提供します。これにより、アプリケーションは、接続の問題が加入者のダウンリンクに起因するのか、パブリッシャーのアップリンクに起因するのかを診断できます。
transport- この加入者のダウンリンク接続のトランスポート統計(以下を参照。OTTransportStats)remotePublisherTransport– リモートパブリッシャーのアップリンク接続に関する転送統計(参照:OTTransportStats).送信側統計が有効でない場合、制限されることがある。networkDegradationSource- ネットワーク劣化の原因があればそれを示す (OTNetworkDegradationSourceNone,OTNetworkDegradationSourceLocal,OTNetworkDegradationSourceRemoteあるいはOTNetworkDegradationSourceBothOrUnclear)
送信側統計
参照 送信側統計の概要.
送信側統計の有効化
送信者側の統計情報は、購読者が受け取る。送信者側の統計を受け取るには、ストリームのパブリッシャーで senderStatsTrack プロパティ true のために OTPublisherKitSettings オブジェクトはパブリッシャーの作成に使われました。
OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.senderStatsTrack = YES;
OTPublisher *publisher = [[OTPublisher alloc] initWithDelegate:self
settings:settings];
もし senderStatsTrack が有効でない場合、このパブリッシャーに対して送信者統計チャンネルは発行されません。デフォルト値は NO.
送信者側の統計情報の受信
パブリッシャーが送信者側の統計情報を有効にしていれば、購読者は自動的に OTSubscriberKitNetworkStatsDelegate コールバック 前述.その senderStats の両方のプロパティを持つ。 OTSubscriberKitVideoNetworkStats そして OTSubscriberKitAudioNetworkStats は2つの指標を提供する:
connectionMaxAllocatedBitrate- 接続時に推定可能な最大ビットレートconnectionEstimatedBandwidth- 接続の現在の推定帯域幅
これらのメトリクスは、オーディオとビデオのバンドルごとに計算されるため、ビデオとオーディオの両方の統計に同じ値が表示されます。
- (void)subscriber:(OTSubscriberKit *)subscriber
videoNetworkStatsUpdated:(OTSubscriberKitVideoNetworkStats *)stats
{
if (stats.senderStats) {
OTSenderStats *sender = stats.senderStats;
NSLog(@"Connection max allocated bitrate: %lld bps", (long long)sender.connectionMaxAllocatedBitrate);
NSLog(@"Connection current estimated bandwidth: %lld bps", (long long)sender.connectionEstimatedBandwidth);
}
}
ネットワークの状態と劣化の原因
SDKは、パブリッシャーとサブスクライバーの両方に対して、コンディションのスコア、そのスコアを駆動する理由、サブスクライバーの劣化ソースを含むリアルタイムのネットワーク・コンディション・メトリクスを提供します。ネットワーク・コンディション・モデル、スコア、理由、およびそれを有効にする方法の詳細については 顧客の観測可能性の概要.
ネットワーク・コンディション・データは2つのチャンネルから入手できる:
- 定期的な統計: メディアリンク統計イベントには、以下のトランスポートメトリクスが含まれます。
networkConditionそしてnetworkConditionReason.購読者向けには、メディアリンクの統計も含まれる。remotePublisherTransportそしてnetworkDegradationSource. - ネットワーク状態の変更イベント: パブリッシャーとサブスクライバーの両方で、ネットワーク状態の重大な変化が検知 されたときに、専用のコールバックがトリガーされる。
以下の例では、加入者ネットワークの状態データを使用して、劣化の原因を特定する方法を示しています:
- (void)subscriber:(OTSubscriberKit *)subscriber
networkConditionChanged:(OTSubscriberKitMediaLinkStats *)mediaLinkStats
reason:(OTNetworkReason)reason {
OTNetworkCondition localCondition = mediaLinkStats.transport.networkCondition;
OTNetworkCondition remoteCondition = mediaLinkStats.remotePublisherTransport.networkCondition;
OTNetworkDegradationSource source = mediaLinkStats.networkDegradationSource;
if (source == OTNetworkDegradationSourceLocal) {
NSLog(@"Local network is degraded (condition: %ld)", (long)localCondition);
} else if (source == OTNetworkDegradationSourceRemote) {
NSLog(@"Remote publisher network is degraded (condition: %ld)", (long)remoteCondition);
} else if (source == OTNetworkDegradationSourceBothOrUnclear) {
NSLog(@"Degradation source unclear — local: %ld, remote: %ld", (long)localCondition, (long)remoteCondition);
}
}
RTC統計レポート
パブリッシャーの低レベルのピア接続統計情報を取得するには、 OTPublisherKit getRtcStatsReport: メソッド。これにより、 メディアストリームのRTC統計レポートが提供されます。これは非同期操作です。 次の設定を行います。 OTPublisherKit rtcStatsReportDelegate プロパティを定義し、 OTPublisherKitRtcStatsReportDelegate publisher:rtcStatsReport: メソッド [OTPublisherKit getRtcStatsReport:] を呼び出す前に。統計情報が利用可能になると、 の OTPublisherKitRtcStatsReportDelegate publisher:rtcStatsReport: メッセージが送信されます。このメッセージには、 OTPublisherRtcStats オブジェクトには、jsonArrayOfReports プロパティが含まれています。これは、 RTC 統計レポートの JSON 配列であり、 Web ブラウザで実装されている RtcStatsReport オブジェクトの形式と類似しています(参照: Mozillaのドキュメント. こちらも参照 このW3Cドキュメント.
加入者の低レベルのピア接続統計情報を取得するには、次のコマンドを使用します。 OTSubscriberKit getRtcStatsReport: メソッド。これにより、 メディアストリームのRTC統計レポートが提供されます。これは非同期操作です。 次の設定を行います。 OTSubscriberKit rtcStatsReportDelegate プロパティを定義し、 OTSubscriberKitRtcStatsReportDelegate subscriber:rtcStatsReport: メソッド [OTSubscriberKit getRtcStatsReport:] を呼び出す前に。統計情報が利用可能になると、 の OTSubscriberKitRtcStatsReportDelegate subscriber:rtcStatsReport: メッセージが送信されます。このメッセージには、jsonArrayOfReports パラメータが含まれています。
サンプルアプリ
について vonage-video-ios-sdk-samples-swift 送信側統計サンプル iOS Client SDKを使用して構築されたモバイルアプリにおいて、送信者側の統計情報を利用します。