ネットワーク品質監視
ユーザーがネットワーク品質をより良く認識できるように、通話前に速度測定を実施し、通話中はネットワーク品質と接続状況を監視し、対応するUIインターフェースのインタラクションと通知を提供することをお勧めします。これにより、ユーザーは現在のネットワーク品質を容易に評価し、ネットワーク設定を適時に調整して、最適な通話効果を達成できます。
通話前のネットワーク速度測定
一般ユーザーはネットワーク状況を認識するのが難しいため、通話前に速度測定を実施し、現在のネットワーク品質を評価して、ネットワークを適時に調整し、通話の最適な効果を達成することをお勧めします。
速度測定の原理は、SDKがサーバーノードに一連の探査パケットを送信し、返送パケットの品質を統計し、速度測定の結果をコールバックインターフェースを通じて通知することです。下図をご参照ください。


通話前の速度測定の利点:
速度測定の結果はSDKのサーバー選択戦略を最適化するために使用されるため、最適なサーバーを選択できるように、ユーザーが初めて通話する前に一度速度測定を実施することをお勧めします。
テスト結果が非常に理想的でない場合、目立つUIでユーザーにより良いネットワーク環境を選択するよう促すことができます。
startSpeedTest 速度測定
//ネットワーク速度測定を開始するサンプルコード、sdkAppIdとUserSigが必要(取得方法は基本機能を参照)// ここではログイン後に測定を開始する例を示しますpublic void onLogin(String userId, String userSig){TRTCCloudDef.TRTCSpeedTestParams params = new TRTCCloudDef.TRTCSpeedTestParams();params.sdkAppId = GenerateTestUserSig.SDKAPPID;params.userId = mEtUserId.getText().toString();params.userSig = GenerateTestUserSig.genTestUserSig(params.userId);params.expectedUpBandwidth = Integer.parseInt(expectUpBandwidthStr);params.expectedDownBandwidth = Integer.parseInt(expectDownBandwidthStr);// sdkAppID はコンソールで取得した実際のアプリケーションのAppIDですtrtcCloud.startSpeedTest(params);}// 速度測定の結果を監視し、TRTCCloudListenerを継承して以下のメソッドを実現しますvoid onSpeedTestResult(TRTCCloudDef.TRTCSpeedTestResult result){// 速度測定が完了すると、速度測定の結果がコールバックされます}Android
// ネットワーク速度測定を開始するサンプルコード、sdkAppIdとUserSigが必要です(取得方法は基本機能を参照)// ここではログイン後に測定を開始する例を示します- (void)onLogin:(NSString *)userId userSig:(NSString *)userSid{TRTCSpeedTestParams *params;// sdkAppID はコンソールで取得した実際のアプリケーションのAppIDですparams.sdkAppID = sdkAppId;params.userID = userId;params.userSig = userSig;// 予想されるアップリンク帯域幅(kbps、範囲:10~5000、0の場合は測定なし)params.expectedUpBandwidth = 5000;// 予想されるダウンリンク帯域幅(kbps、範囲:10~5000、0の場合は測定なし)params.expectedDownBandwidth = 5000;[trtcCloud startSpeedTest:params];}- (void)onSpeedTestResult:(TRTCSpeedTestResult *)result {// 速度測定が完了すると、速度測定の結果が返されます}
// ネットワーク速度測定を開始するサンプルコード、sdkAppIdとUserSigが必要です(取得方法は基本機能を参照)// ここではログイン後に測定を開始する例を示しますvoid onLogin(const char* userId, const char* userSig){TRTCSpeedTestParams params;// sdkAppID はコンソールで取得した実際のアプリケーションのAppIDですparams.sdkAppID = sdkAppId;params.userId = userid;param.userSig = userSig;// 予想されるアップリンク帯域幅(kbps、範囲:10~5000、0の場合は測定なし)param.expectedUpBandwidth = 5000;// 予想されるダウンリンク帯域幅(kbps、範囲:10~5000、0の場合は測定なし)param.expectedDownBandwidth = 5000;trtcCloud->startSpeedTest(params);}// 速度測定の結果を監視しますvoid TRTCCloudCallbackImpl::onSpeedTestResult(const TRTCSpeedTestResult& result){// 速度測定が完了すると、速度測定の結果がコールバックされます}
フィールド | 意味 | 意味説明 |
success | 成功したかどうか | 今回のテストは成功したかどうか |
errMsg | エラー情報 | 帯域幅テストの詳細なエラー情報 |
ip | サーバーIP | 速度測定サーバーのIP |
ネットワーク品質スコア | 評価アルゴリズムによって計算されたネットワーク品質は、lossが低く、rttが小さいほど、スコアが高くなります | |
upLostRate | アップリンク・パケット損失率 | 範囲は[0 - 1.0]で、例えば0.3はサーバーに10個のデータパケットを送信するたびに、3個が途中で損失する可能性があることを示します。 |
downLostRate | ダウンリンク・パケット損失率 | 範囲は[0 - 1.0]で、例えば0.2はサーバーから10個のデータパケットを受信するたびに、2個が途中で損失する可能性があることを示します。 |
rtt | ネットワーク遅延 | SDKとサーバー間の往復にかかる時間を表し、この値は小さいほど良いです。通常の値は10ms~100msの間です。 |
availableUpBandwidth | アップリンク帯域幅 | 予測されるアップリンク帯域幅、単位はkbps、-1は無効値を示します |
availableDownBandwidth | ダウンリンク帯域幅 | 予測されるダウンリンク帯域幅、単位はkbps、-1は無効値を示します |
ツールによる速度測定
インターフェース呼び出し方式によるネットワーク速度測定を行いたくない場合、Real-Time Communication Engine (RTC Engine)はデスクトップ版のネットワーク速度測定ツールも提供しており、詳細なネットワーク品質情報を迅速に取得できます。ご利用のプラットフォームに応じて、以下のプログラムを選択してダウンロードしてください。このプログラムは、クイックテストと持続テストの2種類のテストオプションを提供しています。
Mac
指標 | 意味 |
WiFi Quality | Wi-Fi 信号品質 |
DNS RTT | Tencent Cloudの速度測定ドメイン名解決時間 |
MTR | MTRはネットワークテストツールで、クライアントからRTC Engineノードまでのパケット損失率と遅延を検出でき、ルートの各ホップの詳細情報も確認できます |
UDP Loss | クライアントからRTC EngineノードまでのUDPパケット損失率 |
UDP RTT | クライアントからRTC EngineノードまでのUDP遅延 |
Local RTT | クライアントからローカルゲートウェイまでの遅延 |
Upload | アップリンク予測帯域幅 |
Download | ダウンリンク予測帯域幅 |
注意:
ビデオ通話中は通話品質に影響を与えないよう、テストを行わないでください。
速度測定自体が一定のデータ通信量を消費するため、ごくわずかな追加通信料金が発生する可能性があります(基本的に無視できる程度です)。
通話中のネットワーク検出
ユーザーが通話中に発生する可能性のあるネットワークの変動をより明確に認識できるように、通話画面に適切なUIリマインダーを追加することをお勧めします。特にネットワーク状態が悪い場合、リマインダーによってユーザーが変化を感知し、ネットワーク状況を改善するための調整を迅速に行えるようにします。
onNetworkQuality でローカルネットワーク品質を監視します
onNetworkQualityのコールバックイベントは、2秒ごとに現在のネットワーク品質を報告します。そのパラメータには、localQualityとremoteQualityの2つの部分が含まれます。
localQuality:現在のネットワーク品質を表し、Excellent、Good、Poor、Bad、VeryBad、Downの6つのレベルに分けられます。
remoteQuality:リモートユーザーのネットワーク品質を表し、これは配列であり、配列内の各要素は1つのリモートユーザーのネットワーク品質を表します。
Quality | 名称 | 说明 |
0 | Unknown | 検出されません |
1 | Excellent | 現在のネットワークは非常に良好です |
2 | Good | 現在のネットワークは比較的良好です |
3 | Poor | 現在のネットワークは普通です |
4 | Bad | 現在のネットワークはやや悪く、明らかなラグや通話遅延が発生する可能性があります |
5 | VeryBad | 現在のネットワークは非常に悪く、RTC Engineはかろうじて接続を維持できますが、通信品質は保証できません |
6 | Down | 現在のネットワークはRTC Engineの最低要件を満たしていないため、正常なオーディオ通話やビデオ通話を行うことができません |
onNetworkQualityを監視し、インターフェースで適切な通知を表示するだけで十分です。
// onNetworkQuality コールバックを監視し、現在のネットワーク状態の変化を感知します@Overridepublic void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality,ArrayList<trtcclouddef.trtcquality> remoteQuality){// Get your local network qualityswitch(localQuality) {case TRTCQuality_Unknown:Log.d(TAG, "SDK has not yet sensed the current network quality.");break;case TRTCQuality_Excellent:Log.d(TAG, "The current network is very good.");break;case TRTCQuality_Good:Log.d(TAG, "The current network is good.");break;case TRTCQuality_Poor:Log.d(TAG, "The current network quality barely meets the demand.");break;case TRTCQuality_Bad:Log.d(TAG, "The current network is poor, and there may be significant freezes and call delays.");break;case TRTCQuality_VeryBad:Log.d(TAG, "The current network is very poor, the communication quality cannot be guaranteed");break;case TRTCQuality_Down:Log.d(TAG, "The current network does not meet the minimum requirements.");break;default:break;}// Get the network quality of remote usersfor (TRTCCloudDef.TRTCQuality info : arrayList) {Log.d(TAG, "remote user : = " + info.userId + ", quality = " + info.quality);}}
// onNetworkQuality コールバックを監視し、現在のネットワーク状態の変化を感知します- (void)onNetworkQuality:(TRTCQualityInfo *)localQuality remoteQuality:(NSArray<trtcqualityinfo *=""> *)remoteQuality {// Get your local network qualityswitch(localQuality.quality) {case TRTCQuality_Unknown:NSLog(@"SDK has not yet sensed the current network quality.");break;case TRTCQuality_Excellent:NSLog(@"The current network is very good.");break;case TRTCQuality_Good:NSLog(@"The current network is good.");break;case TRTCQuality_Poor:NSLog(@"The current network quality barely meets the demand.");break;case TRTCQuality_Bad:NSLog(@"The current network is poor, and there may be significant freezes and call delays.");break;case TRTCQuality_VeryBad:NSLog(@"The current network is very poor, the communication quality cannot be guaranteed");break;case TRTCQuality_Down:NSLog(@"The current network does not meet the minimum requirements.");break;default:break;}// Get the network quality of remote usersfor (TRTCQualityInfo *info in arrayList) {NSLog(@"remote user : = %@, quality = %@", info.userId, @(info.quality));}}iOSMac
// onNetworkQuality コールバックを監視し、現在のネットワーク状態の変化を感知しますvoid onNetworkQuality(liteav::TRTCQualityInfo local_quality,liteav::TRTCQualityInfo* remote_quality, uint32_t remote_quality_count) {// Get your local network qualityswitch (local_quality.quality) {case TRTCQuality_Unknown:printf("SDK has not yet sensed the current network quality.");break;case TRTCQuality_Excellent:printf("The current network is very good.");break;case TRTCQuality_Good:printf("The current network is good.");break;case TRTCQuality_Poor:printf("The current network quality barely meets the demand.");break;case TRTCQuality_Bad:printf("The current network is poor, and there may be significant freezes and call delays.");break;case TRTCQuality_Vbad:printf("The current network is very poor, the communication quality cannot be guaranteed");break;case TRTCQuality_Down:printf("The current network does not meet the minimum requirements.");break;default:break;}// Get the network quality of remote usersfor (int i = 0; i < remote_quality_count; ++i) {printf("remote user : = %s, quality = %d", remote_quality[i].userId, remote_quality[i].quality);}}
onStatistics で完全なネットワーク品質を監視します
onStatistics 統計コールバックイベントは2秒間隔でスローされ、SDK内部のオーディオ、ビデオ、およびネットワーク関連の専門的な技術指標を通知するために使用されます。これらの情報はTRTCStatisticsにすべて記載されています。
ビデオ統計情報:ビデオの解像度(resolution)、フレームレート(FPS)およびビットレート(bitrate)などの情報。
オーディオ統計情報:オーディオのサンプルレート(samplerate)、チャンネル(channel)およびビットレート(bitrate)などの情報。
ネットワーク統計情報:SDKとクラウド間の往復(SDK > Cloud > SDK)におけるネットワーク所要時間(rtt)、パケット損失率(loss)、アップリンクトラフィック(sentBytes)、ダウンリンクトラフィック(receivedBytes)などの情報。
列挙型 | 説明 |
appCpu | 現在のアプリケーションのCPU使用率、単位(%)、Android 8.0以上はサポートされていません。 |
downLoss | クラウドからSDKまでのダウンリンクパケット損失率、単位(%)。 この数値は小さいほど良いです。downLossが0%の場合、ダウンリンクのネットワーク品質が非常に良好であり、クラウドから受信したデータパケットが基本的に損失しないことを意味します。 downLossが30%の場合、クラウドからSDKに送信されるオーディオ・ビデオデータパケットの30%が伝送リンクで損失することを意味します。 |
gatewayRtt | SDKからローカルルーターまでの往復遅延、単位はms。この数値は、SDKがネットワークパケットをローカルルーターゲートウェイに送信し、ゲートウェイからSDKにパケットを返送するまでの総所要時間、即ちネットワークパケットが「SDK > ゲートウェイ > SDK」を経由するのにかかる時間を表します。 この数値は小さいほど良いです:gatewayRtt < 50msの場合、オーディオ・ビデオ通話の遅延が低いことを意味します;gatewayRtt > 200msの場合、オーディオ・ビデオ通話の遅延が高いことを意味します。 ネットワークタイプがセルラーネットワークの場合、この値は無効です。 |
localArray | ローカルのオーディオ・ビデオ統計情報。 ローカルには3つのオーディオビデオストリーム(即ち高精細大画面、低精細小画面、および補助ストリーム画面)が存在する可能性があるため、ローカルのオーディオビデオ統計情報は配列形式となります。 |
receiveBytes | 総受信バイト数(シグナリングデータとオーディオ・ビデオデータを含む)、単位はバイト数(Bytes)。 |
remoteArray | リモートのオーディオ・ビデオ統計情報。 複数のリモートユーザーが同時に存在する可能性があり、さらに各リモートユーザーは複数のオーディオ・ビデオストリーム(即ち高精細大画面、低精細小画面、および補助ストリーム画面)を同時に持つ可能性があるため、リモートのオーディオ・ビデオ統計情報は配列形式となります。 |
rtt | SDKからクラウドまでの往復遅延、単位はmsです。この数値は、SDKがネットワークパケットをクラウドに送信し、クラウドからSDKにネットワークパケットを返送するまでの総所要時間、即ちネットワークパケットが「SDK > クラウド > SDK」を経由する総時間を表します。 この数値は小さいほど良いです:rtt < 50msの場合、オーディオ・ビデオ通話の遅延が低いことを意味します;rtt > 200msの場合、オーディオ・ビデオ通話の遅延が高いことを意味します。 説明: rttは「SDK>クラウド>SDK」の総所要時間を表すため、upRttとdownRttを区別する必要はありません。 |
sendBytes | 総送信バイト数(シグナリングデータとオーディオ・ビデオデータを含む)、単位はバイト数(Bytes)。 |
systemCpu | 現在のシステムのCPU使用率、単位(%)、Android 8.0以上はサポートされていません。 |
upLoss | SDKからクラウドへのアップリンクパケット損失率、単位(%)。 この数値は小さいほど良いです。upLossが0%の場合、アップリンクのネットワーク品質が非常に良好であり、クラウドにアップロードしたデータパケットが基本的に損失しないことを意味します。 upLossが30%の場合、SDKからクラウドに送信されるオーディオ・ビデオデータパケットの30%が伝送リンクで損失することを意味します。 |
@Overridepublic void onStatistics(TRTCStatistics statistics) {super.onStatistics(statistics);// appCpu使用率Log.d(TAG, "appCpu:" + statistics.appCpu);// systemCpu使用率Log.d(TAG, "systemCpu:" + statistics.systemCpu);// rtt SDKからクラウドへの往復遅延Log.d(TAG, "rtt:" + statistics.rtt);// upLoss アップリンク・パケット損失率Log.d(TAG, "upLoss:" + statistics.upLoss);// downLoss ダウンリンク・パケット損失率Log.d(TAG, "downLoss:" + statistics.downLoss);// gatewayRtt ゲートウェイからクラウドへの往復遅延Log.d(TAG, "gatewayRtt:" + statistics.gatewayRtt);// sendBytes 送信バイト数Log.d(TAG, "sendBytes:" + statistics.sendBytes);// receiveBytes 受信バイト数Log.d(TAG, "receiveBytes:" + statistics.receiveBytes);if(statistics.localArray != null) {for (int i = 0; i < statistics.localArray.size(); i++) {// ローカルビデオ幅Log.d(TAG, "localStatistics width:" + statistics.localArray.get(i).width);// ローカルビデオ高さLog.d(TAG, "localStatistics height:" + statistics.localArray.get(i).height);// ローカルビデオフレームレートLog.d(TAG, "localStatistics frameRate:" + statistics.localArray.get(i).frameRate);// ローカルビデオビットレートLog.d(TAG, "localStatistics videoBitrate:" + statistics.localArray.get(i).videoBitrate);// ローカルオーディオビットレートLog.d(TAG, "localStatistics audioBitrate:" + statistics.localArray.get(i).audioBitrate);// ローカルオーディオデバイスの収集状態(オーディオ周辺機器の健全性を検出するために使用)0:収集デバイスの状態が正常;1:長時間の無音を検出;2:音割れを検出;3:音声の異常な中断を検出。Log.d(TAG, "localStatistics audioCaptureState:" + statistics.localArray.get(i).audioCaptureState);// ローカルオーディオサンプリングレートLog.d(TAG, "localStatistics audioSampleRate:" + statistics.localArray.get(i).audioSampleRate);// ローカルストリームタイプLog.d(TAG, "localStatistics streamType:" + statistics.localArray.get(i).streamType);}}if(statistics.remoteArray != null) {for (int i = 0; i < statistics.remoteArray.size(); i++) {// リモートユーザーuseridLog.d(TAG, "remoteStatistics userId:" + statistics.remoteArray.get(i).userId);// リモートユーザーストリームタイプLog.d(TAG, "remoteStatistics streamType:" + statistics.remoteArray.get(i).streamType);// リモートビデオ幅Log.d(TAG, "remoteStatistics width:" + statistics.remoteArray.get(i).width);// リモートビデオ高さLog.d(TAG, "remoteStatistics height:" + statistics.remoteArray.get(i).height);// リモートビデオフレームレートLog.d(TAG, "remoteStatistics frameRate:" + statistics.remoteArray.get(i).frameRate);// リモートビデオビットレートLog.d(TAG, "remoteStatistics videoBitrate:" + statistics.remoteArray.get(i).videoBitrate);// リモートビデオブロック率 単位 (%) ビデオ再生ブロック率(videoBlockRate)= ビデオ再生の累計ブロック時間(videoTotalBlockTime)/ ビデオ再生の総時間。Log.d(TAG, "remoteStatistics videoBlockRate:" + statistics.remoteArray.get(i).videoBlockRate);// ビデオ再生の累計ブロック時間、単位 msLog.d(TAG, "remoteStatistics videoTotalBlockTime:" + statistics.remoteArray.get(i).videoTotalBlockTime);// このビデオストリームの総パケット損失率// videoPacketLossは、このビデオストリームが 配信者>クラウド>視聴者 という完全な伝送リンクを経た後、最終的に視聴者側で統計されたパケット損失率を表します。// videoPacketLossは小さいほど良く、パケット損失率が0ということは、そのビデオストリームのすべてのデータが視聴者側に完全に到達したことを意味します。// downLoss == 0 だが videoPacketLoss != 0 の場合、そのビデオストリームは クラウド>視聴者 の伝送リンクではパケット損失が発生しなかったが、配信者>クラウド の伝送リンクで回復不能なパケット損失が発生したことを示します。Log.d(TAG, "remoteStatistics videoPacketLoss:" + statistics.remoteArray.get(i).videoPacketLoss);// リモートオーディオビットレートLog.d(TAG, "remoteStatistics audioBitrate:" + statistics.remoteArray.get(i).audioBitrate);// リモートオーディオ再生のブロック率Log.d(TAG, "remoteStatistics audioBlockRate:" + statistics.remoteArray.get(i).audioBlockRate);// リモートオーディオのサンプリングレートLog.d(TAG, "remoteStatistics audioSampleRate:" + statistics.remoteArray.get(i).audioSampleRate);// リモートオーディオのパケット損失率Log.d(TAG, "remoteStatistics audioPacketLoss:" + statistics.remoteArray.get(i).audioPacketLoss);// オーディオ再生の累計ブロック時間Log.d(TAG, "remoteStatistics audioTotalBlockTime:" + statistics.remoteArray.get(i).audioTotalBlockTime);// 再生遅延 ネットワークジッターやネットワークパケットの順序乱れによる音声と映像のラグを防ぐため、RTC Engineは再生側で再生バッファを管理し、受信したネットワークパケットを整列します。このバッファのサイズは現在のネットワーク品質に応じて自動調整され、このバッファの大きさをミリ秒単位の時間長に換算したものがjitterBufferDelayです。Log.d(TAG, "remoteStatistics jitterBufferDelay:" + statistics.remoteArray.get(i).jitterBufferDelay);// エンドツーエンド遅延、単位 ms//point2PointDelayは「配信者=>クラウド=>視聴者」の遅延を表し、より正確には「収集=>エンコード=>ネットワーク伝送=>受信=>バッファ=>デコード=>再生」という全リンクの遅延を意味します。//point2PointDelay は、ローカルとリモートのSDKがともにバージョン8.5以上の場合にのみ有効です。リモートユーザーが8.5以前のバージョンの場合、この数値は常に0になり、意味を持ちません。Log.d(TAG, "remoteStatistics point2PointDelay:" + statistics.remoteArray.get(i).point2PointDelay);}}}
- (void)onStatistics:(TRTCStatistics *)statistics {// appCpu使用率NSLog(@"appCpu: %u", statistics.appCpu);// systemCpu使用率NSLog(@"systemCpu: %u", statistics.systemCpu);// rtt SDKからクラウドへの往復遅延NSLog(@"rtt: %d", statistics.rtt);// upLoss アップリンク・パケット損失率NSLog(@"upLoss: %u", statistics.upLoss);// downLoss ダウンリンク・パケット損失率NSLog(@"downLoss: %u", statistics.downLoss);// gatewayRtt ゲートウェイからクラウドへの往復遅延NSLog(@"gatewayRtt: %d", statistics.gatewayRtt);// sendBytes 送信バイト数NSLog(@"sendBytes: %llu", (unsigned long long)statistics.sentBytes);// receiveBytes 受信バイト数NSLog(@"receiveBytes: %llu", (unsigned long long)statistics.receivedBytes);if (statistics.localStatistics != nil) {for (int i = 0; i < statistics.localStatistics.count; i++) {// ローカルビデオ幅NSLog(@"localStatistics width: %d", statistics.localStatistics[i].width);// ローカルビデオ高さNSLog(@"localStatistics height: %d", statistics.localStatistics[i].height);// ローカルビデオフレームレートNSLog(@"localStatistics frameRate: %u", statistics.localStatistics[i].frameRate);// ローカルビデオビットレートNSLog(@"localStatistics videoBitrate: %d", statistics.localStatistics[i].videoBitrate);// ローカルオーディオビットレートNSLog(@"localStatistics audioBitrate: %d", statistics.localStatistics[i].audioBitrate);// ローカルオーディオデバイスの収集状態NSLog(@"localStatistics audioCaptureState: %d", statistics.localStatistics[i].audioCaptureState);// ローカルオーディオサンプリングレートNSLog(@"localStatistics audioSampleRate: %d", statistics.localStatistics[i].audioSampleRate);// ローカルストリームタイプNSLog(@"localStatistics streamType: %ld", (long)statistics.localStatistics[i].streamType);}}if (statistics.remoteStatistics != nil) {for (int i = 0; i < statistics.remoteStatistics.count; i++) {// リモートユーザーuseridNSLog(@"remoteStatistics userId: %@", statistics.remoteStatistics[i].userId);// リモートユーザーストリームタイプNSLog(@"remoteStatistics streamType: %ld", (long)statistics.remoteStatistics[i].streamType);// リモートビデオ幅NSLog(@"remoteStatistics width: %d", statistics.remoteStatistics[i].width);// リモートビデオ高さNSLog(@"remoteStatistics height: %d", statistics.remoteStatistics[i].height);// リモートビデオフレームレートNSLog(@"remoteStatistics frameRate: %u", statistics.remoteStatistics[i].frameRate);// リモートビデオビットレートNSLog(@"remoteStatistics videoBitrate: %d", statistics.remoteStatistics[i].videoBitrate);// リモートビデオのブロック率NSLog(@"remoteStatistics videoBlockRate: %u", statistics.remoteStatistics[i].videoBlockRate);// ビデオ再生の累計ブロック時間NSLog(@"remoteStatistics videoTotalBlockTime: %d", statistics.remoteStatistics[i].videoTotalBlockTime);// このビデオストリームの総パケット損失率NSLog(@"remoteStatistics videoPacketLoss: %u", statistics.remoteStatistics[i].videoPacketLoss);// リモートオーディオビットレートNSLog(@"remoteStatistics audioBitrate: %d", statistics.remoteStatistics[i].audioBitrate);// リモートオーディオ再生のブロック率NSLog(@"remoteStatistics audioBlockRate: %u", statistics.remoteStatistics[i].audioBlockRate);// リモートオーディオのサンプリングレートNSLog(@"remoteStatistics audioSampleRate: %d", statistics.remoteStatistics[i].audioSampleRate);// リモートオーディオのパケット損失率NSLog(@"remoteStatistics audioPacketLoss: %u", statistics.remoteStatistics[i].audioPacketLoss);// オーディオ再生の累計ブロック時間NSLog(@"remoteStatistics audioTotalBlockTime: %d", statistics.remoteStatistics[i].audioTotalBlockTime);// 再生遅延NSLog(@"remoteStatistics jitterBufferDelay: %d", statistics.remoteStatistics[i].jitterBufferDelay);// エンドツーエンド遅延NSLog(@"remoteStatistics point2PointDelay: %d", statistics.remoteStatistics[i].point2PointDelay);}}}
void onStatistics(const TRTCStatistics& statistics) {// appCpu使用率printf("appCpu: %f\n", statistics.appCpu);// systemCpu使用率printf("systemCpu: %f\n", statistics.systemCpu);// rtt SDKからクラウドへの往復遅延printf("rtt: %d\n", statistics.rtt);// upLoss アップリンク・パケット損失率printf("upLoss: %f\n", statistics.upLoss);// downLoss ダウンリンク・パケット損失率printf("downLoss: %f\n", statistics.downLoss);// gatewayRtt ゲートウェイからクラウドへの往復遅延printf("gatewayRtt: %d\n", statistics.gatewayRtt);// sentBytes 送信バイト数printf("sentBytes: %lld\n", statistics.sentBytes);// receiveBytes 受信バイト数printf("receivedBytes: %lld\n", statistics.receivedBytes);//for (const auto& localStat : statistics.localStatisticsArray) {if (statistics.localStatisticsArray != nullptr && statistics.localStatisticsArraySize != 0){for (int i = 0; i < statistics.localStatisticsArraySize; i++){// ローカルビデオ幅printf("localStatistics width: %d\n", statistics.localStatisticsArray[i].width);// ローカルビデオ高さprintf("localStatistics height: %d\n", statistics.localStatisticsArray[i].height);// ローカルビデオフレームレートprintf("localStatistics frameRate: %f\n", statistics.localStatisticsArray[i].frameRate);// ローカルビデオビットレートprintf("localStatistics videoBitrate: %d\n", statistics.localStatisticsArray[i].videoBitrate);// ローカルオーディオビットレートprintf("localStatistics audioBitrate: %d\n", statistics.localStatisticsArray[i].audioBitrate);// ローカルオーディオデバイスの収集状態printf("localStatistics audioCaptureState: %d\n", statistics.localStatisticsArray[i].audioCaptureState);// ローカルオーディオサンプリングレートprintf("localStatistics audioSampleRate: %d\n", statistics.localStatisticsArray[i].audioSampleRate);// ローカルストリームタイプprintf("localStatistics streamType: %d\n", statistics.localStatisticsArray[i].streamType);}}//for (const auto& remoteStat : statistics.remoteStatisticsArray) {if (statistics.remoteStatisticsArray != nullptr && statistics.remoteStatisticsArraySize != 0){for (int i = 0; i < statistics.remoteStatisticsArraySize; i++){// リモートユーザーuseridprintf("remoteStatistics userId: %s\n", statistics.remoteStatisticsArray[i].userId);// リモートユーザーストリームタイプprintf("remoteStatistics streamType: %d\n", statistics.remoteStatisticsArray[i].streamType);// リモートビデオ幅printf("remoteStatistics width: %d\n", statistics.remoteStatisticsArray[i].width);// リモートビデオ高さprintf("remoteStatistics height: %d\n", statistics.remoteStatisticsArray[i].height);// リモートビデオフレームレートprintf("remoteStatistics frameRate: %f\n", statistics.remoteStatisticsArray[i].frameRate);// リモートビデオビットレートprintf("remoteStatistics videoBitrate: %d\n", statistics.remoteStatisticsArray[i].videoBitrate);// リモートビデオのブロック率printf("remoteStatistics videoBlockRate: %f\n", statistics.remoteStatisticsArray[i].videoBlockRate);// ビデオ再生の累計ブロック時間printf("remoteStatistics videoTotalBlockTime: %d\n", statistics.remoteStatisticsArray[i].videoTotalBlockTime);// このビデオストリームの総パケット損失率printf("remoteStatistics videoPacketLoss: %f\n", statistics.remoteStatisticsArray[i].videoPacketLoss);// リモートオーディオビットレートprintf("remoteStatistics audioBitrate: %d\n", statistics.remoteStatisticsArray[i].audioBitrate);// リモートオーディオ再生のブロック率printf("remoteStatistics audioBlockRate: %f\n", statistics.remoteStatisticsArray[i].audioBlockRate);// リモートオーディオのサンプリングレートprintf("remoteStatistics audioSampleRate: %d\n", statistics.remoteStatisticsArray[i].audioSampleRate);// リモートオーディオのパケット損失率printf("remoteStatistics audioPacketLoss: %f\n", statistics.remoteStatisticsArray[i].audioPacketLoss);// オーディオ再生の累計ブロック時間printf("remoteStatistics audioTotalBlockTime: %d\n", statistics.remoteStatisticsArray[i].audioTotalBlockTime);// 再生遅延printf("remoteStatistics jitterBufferDelay: %d\n", statistics.remoteStatisticsArray[i].jitterBufferDelay);// エンドツーエンド遅延printf("remoteStatistics point2PointDelay: %d\n", statistics.remoteStatisticsArray[i].point2PointDelay);}}}
通話中の接続監視
ユーザーは通話中にネットワークの変化を感知するだけでなく、現在のSDKとバックエンドの接続状態を把握する必要があります。これにより、ユーザーは現在のネットワークが調整済みかどうか、および正常に通話を行えるかどうかをより正確に判断できます。


コールバックインターフェース | インターフェース説明 |
onConnectionLost | SDKとクラウドの接続が切断されました |
onTryToReconnect | SDKはクラウドへの再接続を試みています |
onConnectionRecovery | SDKとクラウドの接続が復旧しました |
切断再接続ロジック
SDKはユーザーの接続が切断された場合に自動的に再接続をサポートします(30分間再接続に成功しない場合、自動的に退室し、-3301エラーコードが返されます)。接続プロセス中の具体的な接続状態と処理ロジックは以下の通りです。下図は、ユーザーUserid1がチャンネルに参加し、接続が中断され、再度ルームに再参加する過程で受信したリスナーコールバックイベントを示しています。


具体的な説明:
T1:ユーザー側が
enterRoomインターフェースを呼び出して入室リクエストを開始します。T2:ユーザーUserid1が
onEnterRoomコールバックを受信し、Userid2はUserid1の遅延を感知し、約300ms後にUserid2がonRemoteUserEnterRoomコールバックを受信します。T3:Userid1クライアントがネットワーク問題で切断され、SDKはルームへの再参加を試みます。
T4:Userid1が8秒間連続でサーバーに接続できない場合、Userid1は
onConnectionLost切断コールバックを受信します。T5:Userid1が続いて3秒間隔でサーバーに接続できない場合、Userid1は
onTryToReconnect再試行コールバックを受信します。T6:Userid1が続いて24秒ごとに、
onTryToReconnect再試行コールバックを受信します。T7:Userid2はUserid1の切断通知を受信してから90秒後に、SDKがリモートユーザーUserid1の切断を判断し、Userid2は
onRemoteUserLeaveRoomコールバックを受信します。T8:Userid1が切断中にいつでも再接続に成功した場合、Userid1は
onConnectionRecovery回復コールバックを受信します。@Overridepublic void onConnectionLost() {// 接続が切断されましたLog.d(TAG, "onConnectionLost");}@Overridepublic void onTryToReconnect() {// 再接続を試みますLog.d(TAG, "onTryToReconnect");}@Overridepublic void onConnectionRecovery() {// 再接続に成功しましたLog.d(TAG, "onConnectionRecovery");}
- (void)onConnectionLost {// 接続が切断されましたNSLog(@"onConnectionLost");}- (void)onTryToReconnect {// 再接続を試みますNSLog(@"onTryToReconnect");}- (void)onConnectionRecovery {// 再接続に成功しましたNSLog(@"onConnectionRecovery");}
void onConnectionLost() {// 接続が切断されましたprintf("onConnectionLost\n");}void onTryToReconnect() {// 再接続を試みますprintf("onTryToReconnect\n");}void onConnectionRecovery() {// 再接続に成功しましたprintf("onConnectionRecovery\n");}