Observabilité du client : Android
Le SDK Video de Vonage expose des mesures détaillées de la qualité du flux par le biais d'une API de statistiques de haut niveau - recommandée pour la plupart des cas d'utilisation - qui fournit des statistiques audio, vidéo, réseau et côté expéditeur sous une forme unifiée et consciente de la session, qui reste stable lors des transitions de connexion entre pairs. Pour le débogage avancé, le SDK permet également d'accéder au rapport de statistiques WebRTC brut, qui reflète les données de connexion entre pairs non traitées.
API pour les statistiques audio et vidéo
Le SDK Android de Vonage Video envoie des statistiques périodiques sur le réseau audio et vidéo pour les éditeurs et les abonnés. Ces statistiques comprennent le nombre de paquets, les débits binaires, les données sur la fréquence d'images, les mesures de pause et de gel, les informations sur les codecs et l'estimation facultative du réseau du côté de l'expéditeur.
Les statistiques sont fournies par l'intermédiaire de :
PublisherKit.NetworkStatsListener- statistiques côté éditeurSubscriberKit.NetworkStatsListener- statistiques relatives aux abonnés
Pour les recevoir, activez l'écouteur approprié sur l'éditeur ou l'abonné.
Activation des statistiques pour les éditeurs
Attachez une liste d'écoute pour les statistiques de l'éditeur :
publisher.setNetworkStatsListener(new PublisherKit.NetworkStatsListener() {
@Override
public void onVideoStats(PublisherKit publisher, PublisherKit.PublisherVideoStats[] statsArray) {
if (statsArray != null && statsArray.length > 0) {
// For routed sessions, first element is sufficient.
// For relayed sessions, iterate all statsArray elements to get per-subscriber info.
PublisherKit.PublisherVideoStats stats = statsArray[0];
String connectionId = (stats.connectionId != null && !stats.connectionId.isEmpty())
? stats.connectionId
: "<none>";
String subscriberId = (stats.subscriberId != null && !stats.subscriberId.isEmpty())
? stats.subscriberId
: "<none>";
Log.d("VideoStats", "Publisher Video Stats for connectionId: " + connectionId
+ ", subscriberId: " + subscriberId);
Log.d("VideoStats", "Video bytes sent: " + stats.videoBytesSent);
Log.d("VideoStats", "Video packets sent: " + stats.videoPacketsSent);
Log.d("VideoStats", "Video packets lost: " + stats.videoPacketsLost);
Log.d("VideoStats", "Stats timestamp: " + stats.timeStamp + " ms");
if (stats.videoLayers != null) {
for (PublisherKit.VideoLayerStats layer : stats.videoLayers) {
Log.d("VideoStats", "Layer: " + layer.width + "x" + layer.height);
Log.d("VideoStats", " Encoded FPS: " + layer.encodedFrameRate);
Log.d("VideoStats", " Bitrate: " + layer.bitrate + " bps");
Log.d("VideoStats", " Total bitrate (incl. RTP overhead): " + layer.totalBitrate + " bps");
Log.d("VideoStats", " Codec: " + (layer.codec != null ? layer.codec : "unknown"));
Log.d("VideoStats", " Scalability mode: " + (layer.scalabilityMode != null ? layer.scalabilityMode : "none"));
Log.d("VideoStats", " Quality limitation: " + layer.qualityLimitationReason);
}
}
if (stats.transport != null) {
Log.d("VideoStats", "Estimated uplink bandwidth: " + stats.transport.getConnectionEstimatedBandwidth() + " bps");
}
}
}
@Override
public void onAudioStats(PublisherKit publisher, PublisherKit.PublisherAudioStats[] statsArray) {
if (statsArray != null && statsArray.length > 0) {
// For routed sessions, first element is sufficient.
// For relayed sessions, iterate all statsArray elements to get per-subscriber info.
PublisherKit.PublisherAudioStats stats = statsArray[0];
String connectionId = (stats.connectionId != null && !stats.connectionId.isEmpty())
? stats.connectionId
: "<none>";
String subscriberId = (stats.subscriberId != null && !stats.subscriberId.isEmpty())
? stats.subscriberId
: "<none>";
Log.d("AudioStats", "Publisher Audio Stats for connectionId: " + connectionId
+ ", subscriberId: " + subscriberId);
Log.d("AudioStats", "Audio bytes sent: " + stats.audioBytesSent);
Log.d("AudioStats", "Audio packets sent: " + stats.audioPacketsSent);
Log.d("AudioStats", "Audio packets lost: " + stats.audioPacketsLost);
Log.d("AudioStats", "Stats timestamp: " + stats.timeStamp + " ms");
if (stats.transport != null) {
Log.d("AudioStats", "Estimated uplink bandwidth: " + stats.transport.getConnectionEstimatedBandwidth() + " bps");
}
}
}
});
Pour un éditeur dans une session acheminée (qui utilise l'option Routeur vidéo multimédia de Vonage), le tableau stats comprend un objet, définissant les statistiques pour le flux audio ou vidéo unique envoyé au routeur vidéo de Vonage. Dans une session relayée, le tableau de statistiques comprend un objet pour chaque abonné au flux publié. le flux publié.
Réception d'événements de qualité vidéo sur les éditeurs
Pour les événements de qualité vidéo, mettre en œuvre :
@Override
public void onPublisherVideoQualityChanged(PublisherKit.PublisherVideoStats stats, String reason) {
Log.d("Stats", "Publisher video quality event: " + reason);
}
Activation des statistiques pour les abonnés
Attacher un écouteur mettant en œuvre SubscriberKit.SubscriberKitNetworkStatsListener:
Subscriber subscriber = new Subscriber(stream);
subscriber.setNetworkStatsListener(new SubscriberKit.SubscriberKitNetworkStatsListener() {
@Override
public void onSubscriberVideoStatsUpdated(SubscriberKit.SubscriberVideoStats stats) {
Log.d("Stats", "Video bytes received: " + stats.videoBytesReceived);
}
@Override
public void onSubscriberAudioStatsUpdated(SubscriberKit.SubscriberAudioStats stats) {
Log.d("Stats", "Audio packets received: " + stats.audioPacketsReceived);
}
});
Réception d'événements relatifs à la qualité vidéo sur les abonnés
Pour les événements de qualité vidéo, mettre en œuvre :
@Override
public void onSubscriberVideoQualityChanged(SubscriberKit.SubscriberVideoStats stats, String reason) {
Log.d("Stats", "Subscriber video quality event: " + reason);
}
Statistiques Structures de données
Cette section présente les structures et les propriétés fournies par l'API de statistiques audio et vidéo d'Android. Bien que toutes les plateformes SDK vidéo exposent le même ensemble de statistiques, il peut y avoir des différences mineures dans la façon dont chaque plateforme structure ou nomme les champs individuels. Ces variations reflètent les conventions de conception du SDK propres à chaque plateforme plutôt que des différences dans les mesures sous-jacentes.
Pour une explication indépendante de la plate-forme des statistiques disponibles et de ce qu'elles représentent, voir aperçu de l'observabilité du client.
TransportStats
Représente l'estimation partagée au niveau du transport.
connectionEstimatedBandwidth- Estimation de la largeur de bande disponible de la connexion de liaison montante (bps).
PublisherKit.PublisherVideoStats
Fournit des statistiques sur la piste vidéo d'un éditeur. Elles comprennent :
connectionId- Dans une session relayée, l'identifiant de connexion du client souscrivant au flux. Indéfini dans une session routée.subscriberId- Dans une session relayée, l'identifiant du client abonné au flux. Indéfini dans une session routée.videoPacketsLost- Estimation des paquets vidéo perdus.videoPacketsSent- Paquets vidéo envoyés.videoBytesSent- Octets vidéo envoyés.timeStamp- Date Unix en millisecondes à laquelle les statistiques ont été recueillies.startTime- Le timestamp, en millisecondes depuis l'époque Unix, à partir duquel les totaux cumulés ont commencé à s'accumuler.videoLayers- Tableau de statistiques sur la couche vidéo (voirOTPublisherKitVideoLayerStats).transport- Statistiques sur les transports.
PublisherKit.PublisherAudioStats
Fournit des statistiques sur la piste audio d'un éditeur. Elle comprend :
connectionId- Dans une session relayée, l'identifiant de connexion du client souscrivant au flux. Indéfini dans une session routée.subscriberId- Dans une session relayée, l'identifiant du client abonné au flux. Indéfini dans une session routée.audioPacketsLost- Estimation des paquets perdus.audioPacketsSent- Paquets audio envoyés.audioBytesSent- Octets audio envoyés.timeStamp- Horodatage Unix en millisecondes.startTime- Le timestamp, en millisecondes depuis l'époque Unix, à partir duquel les totaux cumulés ont commencé à s'accumuler.transport- Statistiques sur les transports.
PublisherKit.VideoLayerStats
Représente une couche simulcast ou une couche SVC.
width- Largeur de la trame encodée.height- Hauteur du cadre codé.encodedFrameRate- Images codées par seconde.bitrate- Débit binaire de la couche (bps).totalBitrate- Débit de la couche incluant le surdébit RTP (bps).scalabilityMode- Descripteur SVC/scalability (par exemple, "L3T3").qualityLimitationReason- Raison de la limitation de la qualité (bande passante, CPU, codec, résolution ou changement de couche).codec- Le codec utilisé par cette couche vidéo.
SubscriberKit.SenderStats
Mesures d'estimation du côté de l'expéditeur (reflétées à la fois sur l'audio et la vidéo).
connectionMaxAllocatedBitrate- Débit maximum estimé pour la connexion de l'expéditeur.connectionEstimatedBandwidth- Estimation de la largeur de bande actuelle (bps).
SubscriberKit.SubscriberVideoStats
Fournit des statistiques sur la piste vidéo d'un abonné. Elles comprennent :
videoPacketsLost- Estimation des paquets vidéo perdus.videoPacketsReceived- Paquets vidéo reçus.videoBytesReceived- Octets vidéo reçus.timeStamp- Date Unix en millisecondes à laquelle les statistiques ont été recueillies.senderStats- Mesures du côté de l'expéditeur (facultatif).width- Largeur de la trame décodée en pixels.height- Hauteur de l'image décodée en pixels.decodedFrameRate- Images décodées par seconde.bitrate- Débit binaire vidéo (bps).totalBitrate- Débit binaire incluant l'overhead RTP (bps).pauseCount- Nombre de pauses (>5s depuis la dernière image). Inclut les désactivations intentionnelles et les cas de retour audio.totalPausesDuration- Durée totale de la pause (ms).freezeCount- Compte de gel (événement de gel défini par WebRTC).totalFreezesDuration- Durée totale de l'arrêt sur image (ms).codec- Codec du décodeur actuel.
SubscriberKit.SubscriberAudioStats
Fournit des statistiques sur la piste audio d'un abonné. Elles comprennent :
audioPacketsLost- Estimation des paquets perdus.audioPacketsReceived- Paquets reçus.audioBytesReceived- Octets reçus.timeStamp- Horodatage Unix en millisecondes.senderStats- Mesures du côté de l'expéditeur (facultatif).
Statistiques côté expéditeur
Voir le aperçu des statistiques côté expéditeur.
Activation des statistiques côté expéditeur
Les statistiques côté émetteur sont reçues par les abonnés. Pour recevoir les statistiques côté émetteur, il faut les activer pour l'éditeur du flux en définissant l'attribut senderStatisticsTrack à la propriété true lors de la construction de l'éditeur :
Publisher publisher = new Publisher.Builder(context)
.senderStatsTrack(true) // Enable sender-side stats
.build();
Si senderStatsTrack n'est pas activé, aucun canal de statistiques sur les expéditeurs ne sera publié pour cet éditeur. La valeur par défaut est false.
Abonnement aux statistiques côté expéditeur
Les abonnés reçoivent automatiquement les statistiques de l'expéditeur uniquement si l'éditeur les a activées et si l'abonné enregistre un auditeur pour les événements de statistiques du réseau.
Statistiques de réception Événements
Les statistiques du côté de l'expéditeur sont fournies par l'intermédiaire de l'application SubscriberKit.VideoStatsListener et SubscriberKit.AudioStatsListener pour la vidéo et l'audio. Les SubscriberKit.SubscriberVideoStats et SubscriberKit.SubscriberAudioStats comprennent toutes ces propriétés :
connectionMaxAllocatedBitrate- Le débit maximum qui peut être estimé pour la connexionconnectionEstimatedBandwidth- Le débit binaire actuel estimé pour la connexion
Ces deux mesures sont calculées par paquet audio-vidéo, de sorte que les mêmes valeurs apparaissent dans les statistiques audio et vidéo. Parce qu'elles reflètent le transport plutôt que les pistes individuelles, les mesures sont partagées entre l'audio et la vidéo.
Les stats comprend un objet optionnel senderStats qui fournit les statistiques du côté de l'expéditeur. Par exemple, lors de l'utilisation de SubscriberKit.setVideoStatsListener(), le stats est un paramètre SubscriberKit.SubscriberVideoStats objet :
subscriber.setVideoStatsListener((subscriber, stats) -> {
if (stats.senderStats != null) {
Log.d(TAG, "Connection max allocated bitrate: " + stats.senderStats.connectionMaxAllocatedBitrate);
Log.d(TAG, "Connection current estimated bandwidth: " + stats.senderStats.connectionEstimatedBandwidth);
} else {
Log.d(TAG, "Sender stats not available yet.");
}
});
Il en va de même pour les statistiques audio utilisant SubscriberKit.AudioStatsListener.
Rapport statistique RTC
Pour obtenir des statistiques de bas niveau sur les connexions entre pairs pour un éditeur, utilisez la commande PublisherKit.getRtcStatsReport() méthode. Cette méthode fournit des rapports de statistiques RTC pour le flux multimédia. Il s'agit d'une opération asynchrone. Appelez la méthode PublisherKit.setRtcStatsReportListener(PublisherKit.PublisherRtcStatsReportListener listener) puis mettre en œuvre la méthode PublisherKit.PublisherRtcStatsReportListener.onRtcStatsReport(PublisherKit publisher, PublisherKit.PublisherRtcStats[] stats) avant d'appeler la méthode PublisherKit.getRtcStatsReport().
Lorsque les statistiques sont disponibles, la mise en œuvre de la fonction PublisherKit.PublisherRtcStatsReportListener.onRtcStatsReport(PublisherKit publisher, PublisherKit.PublisherRtcStats[] stats) est appelée.
Un tableau de PublisherRtcStats est transmis à cette méthode. La méthode PublisherRtcStats comprend un objet jsonArrayOfReports propriété. Il s'agit d'un tableau JSON de rapports de statistiques RTC, dont le format est similaire à celui de l'objet RtcStatsReport mis en œuvre dans les navigateurs web (voir ces documents de Mozilla).
Pour obtenir des statistiques de bas niveau sur les connexions entre pairs pour un abonné, utilisez la commande SubscriberKit.getRtcStatsReport() méthode. Cette méthode permet d'obtenir un rapport de statistiques RTC pour le flux multimédia.
Il s'agit d'une opération asynchrone. Appeler le SubscriberKit.setRtcStatsReportListener(SubscriberKit.SubscriberRtcStatsReportListener listener) puis mettre en œuvre la méthode SubscriberKit.SubscriberRtcStatsReportListener.onRtcStatsReport(SubscriberKit subscriber, java.lang.String jsonArrayOfReports) avant d'appeler la méthode SubscriberKit.getRtcStatsReport().
Lorsque les statistiques sont disponibles, la mise en œuvre de la fonction SubscriberKit.SubscriberRtcStatsReportListener.onRtcStatsReport(SubscriberKit subscriber, java.lang.String jsonArrayOfReports) est appelée. La méthode jsonArrayOfReports est un tableau JSON de rapports de statistiques RTC, dont le format est similaire à celui de l'objet RtcStatsReport mis en œuvre dans les navigateurs web (voir ces documents de Mozilla).
Voir aussi cette documentation du W3C.