Topik ini menjelaskan cara memantau kualitas jaringan, audio, dan video selama panggilan.
Pengenalan Fungsi
Selama panggilan, RTC SDK memicu callback terkait kualitas panggilan dan live streaming. Callback ini dapat digunakan untuk mengevaluasi pengalaman interaksi pengguna, memecahkan masalah, serta mengoptimalkan pengalaman pengguna. SDK juga memicu callback saat status jaringan pengguna berubah dan melaporkan status terbaru tersebut.
Kode Contoh
Pemantauan kualitas selama panggilan untuk Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/StreamMonitoring/StreamMonitoringActivity.java.
Pemantauan kualitas selama panggilan untuk iOS: iOS/ARTCExample/BasicUsage/StreamMonitoring/StreamMonitoringVC.swift.
Prasyarat
Sebelum mengonfigurasi pengaturan video, penuhi persyaratan berikut:
Anda memiliki Akun Alibaba Cloud yang valid dan telah membuat aplikasi ApsaraVideo Real-time Communication. Untuk informasi lebih lanjut, lihat Buat Aplikasi. Dapatkan App ID dan App Key Anda dari Konsol Manajemen Aplikasi.
Anda telah mengintegrasikan ARTC SDK ke dalam proyek Anda dan menerapkan fitur audio dan video real-time dasar. Untuk integrasi SDK, lihat Unduh dan Integrasi SDK. Untuk implementasi audio dan video, lihat Implementasikan Panggilan Audio dan Video.
Implementasi
Dokumen ini menggunakan Android sebagai contoh. Nama antarmuka dapat berbeda di berbagai platform. Untuk detailnya, lihat kode contoh.
Laporan Kualitas Jaringan Uplink dan Downlink
Saat kualitas jaringan berubah, pengguna dapat memperoleh informasi kualitas jaringan uplink dan downlink melalui callback onNetworkQualityChanged.
Fitur ini tidak didukung di Linux.
uid: User ID. Jika kosong, merepresentasikan status jaringan uplink dan downlink pengguna lokal.
upQuality: Status jaringan uplink.
downQuality: Status jaringan downlink.
Tipe kualitas jaringan AliRtcNetworkQuality didefinisikan sebagai berikut:
Nilai Enumerasi | Deskripsi |
AliRtcNetworkExcellent (0) | Kualitas jaringan sangat baik. |
AliRtcNetworkGood (1) | Kualitas jaringan baik. |
AliRtcNetworkPoor (2) | Kualitas jaringan buruk. |
AliRtcNetworkBad (3) | Kualitas jaringan jelek. |
AliRtcNetworkVeryBad (4) | Kualitas jaringan sangat jelek. |
AliRtcNetworkDisconnected (5) | Jaringan terputus. |
AliRtcNetworkUnknow (6) | Kualitas jaringan tidak diketahui. |
Laporan Statistik
Callback onAliRtcStats dipicu setiap 2 detik dan memberikan umpan balik real-time mengenai statistik seperti transmisi data, penggunaan CPU, durasi panggilan, dan tingkat kehilangan paket. Untuk informasi lebih lanjut tentang metrik, lihat AliRtcStats.
Laporan Kualitas Audio
Statistik Aliran Audio Lokal
Callback onRtcLocalAudioStats menyediakan statistik real-time untuk pengirim audio lokal dan dipicu setiap 2 detik. Developer dapat menggunakannya untuk memantau kualitas audio, kondisi jaringan, dan status pengambilan aliran. Metrik utama meliputi hal berikut:
sentSamplerate: Laju sampel (Hz), seperti 44100 atau 48000. Menunjukkan frekuensi pengambilan sampel frame audio saat ini dan memengaruhi kejernihan audio.
numChannel: Jumlah saluran suara, seperti 1 (mono) atau 2 (stereo). Mempengaruhi persepsi spasial dan overhead transmisi.
sentBitrate: Bitrate yang dikirim (kbps). Menunjukkan jumlah data audio terkode yang dikirim per detik. Bitrate yang lebih tinggi meningkatkan kualitas audio tetapi meningkatkan penggunaan bandwidth.
Untuk metrik dan deskripsi lainnya, lihat AliRtcLocalAudioStats.
Statistik Data Langganan Audio
Callback onRtcRemoteAudioStats menyediakan statistik real-time untuk aliran audio pengguna remote, dipicu setiap 2 detik, dan memberikan data rinci mengenai kualitas audio, kondisi jaringan, dan performa pemutaran. Metrik utama meliputi hal berikut:
quality:
0: Unknown — Kualitas tidak diketahui.
1: Excellent — Kualitas sangat baik.
2: Good — Kualitas baik dengan bitrate sedikit lebih rendah.
3: Poor — Pengalaman pengguna menurun, tetapi komunikasi tidak terganggu.
4: Bad — Kualitas buruk; komunikasi terganggu.
5: Very Bad — Kualitas sangat buruk; komunikasi hampir tidak mungkin dilakukan.
6: NetworkDisconnected — Jaringan terputus; tidak ada komunikasi yang mungkin.
audioTotalFrozenRate: Laju tersendat pemutaran audio sejak bergabung ke channel.
network_transport_delay: Latensi jaringan dari pengirim ke penerima (ms).
Untuk metrik dan deskripsi lainnya, lihat AliRtcRemoteAudioStats.
Laporan Kualitas Video
Statistik Aliran Video Lokal
Callback onRtcLocalVideoStats menyediakan statistik real-time untuk pengirim video lokal dan dipicu setiap 2 detik. Developer dapat menggunakannya untuk memantau kualitas pengkodean video, kondisi jaringan, dan status pengambilan aliran. Metrik utama meliputi hal berikut:
actualEncodeBitrate: Bitrate pengkodean aktual yang digunakan selama proses encoding.
sentBitrate: Bitrate yang dikirim (kbps). Menunjukkan bitrate video aktual yang dikirim melalui jaringan.
captureFps, encodeFps, sentFps: Laju frame untuk capture, encoding, dan pengiriman video.
avgQp: Rata-rata Quantization Parameter (QP) per detik. Mencerminkan kualitas pengkodean video. Nilai QP yang lebih rendah menunjukkan kompresi yang lebih rendah.
Untuk metrik dan deskripsi lainnya, lihat AliRtcLocalVideoStats.
Statistik Data Langganan Video
Callback onRtcRemoteVideoStats menyediakan statistik real-time untuk aliran video pengguna remote, dipicu setiap 2 detik, dan memberikan data rinci mengenai kualitas video, kondisi jaringan, serta performa pemutaran. Metrik utama meliputi hal berikut:
width, height: Resolusi video.
decodeFps, renderFps: Laju frame untuk decoding dan rendering video.
videoTotalFrozenRate: Laju kumulatif tersendat pemutaran video.
Untuk metrik dan deskripsi lainnya, lihat AliRtcRemoteVideoStats.
Android
// Kualitas jaringan uplink dan downlink
private AliRtcEngineEventListener mRtcEngineEventListener = new AliRtcEngineEventListener() {
// Perubahan kualitas jaringan
@Override
public void onNetworkQualityChanged(String uid, AliRtcEngine.AliRtcNetworkQuality upQuality, AliRtcEngine.AliRtcNetworkQuality downQuality){
super.onNetworkQualityChanged(uid, upQuality, downQuality);
// TODO: Tambahkan logika bisnis
}
}
// Callback statistik
private AliRtcEngineNotify mRtcEngineNotify = new AliRtcEngineNotify() {
@Override
public void onAliRtcStats(AliRtcEngine.AliRtcStats stats){
super.onAliRtcStats(stats);
mRtcStats = stats;
updateStatsDisplay();
}
@Override
public void onRtcLocalAudioStats(AliRtcEngine.AliRtcLocalAudioStats aliRtcStats){
super.onRtcLocalAudioStats(aliRtcStats);
mLocalAudioStats = aliRtcStats;
}
@Override
public void onRtcRemoteAudioStats(AliRtcEngine.AliRtcRemoteAudioStats aliRtcStats){
super.onRtcRemoteAudioStats(aliRtcStats);
mRemoteAudioStats = aliRtcStats;
}
@Override
public void onRtcLocalVideoStats(AliRtcEngine.AliRtcLocalVideoStats aliRtcLocalVideoStats){
super.onRtcLocalVideoStats(aliRtcLocalVideoStats);
mLocalVideoStats = aliRtcLocalVideoStats;
}
@Override
public void onRtcRemoteVideoStats(AliRtcEngine.AliRtcRemoteVideoStats aliRtcRemoteVideoStats){
super.onRtcRemoteVideoStats(aliRtcRemoteVideoStats);
mRemoteVideoStats = aliRtcRemoteVideoStats;
// Perbarui tampilan semua statistik
updateStatsDisplay();
}
}iOS
extension StreamMonitoringMainVC: AliRtcEngineDelegate {
// MARK: Kualitas Jaringan
func onNetworkQualityChanged(_ uid: String, up upQuality: AliRtcNetworkQuality, downNetworkQuality downQuality: AliRtcNetworkQuality) {
}
// MARK: Callback Pemantauan Aliran
func onRtcStats(_ stats: AliRtcStats) {
}
func onRtcLocalAudioStats(_ localAudioStats: AliRtcLocalAudioStats) {
}
func onRtcRemoteAudioStats(_ remoteAudioStats: AliRtcRemoteAudioStats) {
}
func onRtcLocalVideoStats(_ localVideoStats: AliRtcLocalVideoStats) {
}
func onRtcRemoteVideoStats(_ remoteVideoStats: AliRtcRemoteVideoStats) {
}
}Mac
- (void)onNetworkQualityChanged:(NSString *)uid upNetworkQuality:(AliRtcNetworkQuality)upQuality downNetworkQuality:(AliRtcNetworkQuality)downQuality{
NSLog(@"onNetworkQualityChanged callback!");
}
- (void)onRtcStats:(AliRtcStats)stats{
/* */
NSLog(@"onRtcStats callback!");
}
- (void)onRtcLocalAudioStats:(AliRtcLocalAudioStats *)localAudioStats {
NSLog(@"onRtcLocalAudioStats callback!");
}
- (void)onRtcRemoteAudioStats:(AliRtcRemoteAudioStats *)remoteAudioStats {
NSLog(@"onRtcRemoteAudioStats callback!");
}
- (void)onRtcLocalVideoStats:(AliRtcLocalVideoStats *)localVideoStats{
NSLog(@"onRtcLocalVideoStats callback!");
}
- (void)onRtcRemoteVideoStats:(AliRtcRemoteVideoStats *)remoteVideoStats{
NSLog(@"onRtcRemoteVideoStats callback!");
}
Windows
/* Status video lokal */
void CTutorialDlg::OnLocalVideoStats(const AliEngineLocalVideoStats& localVideoStats)
{
if (m_pRtcStatsDlg != nullptr) {
m_pRtcStatsDlg->setLocalVideoStats(localVideoStats);
}
}
/* Status audio lokal */
void CTutorialDlg::OnLocalAudioStats(const AliEngineLocalAudioStats& localVideoStats)
{
if (nullptr != m_pRtcStatsDlg)
{
m_pRtcStatsDlg->setLocalAudioStats(localVideoStats);
}
}
/* Status jaringan */
void CTutorialDlg::OnNetworkQualityChanged(const char *uid,
AliEngineNetworkQuality upQuality,
AliEngineNetworkQuality downQuality)
{
// Tangani perubahan kualitas jaringan
}
/* Status audio remote */
void CTutorialDlg::OnRemoteAudioStats(const AliEngineRemoteAudioStats& remoteAudioStats)
{
CString strText, strTemp;
switch (remoteAudioStats.track)
{
case AliEngineAudioTrackMic:
strText = _T("AudioTrackMic");
break;
default:
strText = _T("AudioTrackNo");
break;
}
strText += _T(": { ");
strTemp.Format(_T("quality: %d,"), remoteAudioStats.quality);
strText += strTemp;
strTemp.Format(_T("audio_loss_rate: %d,"), remoteAudioStats.audioLossRate);
strText += strTemp;
strTemp.Format(_T("rcvd_bitrate: %d,"), remoteAudioStats.rcvdBitrate);
strText += strTemp;
strTemp.Format(_T("total_frozen_times: %d,"), remoteAudioStats.totalFrozenTimes);
strText += strTemp;
strTemp.Format(_T("network_transport_delay: %d,"), remoteAudioStats.networkTransportDelay);
strText += strTemp;
strTemp.Format(_T("jitter_buffer_delay: %d }\n"), remoteAudioStats.jitterBufferDelay);
strText += strTemp;
CString strid = AliStringToCString(remoteAudioStats.userId);
/* Tulis ke peta status. UI membaca dan menampilkannya melalui timer. */
m_MuteUserAudioStats.Lock();
m_UserAudioStatsMap[strid] = strText;
m_MuteUserAudioStats.Unlock();
}
/* Status video remote */
void CTutorialDlg::OnRemoteVideoStats(const AliEngineRemoteVideoStats& remoteVideoStats)
{
CString strText, strTemp, strStats;
CString strid = AliStringToCString(remoteVideoStats.userId);
auto iter = m_UserVideoStatsMap.find(strid);
if (iter != m_UserVideoStatsMap.end())
{
strStats = iter->second;
}
switch (remoteVideoStats.track)
{
case AliEngineVideoTrackCamera:
strText = _T("TrackCamera");
break;
case AliEngineVideoTrackScreen:
strText = _T("TrackScreen");
break;
case AliEngineVideoTrackBoth:
strText = _T("TrackBoth");
break;
default:
strText = _T("TrackNo");
break;
}
delRepeatTrackStatic(strStats, strText);
strText += _T(": { ");
strTemp.Format(_T("Width: %d,"), remoteVideoStats.width);
strText += strTemp;
strTemp.Format(_T("Height: %d,"), remoteVideoStats.height);
strText += strTemp;
strTemp.Format(_T("Decode_fps: %d,"), remoteVideoStats.decodeFps);
strText += strTemp;
strTemp.Format(_T("Render_fps: %d,"), remoteVideoStats.renderFps);
strText += strTemp;
strTemp.Format(_T("Frozen_times: %d }\n"), remoteVideoStats.frozenTimes);
strText += strTemp;
strStats += strText;
/* Tulis ke peta status. UI membaca dan menampilkannya melalui timer. */
m_MutexUserVideoStats.Lock();
m_UserVideoStatsMap[strid] = strStats;
m_MutexUserVideoStats.Unlock();
}
/* Status global engine */
void CTutorialDlg::OnStats(const AliEngineStats& stats)
{
AliEngineStats* pStats = new AliEngineStats;
if (pStats == nullptr)
{
return;
}
/* Status global juga dapat dikirim ke modul UI untuk ditampilkan. */
*pStats = stats;
PostMessage(MM_UPDATE_STATS, (WPARAM)pStats, 0);
}Linux
Implementasikan antarmuka callback di kelas EngineEventHandlerInterface.
/**
* @brief Callback statistik sesi
* @param stats Statistik sesi
* @note SDK memicu callback ini setiap dua detik.
*/
virtual void OnStats(const AliRTCSdk::Linux::AliEngineStats& stats) {}
/**
* @brief Statistik video lokal
* @param localVideoStats Statistik video lokal
* @note SDK memicu callback ini setiap dua detik.
*/
virtual void OnLocalVideoStats(const AliRTCSdk::Linux::AliEngineLocalVideoStats& localVideoStats) {}
/**
* @brief Statistik video remote
* @param remoteVideoStats Statistik video remote
* @note SDK memicu callback ini setiap dua detik.
*/
virtual void OnRemoteVideoStats(const AliRTCSdk::Linux::AliEngineRemoteVideoStats& remoteVideoStats) {}
/**
* @brief Statistik audio lokal
* @param localAudioStats Statistik audio lokal
* @note SDK memicu callback ini setiap dua detik.
*/
virtual void OnLocalAudioStats(const AliRTCSdk::Linux::AliEngineLocalAudioStats& localAudioStats) {}
/**
* @brief Statistik audio remote
* @param remoteAudioStats Statistik audio remote
* @note SDK memicu callback ini setiap dua detik.
*/
virtual void OnRemoteAudioStats(const AliRTCSdk::Linux::AliEngineRemoteAudioStats& remoteAudioStats) {}