クライアントの観測可能性:iOS(Swift)
Vonage Video SDKは、ほとんどのユースケースで推奨される高レベルの統計APIを通じて、詳細なストリーム品質メトリクスを公開します。このAPIは、音声、ビデオ、ネットワーク、および送信者側の統計を、ピア接続の遷移をまたいで安定したまま、統一されたセッション認識形式で提供します。高度なデバッグのために、SDKは未処理のピア接続データを反映する生のWebRTC統計レポートへのアクセスも提供します。
音声・ビデオ統計API
Vonage Video iOS SDKは、パブリッシャーとサブスクライバーの両方に対して、オーディオとビデオのネットワーク統計を定期的に送信します。これらには、パケット数、ビットレート、フレームレートデータ、一時停止/フリーズメトリクス、コーデック情報、およびオプションの送信側ネットワーク推定が含まれます。
統計は以下の方法で配信される:
OTPublisherKitNetworkStatsDelegate- パブリッシャー側の統計OTSubscriberKitNetworkStatsDelegate- 加入者側の統計
それを受け取るには、パブリッシャーかサブスクライバーで適切なデリゲートを有効にしてください。
パブリッシャー向け統計の有効化
OTPublisherKitNetworkStatsDelegate を採用したクラスをアタッチします:
class MyViewController: UIViewController, OTPublisherKitDelegate, OTPublisherKitNetworkStatsDelegate {
var publisher: OTPublisher?
func setupPublisher() {
let settings = OTPublisherSettings()
// Configure settings as needed
publisher = OTPublisher(delegate: self, settings: settings)
publisher?.networkStatsDelegate = self
}
}
コールバックを実装する:
func publisher(_ publisher: OTPublisherKit, videoNetworkStatsUpdated stats: [OTPublisherKitVideoNetworkStats]) {
let first = stats.first
// For routed sessions, stats.first is enough.
// For relayed sessions (one object per subscriber), you would iterate all elements.
let connectionId = first.connectionId.isEmpty ? "<none>" : first.connectionId
let subscriberId = first.subscriberId.isEmpty ? "<none>" : first.subscriberId
print("Publisher Video Stats for connectionId: \(connectionId), subscriberId: \(subscriberId)")
print("Video bytes sent: \(first.videoBytesSent)")
print("Video packets sent: \(first.videoPacketsSent)")
print("Video packets lost: \(first.videoPacketsLost)")
print("Current average frame rate: \(first.videoFrameRate) fps")
for layer in first.videoLayers {
print("Layer: \(layer.width)x\(layer.height)")
print(" Encoded FPS: \(layer.encodedFrameRate)")
print(" Bitrate: \(layer.bitrate) bps")
print(" Total bitrate (incl. RTP overhead): \(layer.totalBitrate) bps")
print(" Codec: \(layer.codec ?? "<none>")")
print(" Scalability mode: \(layer.scalabilityMode ?? "<none>")")
print(" Quality limitation: \(layer.qualityLimitationReason.rawValue)")
}
if let transport = first.transport {
print("Estimated uplink bandwidth: \(transport.connectionEstimatedBandwidth) bps")
}
}
func publisher(_ publisher: OTPublisherKit, audioNetworkStatsUpdated stats: [OTPublisherKitAudioNetworkStats]) {
let first = stats.first
// For routed sessions, stats.first is enough.
// For relayed sessions (one object per subscriber), you would iterate all elements.
let connectionId = first.connectionId.isEmpty ? "<none>" : first.connectionId
let subscriberId = first.subscriberId.isEmpty ? "<none>" : first.subscriberId
print("Publisher Audio Stats for connectionId: \(connectionId), subscriberId: \(subscriberId)")
print("Audio bytes sent: \(first.audioBytesSent)")
print("Audio packets sent: \(first.audioPacketsSent)")
print("Audio packets lost: \(first.audioPacketsLost)")
if let transport = first.transport {
print("Estimated uplink bandwidth: \(transport.connectionEstimatedBandwidth) bps")
}
}
ルーティングされたセッション( ビデオ・メディア・ルーター), の統計情報を定義する1つのオブジェクトが含まれます。 の統計情報を定義します。 中継セッションの場合、stats 配列には公開ストリームの加入者ごとのオブジェクトが含まれます。 オブジェクトが含まれます。
パブリッシャーでのビデオ品質イベントの受信
ビデオ画質のイベントにも興味がある場合は、このコールバックを実装してください:
func publisher(_ publisher: OTPublisherKit, videoQualityChanged stats: OTPublisherKitVideoNetworkStats, reason: OTPublisherVideoEventReason) {
print("Publisher video quality event: \(reason.rawValue)")
}
購読者の統計を有効にする
を採用するクラスを付ける。 OTSubscriberKitNetworkStatsDelegate:
class MyViewController: UIViewController, OTSubscriberKitDelegate, OTSubscriberKitNetworkStatsDelegate {
var subscriber: OTSubscriber?
func setupSubscriber(stream: OTStream, session: OTSession) {
subscriber = OTSubscriber(stream: stream, delegate: self)
subscriber?.networkStatsDelegate = self
try? session.subscribe(subscriber!)
}
}
コールバックを実装する:
func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {
print("Video bytes received: \(stats.videoBytesReceived)")
}
func subscriber(_ subscriber: OTSubscriberKit, audioNetworkStatsUpdated stats: OTSubscriberKitAudioNetworkStats) {
print("Audio packets received: \(stats.audioPacketsReceived)")
}
加入者のビデオ品質イベントの受信
さらに、加入者のビデオ品質が変更されたイベントを処理する:
func subscriber(_ subscriber: OTSubscriberKit, videoQualityChanged stats: OTSubscriberKitVideoNetworkStats, reason: OTSubscriberVideoEventReason) {
print("Subscriber video quality event: \(reason.rawValue)")
}
統計データ構造
このセクションでは、iOS オーディオ/ビデオ統計 API が提供する構造体とプロパティの概要を説明します。すべての Video SDK プラットフォームが同じ統計情報セットを公開していますが、各プラットフォームで個々のフィールドの構造や名前の付け方に若干の違いがある場合があります。これらの違いは、基本的なメトリクスの違いではなく、プラットフォーム固有の SDK の設計規約を反映しています。
利用可能な統計とそれが表すものについてのプラットフォームに依存しない説明については、以下を参照のこと。 顧客の観測可能性の概要.
OTTransportStats
共有トランスポートレベルの推定を表す。
connectionEstimatedBandwidth- 推定利用可能アップリンク接続帯域幅(bps)。
OTPublisherKitVideoNetworkStats
パブリッシャーのビデオトラックに関する統計を提供します。これには以下が含まれます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。videoPacketsLost- 失われたビデオパケットの推定値。videoPacketsSent- ビデオパケットの送信。videoBytesSent- ビデオバイトが送信された。timestamp- 統計情報が収集されたミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。videoLayers- ビデオレイヤーの統計情報の配列 (OTPublisherKitVideoLayerStats).transport- 運輸統計
OTPublisherKitAudioNetworkStats
パブリッシャーのオーディオトラックに関する統計を提供します。以下を含みます:
connectionId- リレーセッションの場合、ストリームを購読しているクライアントのコネクションID。ルーティングされたセッションでは未定義。subscriberId- リレーセッションの場合、ストリームを購読するクライアントの購読ID。ルーティングされたセッションでは未定義。audioPacketsLost- 失われたパケットの推定値。audioPacketsSent- オーディオパケットを送信。audioBytesSent- 送信されたオーディオ・バイト。timestamp- ミリ秒単位のUnixタイムスタンプ。startTime- Unixエポックからのミリ秒単位のタイムスタンプ。transport- 運輸統計
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- 送信側のメトリクス(オプション)。
送信側統計
参照 送信側統計の概要.
送信側統計の有効化
送信者側の統計情報は、購読者が受け取る。送信者側の統計を受け取るには、ストリームのパブリッシャーで senderStatsTrack プロパティ true のために OTPublisherKitSettings オブジェクトはパブリッシャーの作成に使われました。
let settings = OTPublisherKitSettings()
settings.senderStatsTrack = true
let publisher = OTPublisher(delegate: self, settings: settings)
もし senderStatsTrack が有効でない場合、このパブリッシャーに対して送信者統計チャンネルは発行されません。デフォルト値は NO.
送信側統計の購読
ストリームのパブリッシャーが送信者側の統計を有効にしている場合、リスナーがビデオまたはオーディオの統計に登録されると、上記のように、購読者は自動的に統計を受信し始めます。
ビデオ統計用のデリゲート・メソッドを実装する:
func subscriber(_ subscriber: OTSubscriberKit, videoNetworkStatsUpdated stats: OTSubscriberKitVideoNetworkStats) {
if let sender = stats.senderStats {
print("Connection max allocated bitrate: \(sender.connectionMaxAllocatedBitrate)")
print("Connection current estimated bandwidth: \(sender.connectionEstimatedBandwidth)")
} else {
print("Sender-side stats not available yet.")
}
}
統計イベントの受信
送信側の統計は OTSubscriberKitNetworkStatsDelegate 上に示したように、ビデオとオーディオのコールバック。その OTSenderStatsとして含まれている。 senderStats 両方のメンバー OTSubscriberKitVideoNetworkStats そして OTSubscriberKitAudioNetworkStatsの2つのプロパティを提供する:
connectionMaxAllocatedBitrate- 接続時に推定可能な最大ビットレートconnectionEstimatedBandwidth- 接続の現在の推定帯域幅
これらの2つのメトリクスは、オーディオ・ビデオ・バンドルごとに計算されるため、ビデオとオーディオの両方の統計に同じ値が表示されます。個々のトラックではなくトランスポートを反映するため、メトリクスはオーディオとビデオの両方で共有されます。
RTC統計レポート
低レベルのストリーム統計を取得するには getRtcStatsReport() メソッド OTPublisherKit.これはメディアストリームのRTC統計レポートを非同期で提供する。
このメソッドを呼び出す前に rtcStatsReportDelegate プロパティを実装し、デリゲートメソッド publisher(_:rtcStatsReport:) より OTPublisherKitRtcStatsReportDelegate.統計情報が利用可能になると、このメソッドは OTPublisherRtcStats オブジェクトを含む。各オブジェクトには jsonArrayOfReports プロパティは、ウェブブラウザのWebRTCで使用される形式に似たRTC統計レポートのJSON配列です。
例
class MyViewController: UIViewController, OTPublisherKitRtcStatsReportDelegate {
var publisher: OTPublisher?
func setupPublisher() {
// Create and configure the publisher
publisher = OTPublisher(delegate: self, settings: OTPublisherKitSettings())
publisher?.rtcStatsReportDelegate = self
}
func fetchRtcStats() {
publisher?.getRtcStatsReport()
}
// Delegate method called when stats are ready
func publisher(_ publisher: OTPublisherKit, rtcStatsReport stats: [OTPublisherRtcStats]) {
for stat in stats {
print("RTC Stats JSON: \(stat.jsonArrayOfReports)")
}
}
}
参照 Mozillaのドキュメント). 以下も参照のこと。 このW3Cドキュメント.
サンプル
について Vonage Video iOS SDK Client Observability サンプルアプリ は、iOS Client SDKでビルドされたモバイルアプリで、クライアントの観測可能な機能を実証しています。