Surveillez la qualité du réseau, de l'audio et de la vidéo pendant un appel afin de résoudre les problèmes et d'optimiser l'expérience utilisateur.
Présentation de la fonctionnalité
Pendant un appel, le SDK RTC déclenche des rappels liés à la qualité des appels et du streaming en direct. Utilisez ces rappels pour évaluer la qualité des interactions, diagnostiquer les problèmes et optimiser l'expérience utilisateur. Le SDK signale également les changements d'état du réseau via des rappels dédiés.
Exemple de code
Surveillance de la qualité des appels pour Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/StreamMonitoring/StreamMonitoringActivity.java.
Surveillance de la qualité des appels pour iOS: iOS/ARTCExample/BasicUsage/StreamMonitoring/StreamMonitoringVC.swift.
Prérequis
Avant de commencer, assurez-vous que les conditions suivantes sont remplies :
Vous disposez d'un compte Alibaba Cloud valide et avez créé une application ApsaraVideo Real-time Communication. Pour plus d'informations, reportez-vous à Créer une application. Récupérez votre App ID et votre App Key depuis la console de gestion des applications.
Vous avez intégré le SDK ARTC dans votre projet et implémenté les fonctionnalités audio et vidéo en temps réel de base. Pour l'intégration du SDK, reportez-vous à Téléchargement et intégration du SDK. Pour l'implémentation audio et vidéo, reportez-vous à Implémenter les appels audio et vidéo.
Implémentation
Les exemples suivants utilisent Android. Les noms d'interface peuvent varier selon les plateformes. Pour plus de détails, consultez l'exemple de code.
Rapports sur la qualité du réseau en amont et en aval
Lorsque la qualité du réseau change, le rappel onNetworkQualityChanged signale la qualité du réseau en amont (upload) et en aval (download).
Cette fonctionnalité n'est pas prise en charge sous Linux.
uid : ID utilisateur. Si ce champ est vide, il représente l'état du réseau en amont et en aval de l'utilisateur local.
upQuality : État du réseau en amont.
downQuality : État du réseau en aval.
Le type de qualité du réseau AliRtcNetworkQuality est défini comme suit :
|
Valeur d'énumération |
Description |
|
AliRtcNetworkExcellent (0) |
Qualité du réseau excellente. |
|
AliRtcNetworkGood (1) |
Qualité du réseau bonne. |
|
AliRtcNetworkPoor (2) |
Qualité du réseau médiocre. |
|
AliRtcNetworkBad (3) |
Qualité du réseau mauvaise. |
|
AliRtcNetworkVeryBad (4) |
Qualité du réseau très mauvaise. |
|
AliRtcNetworkDisconnected (5) |
Réseau déconnecté. |
|
AliRtcNetworkUnknow (6) |
Qualité du réseau inconnue. |
Rapports statistiques
Le rappel onAliRtcStats se déclenche toutes les 2 secondes et fournit des statistiques en temps réel sur la transmission des données, l'utilisation du CPU, la durée de l'appel et le taux de perte de paquets. Pour plus d'informations sur les métriques, reportez-vous à AliRtcStats.
Rapports sur la qualité audio
Statistiques du flux audio local
Le rappel onRtcLocalAudioStats se déclenche toutes les 2 secondes et fournit des statistiques en temps réel pour l'émetteur audio local, y compris la qualité audio, les conditions réseau et l'état de l'ingestion du flux. Les principales métriques incluent :
sentSamplerate : Taux d'échantillonnage (Hz), par exemple 44100 ou 48000. Indique la fréquence d'échantillonnage de la trame audio actuelle et affecte la clarté audio.
numChannel : Nombre de canaux audio, par exemple 1 (mono) ou 2 (stéréo). Affecte la perception spatiale et la charge de transmission.
sentBitrate : Débit binaire envoyé (kbps). Indique la quantité de données audio encodées envoyées par seconde. Des débits plus élevés améliorent la qualité audio mais augmentent l'utilisation de la bande passante.
Pour plus de métriques et de descriptions, reportez-vous à AliRtcLocalAudioStats.
Statistiques des données d'abonnement audio
Le rappel onRtcRemoteAudioStats se déclenche toutes les 2 secondes et fournit des statistiques en temps réel pour les flux audio distants, y compris la qualité audio, les conditions réseau et les performances de lecture. Les principales métriques incluent :
-
quality :
0 : Inconnu — Qualité inconnue.
1 : Excellent — Qualité excellente.
2 : Bon — Bonne qualité avec un débit binaire légèrement inférieur.
3 : Médiocre : L'expérience utilisateur est dégradée, mais la communication n'est pas affectée.
4 : Mauvais — Mauvaise qualité ; la communication est perturbée.
5 : Très mauvais — Qualité très mauvaise ; la communication est presque impossible.
6 : NetworkDisconnected — Réseau déconnecté ; aucune communication possible.
audioTotalFrozenRate : Taux de saccades de la lecture audio depuis la connexion au canal.
network_transport_delay : Latence réseau de l'émetteur au récepteur (ms).
Pour plus de métriques et de descriptions, reportez-vous à AliRtcRemoteAudioStats.
Rapports sur la qualité vidéo
Statistiques du flux vidéo local
Le rappel onRtcLocalVideoStats se déclenche toutes les 2 secondes et fournit des statistiques en temps réel pour l'émetteur vidéo local, y compris la qualité d'encodage, les conditions réseau et l'état de l'ingestion du flux. Les principales métriques incluent :
actualEncodeBitrate : Débit binaire d'encodage réel utilisé lors de l'encodage.
sentBitrate : Débit binaire envoyé (kbps). Indique le débit vidéo réel envoyé sur le réseau.
captureFps, encodeFps, sentFps : Fréquences d'images pour la capture, l'encodage et l'envoi de la vidéo.
avgQp : Paramètre de quantification moyen (QP) par seconde. Reflète la qualité de l'encodage vidéo. Des valeurs QP plus faibles indiquent une compression moindre.
Pour plus de métriques et de descriptions, reportez-vous à AliRtcLocalVideoStats.
Statistiques des données d'abonnement vidéo
Le rappel onRtcRemoteVideoStats se déclenche toutes les 2 secondes et fournit des statistiques en temps réel pour les flux vidéo distants, y compris la qualité vidéo, les conditions réseau et les performances de lecture. Les principales métriques incluent :
width, height : Résolution vidéo.
decodeFps, renderFps : Fréquences d'images pour le décodage et le rendu vidéo.
videoTotalFrozenRate : Taux cumulé de saccades de la lecture vidéo.
Pour plus de métriques et de descriptions, reportez-vous à AliRtcRemoteVideoStats.
Android
// Uplink and downlink network quality
private AliRtcEngineEventListener mRtcEngineEventListener = new AliRtcEngineEventListener() {
// Network quality change
@Override
public void onNetworkQualityChanged(String uid, AliRtcEngine.AliRtcNetworkQuality upQuality, AliRtcEngine.AliRtcNetworkQuality downQuality){
super.onNetworkQualityChanged(uid, upQuality, downQuality);
// TODO: Add business logic
}
}
// Statistics callback
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;
// Update display for all statistics
updateStatsDisplay();
}
}
iOS
extension StreamMonitoringMainVC: AliRtcEngineDelegate {
// MARK: Network Quality
func onNetworkQualityChanged(_ uid: String, up upQuality: AliRtcNetworkQuality, downNetworkQuality downQuality: AliRtcNetworkQuality) {
}
// MARK: Stream Monitoring Callback
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
/* Local video status */
void CTutorialDlg::OnLocalVideoStats(const AliEngineLocalVideoStats& localVideoStats)
{
if (m_pRtcStatsDlg != nullptr) {
m_pRtcStatsDlg->setLocalVideoStats(localVideoStats);
}
}
/* Local audio status */
void CTutorialDlg::OnLocalAudioStats(const AliEngineLocalAudioStats& localVideoStats)
{
if (nullptr != m_pRtcStatsDlg)
{
m_pRtcStatsDlg->setLocalAudioStats(localVideoStats);
}
}
/* Network status */
void CTutorialDlg::OnNetworkQualityChanged(const char *uid,
AliEngineNetworkQuality upQuality,
AliEngineNetworkQuality downQuality)
{
// Handle network quality change
}
/* Remote audio status */
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);
/* Write to status map. UI reads and displays it via timer. */
m_MuteUserAudioStats.Lock();
m_UserAudioStatsMap[strid] = strText;
m_MuteUserAudioStats.Unlock();
}
/* Remote video status */
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;
/* Write to status map. UI reads and displays it via timer. */
m_MutexUserVideoStats.Lock();
m_UserVideoStatsMap[strid] = strStats;
m_MutexUserVideoStats.Unlock();
}
/* Engine global status */
void CTutorialDlg::OnStats(const AliEngineStats& stats)
{
AliEngineStats* pStats = new AliEngineStats;
if (pStats == nullptr)
{
return;
}
/* Global status can also be sent to the UI module for display. */
*pStats = stats;
PostMessage(MM_UPDATE_STATS, (WPARAM)pStats, 0);
}
Linux
Implémentez les interfaces de rappel dans la classe EngineEventHandlerInterface.
/**
* @brief Session statistics callback
* @param stats Session statistics
* @note SDK triggers this callback every two seconds.
*/
virtual void OnStats(const AliRTCSdk::Linux::AliEngineStats& stats) {}
/**
* @brief Local video statistics
* @param localVideoStats Local video statistics
* @note SDK triggers this callback every two seconds.
*/
virtual void OnLocalVideoStats(const AliRTCSdk::Linux::AliEngineLocalVideoStats& localVideoStats) {}
/**
* @brief Remote video statistics
* @param remoteVideoStats Remote video statistics
* @note SDK triggers this callback every two seconds.
*/
virtual void OnRemoteVideoStats(const AliRTCSdk::Linux::AliEngineRemoteVideoStats& remoteVideoStats) {}
/**
* @brief Local audio statistics
* @param localAudioStats Local audio statistics
* @note SDK triggers this callback every two seconds.
*/
virtual void OnLocalAudioStats(const AliRTCSdk::Linux::AliEngineLocalAudioStats& localAudioStats) {}
/**
* @brief Remote audio statistics
* @param remoteAudioStats Remote audio statistics
* @note SDK triggers this callback every two seconds.
*/
virtual void OnRemoteAudioStats(const AliRTCSdk::Linux::AliEngineRemoteAudioStats& remoteAudioStats) {}