Das Vonage Video SDK stellt detaillierte Metriken zur Stream-Qualität über eine High-Level-Statistik-API zur Verfügung, die für die meisten Anwendungsfälle empfohlen wird und die Audio-, Video-, Netzwerk- und Absenderstatistiken in einer einheitlichen, sitzungsspezifischen Form bereitstellt, die über Peer-Verbindungsübergänge hinweg stabil bleibt. Für fortgeschrittenes Debugging bietet das SDK auch Zugriff auf den rohen WebRTC-Statistikbericht, der unverarbeitete Peer-Verbindungsdaten wiedergibt.
Audio- und Videostatistik-API
Das Vonage Video Web SDK sendet regelmäßig Audio- und Videonetzwerkstatistiken sowohl für Publisher als auch für Abonnenten. Dazu gehören die Anzahl der Pakete, Bitraten, Daten zur Bildrate, Pausen-/Freeze-Metriken, Codec-Informationen und optionale senderseitige Netzwerkschätzungen.
Abrufen von Statistiken für einen Verlag
Die Verlag.getStats() Methode liefert Ihnen ein Array
von Objekten, die die aktuellen Audio-Video-Statistiken für den Verleger definieren.
Für einen Verleger in einer gerouteten Sitzung (eine, die die OpenTok
Medien-Router), enthält dieses Array ein Objekt, das die Statistiken für
den einzelnen Audio-Video-Stream, der an den Vonage Video Media Router gesendet wird. In einer weitergeleiteten Sitzung,
enthält das Array ein Objekt für jeden Teilnehmer des veröffentlichten Streams.
Der folgende Code protokolliert jede Sekunde einige Metriken für den Stream des Herausgebers:
window.setInterval(() => {
publisher.getStats((error, statsArray) => {
if (error) {
console.error(error);
return;
}
statsArray.forEach(statsContainer => {
const stats = statsContainer.stats;
const connectionId = stats.connectionId || 'routed';
console.log(`\nStats for ${connectionId}`);
if (stats.video) {
const video = stats.video;
if (video.layers && video.layers.length > 0) {
console.log(`Video layers: ${video.layers.length}`);
video.layers.forEach((layer, index) => {
console.log(` Layer ${index}: ${layer.width}x${layer.height}`);
console.log(` encodedFrameRate: ${layer.encodedFrameRate} fps`);
console.log(` bitrate: ${layer.bitrate} bps`);
console.log(` totalBitrate: ${layer.totalBitrate} bps`);
console.log(` codec: ${layer.codec}`);
console.log(` scalabilityMode: ${layer.scalabilityMode}`);
if (layer.qualityLimitationReason) {
console.log(` qualityLimitationReason: ${layer.qualityLimitationReason}`);
}
});
}
if (stats.transportStats) {
console.log(
'transport estimated bandwidth:',
stats.transportStats.connectionEstimatedBandwidth,
'bps'
);
}
}
});
});
}, 1000);
Empfang von Ereignissen in Videoqualität bei den Herausgebern
Neben der Abfrage von Statistiken mit Publisher.getStats()können Sie sich in Echtzeit benachrichtigen lassen, wenn der Herausgeber eine bedeutsame Änderung der Videoqualität feststellt, indem Sie sich bei der videoQualityChanged Veranstaltung:
publisher.on('videoQualityChanged', ({ reason, statsContainer }) => {
console.log('Video quality change reason:', reason);
const { stats } = statsContainer;
if (stats.video && stats.video.layers) {
stats.video.layers.forEach((layer) => {
console.log(
`Resolution: ${layer.width}x${layer.height}, FPS: ${layer.frameRate}`
);
});
}
});
Abrufen von Statistiken für einen Teilnehmer
Die getStats() Methode eines Subscriber-Objekts liefert Ihnen Informationen über den
Stream des Abonnenten.
Der folgende Code protokolliert jede Sekunde mehrere Metriken für den Stream des Abonnenten:
window.setInterval(() => {
subscriber.getStats((error, stats) => {
if (error) {
console.error('Error getting subscriber stats: ', error.message);
return;
}
const video = stats.video;
if (video) {
console.log('video bitrate:', video.bitrate, 'bps');
console.log('video totalBitrate:', video.totalBitrate, 'bps');
console.log('decoded frame rate:', video.decodedFrameRate, 'fps');
console.log('codec:', video.codec);
console.log('res:', `${video.width}x${video.height}`);
console.log('freezeCount:', video.freezeCount);
console.log('totalFreezesDuration:', video.totalFreezesDuration, 'ms');
console.log('pauseCount:', video.pauseCount);
console.log('totalPausesDuration:', video.totalPausesDuration, 'ms');
}
});
}, 1000);
Empfang von Videoqualitätsereignissen bei den Abonnenten
Abonnenten können auf die videoQualityChanged Ereignis, um benachrichtigt zu werden, wenn signifikante Unterbrechungen oder Änderungen der Videoqualität festgestellt werden.
subscriber.on('videoQualityChanged', ({ reason, stats }) => {
if (reason === 'videoInterruption') {
console.warn('Video playback was interrupted');
if (stats.video.freezeCount > 0) {
console.log(`Freeze count: ${stats.video.freezeCount}`);
}
if (stats.video.pauseCount > 0) {
console.log(`Pause count: ${stats.video.pauseCount}`);
}
}
});
Bekannte Probleme
Die tatsächlichen Werte und Bedingungen, die Qualitätseinschränkungen auslösen, sind implementierungsspezifisch und können zwischen Browsern und Plattformen variieren. Zum Beispiel:
- Video-Streams zur gemeinsamen Nutzung des Bildschirms lösen nie die
videoQualityChangedVeranstaltung. - Firefox unterstützt nicht
qualityLimitationReasonDaher ist diese Eigenschaft in den Statistiken des Herausgebers nicht enthalten. Auch,videoQualityChangedEreignisse mit Begründungbandwidth,cpuundotherwerden in diesem Browser nicht unterstützt. - Hardware-beschleunigte Videokodierung und spezielle Video-Encoder verhindern, dass macOS
cpuEinschränkungen.
Statistik-Datenstrukturen
In diesem Abschnitt werden die Strukturen und Eigenschaften beschrieben, die von der Web-Audio- und Videostatistik-API bereitgestellt werden. Während alle Video SDK-Plattformen die gleichen Statistiken bereitstellen, kann es geringfügige Unterschiede bei der Strukturierung oder Benennung einzelner Felder geben. Diese Unterschiede spiegeln eher plattformspezifische SDK-Designkonventionen als Unterschiede in den zugrunde liegenden Metriken wider.
Verlagsstatistiken (stats)
Liefert Statistiken über einen Verlag.
connectionId- Die eindeutige ID der Client-Verbindung, die mit der id-Eigenschaft der DateiconnectionEigenschaft derconnectionCreatedEreignis, das das Sitzungsobjekt für den entfernten Client ausgelöst hat (nur bei weitergeleiteten Sitzungen verfügbar).subscriberId- Die eindeutige ID des Abonnenten, die mit der id-Eigenschaft der DateiSubscriberObjekt in der Anwendung des abonnierenden Clients (nur in weitergeleiteten Sitzungen verfügbar).
Verlags-Audiostatistik (stats.audio)
Liefert Statistiken über die Audiospur eines Verlags.
bytesSent- Insgesamt gesendete Audio-Bytes.packetsLost- Summe der Audiopakete, die den Teilnehmer oder Media Router nicht erreicht haben.packetsSent- Insgesamt gesendete Audiopakete.timestamp- Unix-Zeitstempel (ms), als die Statistiken erfasst wurden.
Videostatistik des Herausgebers (stats.video)
Diese Felder stellen die aktuelle Videoleistung des Herausgebers dar:
bytesSent- Insgesamt gesendete Video-Bytes.packetsLost- Gesamtzahl der Videopakete, die den Teilnehmer oder Media Router nicht erreicht haben.packetsSent- Gesamtzahl der gesendeten Videopakete.layers- Eine geordnete Liste aktiver Videocodierungsebenen von der höchsten zur niedrigsten Auflösung.
Statistik der Videoebene des Herausgebers (stats.video.layers)
Steht für eine Simulcast- oder SVC-Schicht.
width- Kodierte Breite in Pixel.height- Kodierte Höhe in Pixel.encodedFrameRate- Tatsächliche Kodierbildrate für diese Ebene.bitrate- Nutzdaten-Bitrate (bps).totalBitrate- Bitrate einschließlich RTP-Header und Padding (bps).scalabilityMode- Konfiguration der Skalierbarkeit (z. B. "L1T3" für SVC oder "L3T3" für Simulcast).codec- Für diese Ebene verwendeter Codec.qualityLimitationReason- Gibt an, warum der Encoder die Qualität angepasst hat ("Bandbreite", "CPU", "Sonstiges").
Verlagsverkehrsstatistik (stats.transport)
Das transportStats-Objekt liefert Metriken zur Netzwerkeinschätzung auf Peer-Verbindungsebene, die sich auf den gesamten Audio-Video-Transport beziehen und nicht auf einzelne Spuren oder Schichten.
connectionEstimatedBandwidth- Geschätzte verfügbare Uplink-Bandbreite für die Verbindung (bps).
Teilnehmer-Audiostatistik (stats.audio)
Liefert Statistiken über die Audiospur eines Abonnenten.
bytesReceived- Insgesamt empfangene Audio-Bytes.packetsLost- Summe der Audiopakete, die den Teilnehmer nicht erreicht haben.packetsReceived- Insgesamt erfolgreich empfangene Audiopakete.timestamp- Unix-Zeitstempel (ms), als diese Statistiken erfasst wurden.
Abonnenten-Videostatistik (stats.video)
Diese Felder beschreiben die Echtzeit-Videoempfangs- und Dekodierleistung des Teilnehmers:
bytesReceived- Insgesamt empfangene Video-Bytes.packetsLost- Gesamtzahl der Videopakete, die den Teilnehmer nicht erreicht haben.packetsReceived- Insgesamt empfangene Videopakete.timestamp- Unix-Zeitstempel (ms), als die Statistiken erfasst wurden.decodedFrameRate- Tatsächliche vom Decoder erzeugte Bildrate (fps).bitrate- Bitrate der Nutzdaten in Bits pro Sekunde.totalBitrate- Bitrate einschließlich RTP-Header und Padding (bps).codec- Für diesen Teilnehmer verwendeter Codec.pauseCount- Numbers of pauses where no frame was rendered for ≥5 seconds.totalPausesDuration- Kumulative Dauer (ms) aller Pausen.freezeCount- Numbers of short freezes (aus der WebRTC-Statistikdefinition).totalFreezesDuration- Kumulative Dauer (ms) aller Einfrierungen.
Teilnehmerseitige Schätzung auf der Absenderseite (stats.senderStats)
Diese Metriken liefern Bandbreitenschätzungen, die für die abgehende Verbindung des Absenders gemeldet werden:
connectionMaxAllocatedBitrate- Geschätzte maximale zugewiesene Bitrate für den Absender (bps).connectionEstimatedBandwidth- Aktuelle geschätzte Uplink-Bandbreite für den Absender (bps).
Statistik auf der Absenderseite
Siehe die Übersicht der Absenderstatistiken.
Aktivieren von Statistiken auf der Absenderseite
Senderstatistiken werden von den Abonnenten empfangen. Um absenderseitige Statistiken zu erhalten, aktivieren Sie sie für den Herausgeber des Streams, indem Sie die publishSenderStats Eigenschaft eingestellt auf true im OT.initPublisher anrufen:
const publisher = OT.initPublisher({
publishSenderStats: true
});
Wenn publishSenderStats nicht aktiviert ist, wird kein Absenderstatistikkanal für diesen Verlag veröffentlicht. Der Standardwert ist false.
Abonnieren von Statistiken auf der Absenderseite
Abonnenten erhalten nur dann automatisch Absenderstatistiken, wenn der Herausgeber diese aktiviert hat und wenn der Benutzer die Subscriber.getStats() mindestens einmal. Beachten Sie, dass aufgrund der Netzwerklatenz der erste Aufruf von getStats enthält möglicherweise keine Absenderstatistiken. Bei späteren Aufrufen ist es wahrscheinlicher, dass diese Daten zurückgegeben werden.
Es sind keine zusätzlichen Ereignisse oder Methoden erforderlich; die Absenderstatistiken sind in den bestehenden stats Objekt zurückgegeben von getStats().
Empfang von Statistikereignissen
Absenderstatistiken sind als optionales Element enthalten senderStats Objekt innerhalb der stats Objekt, das an die Subscriber.getStats() Rückruf. Die senderStats Objekt enthält zwei Eigenschaften:
connectionMaxAllocatedBitrate- Die maximale Bitrate, die für die Verbindung geschätzt werden kann (in Bits pro Sekunde)connectionEstimatedBandwidth- Die aktuell geschätzte Bandbreite für die Verbindung (in Bits pro Sekunde)
Diese beiden Metriken werden pro Audio-Video-Bündel berechnet, so dass sowohl in der Video- als auch in der Audiostatistik die gleichen Werte erscheinen. Da sie den Transport und nicht einzelne Tracks widerspiegeln, werden die Metriken sowohl für Audio als auch für Video verwendet.
subscriber.getStats((stats) => {
if (stats.senderStats) {
console.log(`Connection max allocated bitrate: ${stats.senderStats.connectionMaxAllocatedBitrate} bps`);
console.log(`Connection current estimated bandwidth: ${stats.senderStats.connectionEstimatedBandwidth} bps`);
} else {
console.log("Sender stats not available yet.");
}
});
Bekannte Probleme
In einigen Fällen, wenn die Sitzung weitergeleitet wird - oder in bestimmten gerouteten Setups mit nur zwei Teilnehmern - und der Publisher Firefox verwendet, sind aufgrund von Browsereinschränkungen möglicherweise keine absenderseitigen Statistiken verfügbar.
RTC-Statistikbericht
Um Low-Level-Peer-Verbindungsstatistiken für einen Publisher zu erhalten, verwenden Sie die Publisher.getRtcStatsReport() Methode. Sie gibt ein Versprechen zurück, das im Erfolgsfall mit einer RtcStatsReport Objekt für den abonnierten Stream:
publisher.getRtcStatsReport()
.then((stats) => stats.forEach(console.log))
.catch(console.log);
Um Low-Level-Peer-Verbindungsstatistiken für einen Teilnehmer zu erhalten, verwenden Sie die Subscriber.getRtcStatsReport() Methode. Sie gibt ein Versprechen zurück, das im Erfolgsfall mit einer RtcStatsReport Objekt für den abonnierten Stream:
subscriber.getRtcStatsReport()
.then((stats) => stats.forEach(console.log))
.catch(console.log);