• 製品
  • 価格
  • リソース
  • サポート

ネットワーク品質監視

ユーザーがネットワーク品質をより良く認識できるように、通話前に速度測定を実施し、通話中はネットワーク品質と接続状況を監視し、対応するUIインターフェースのインタラクションと通知を提供することをお勧めします。これにより、ユーザーは現在のネットワーク品質を容易に評価し、ネットワーク設定を適時に調整して、最適な通話効果を達成できます。

通話前のネットワーク速度測定

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



通話前の速度測定の利点:
速度測定の結果はSDKのサーバー選択戦略を最適化するために使用されるため、最適なサーバーを選択できるように、ユーザーが初めて通話する前に一度速度測定を実施することをお勧めします。
テスト結果が非常に理想的でない場合、目立つUIでユーザーにより良いネットワーク環境を選択するよう促すことができます。

startSpeedTest 速度測定

Android
iOS
Windows
//ネットワーク速度測定を開始するサンプルコード、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)
{
// 速度測定が完了すると、速度測定の結果がコールバックされます
}
速度測定の結果(TRTCSpeedTestResult)には以下のフィールドが含まれます。
フィールド
意味
意味説明
success
成功したかどうか
今回のテストは成功したかどうか
errMsg
エラー情報
帯域幅テストの詳細なエラー情報
ip
サーバーIP
速度測定サーバーのIP
quality
ネットワーク品質スコア
評価アルゴリズムによって計算されたネットワーク品質は、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を監視し、インターフェースで適切な通知を表示するだけで十分です。
Android
iOS&Mac
Windows
// onNetworkQuality コールバックを監視し、現在のネットワーク状態の変化を感知します
@Override
public void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality,
ArrayList<trtcclouddef.trtcquality> remoteQuality)
{
// Get your local network quality
switch(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 users
for (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 quality
switch(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 users
for (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 quality
switch (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 users
for (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%が伝送リンクで損失することを意味します。
Android
iOS&Mac
Windows
@Override
public 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++) {
// リモートユーザーuserid
Log.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);
// ビデオ再生の累計ブロック時間、単位 ms
Log.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++) {
// リモートユーザーuserid
NSLog(@"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++)
{
// リモートユーザーuserid
printf("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回復コールバックを受信します。
Android
iOS&Mac
Windows
@Override
public void onConnectionLost() {
// 接続が切断されました
Log.d(TAG, "onConnectionLost");
}

@Override
public void onTryToReconnect() {
// 再接続を試みます
Log.d(TAG, "onTryToReconnect");
}

@Override
public 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");
}