Signatur
Beschreibung
Die Eigenschaft totalProcessingDelay des Wörterbuchs RTCInboundRtpStreamStats ist ein kumulativer Zähler (Gleitkommazahl in Sekunden). Für jedes decodierte Audiosample und jeden decodierten Videoframe wird die Zeit vom Empfangszeitpunkt bis zum Decodierzeitpunkt addiert. Der Empfangszeitpunkt wird so nah wie möglich an der Netzwerkschicht gemessen. Bei Video gilt der Zeitstempel des frühesten RTP-Pakets, das zum Frame gehört.
Der Wert steigt während einer Verbindung ständig an. Für sich allein sagt er daher wenig aus. Brauchbar wird er erst, wenn man ihn durch die Zahl der verarbeiteten Einheiten teilt: bei Video durch framesDecoded, bei Audio durch totalSamplesDecoded. Heraus kommt die durchschnittliche Verarbeitungsverzögerung. Diese Kennzahl enthält die Wartezeit im Jitter-Buffer und die Decodierzeit. Damit eignet sie sich gut, um Latenzprobleme auf der Empfängerseite zu finden.
Du fragst den Wert über RTCPeerConnection.getStats() oder RTCRtpReceiver.getStats() ab. Dort filterst du die Einträge mit type === "inbound-rtp". Wenn du die Werte zweier Abfragen voneinander abziehst, erhältst du die durchschnittliche Verzögerung in einem bestimmten Zeitraum.
Rückgabewert
double: die bisher insgesamt angesammelte Verarbeitungszeit in Sekunden. Der Wert kann undefined sein, wenn der Browser die Kennzahl nicht unterstützt.Beispiele
Durchschnittliche Verarbeitungsverzögerung für Video berechnen
// pc ist eine bereits verbundene RTCPeerConnection
const logeVideoVerzoegerung = async (pc) => {
const stats = await pc.getStats();
stats.forEach((report) => {
if (report.type === 'inbound-rtp' && report.kind === 'video') {
const { totalProcessingDelay, framesDecoded } = report;
if (totalProcessingDelay !== undefined && framesDecoded > 0) {
const avgMs = (totalProcessingDelay / framesDecoded) * 1000;
console.log(`Ø Verarbeitungsverzögerung: ${avgMs.toFixed(1)} ms`);
}
}
});
};
await logeVideoVerzoegerung(pc);
Verzögerung pro Intervall über zwei Messungen (Delta)
// Misst jede Sekunde die durchschnittliche Verzögerung im letzten Intervall
const ueberwacheReceiver = (receiver) => {
let vorher = null;
return setInterval(async () => {
const stats = await receiver.getStats();
for (const report of stats.values()) {
if (report.type !== 'inbound-rtp') continue;
if (vorher) {
const deltaDelay = report.totalProcessingDelay - vorher.totalProcessingDelay;
const deltaFrames = report.framesDecoded - vorher.framesDecoded;
if (deltaFrames > 0) {
console.log(`Letzte Sekunde: ${(deltaDelay / deltaFrames * 1000).toFixed(1)} ms/Frame`);
}
}
vorher = report;
}
}, 1000);
};
const [videoReceiver] = pc.getReceivers().filter((r) => r.track.kind === 'video');
const timerId = ueberwacheReceiver(videoReceiver);
// später: clearInterval(timerId);
Audio: Verzögerung pro Sample
const audioVerzoegerung = async (pc) => {
const stats = await pc.getStats();
for (const r of stats.values()) {
if (r.type === 'inbound-rtp' && r.kind === 'audio' && r.totalSamplesDecoded) {
return (r.totalProcessingDelay / r.totalSamplesDecoded) * 1000;
}
}
return null;
};
console.log(`Audio: ${(await audioVerzoegerung(pc))?.toFixed(2)} ms`);
// Wichtig · Fallstricke
- Kumulativer Zähler: Der Rohwert wächst ständig weiter. Aussagekräftig ist er nur, wenn du ihn durch
framesDecoded(Video) bzw.totalSamplesDecoded(Audio) teilst oder die Differenz zwischen zwei Messungen bildest. - Nur erfolgreich decodierte Frames zählen mit. Verworfene Frames (
framesDropped) und Frames, deren Decodierung fehlschlägt, erhöhen den Wert nicht. - Die Einheit ist Sekunden, nicht Millisekunden. Für die Anzeige musst du mit 1000 multiplizieren.
- Kompatibilität: Chromium-basierte Browser (Chrome, Edge) unterstützen die Eigenschaft. In Firefox und Safari kann sie fehlen. Prüfe den Wert deshalb immer auf
undefined, bevor du damit rechnest. - Seit dem Wegfall von
track-Statistiken istinbound-rtpder richtige Ort für diese Kennzahl. Ältere Beispiele greifen teils noch auf veraltete Statistiktypen zu.