Signatur
Beschreibung
Die schreibgeschützte Eigenschaft jitterBufferTargetDelay eines RTCInboundRtpStreamStats-Objekts (Typ "inbound-rtp") ist ein kumulativer Wert in Sekunden. Jedes Mal, wenn der Jitter-Puffer ein Audio-Sample oder einen Video-Frame ausgibt, wird die in diesem Moment angestrebte Pufferverzögerung (die Zielverzögerung) aufaddiert. Gleichzeitig steigt jitterBufferEmittedCount um die Anzahl der ausgegebenen Samples bzw. Frames.
Die Zielverzögerung legt der Empfänger selbst fest. Sie hängt vom gemessenen Netzwerk-Jitter ab, von der Mindestverzögerung (jitterBufferMinimumDelay) und von einem Wunschwert, den die Anwendung über RTCRtpReceiver.jitterBufferTarget vorgeben kann. Einzeln ist der Wert wenig aussagekräftig. Brauchbar wird er erst, wenn man ihn durch jitterBufferEmittedCount teilt: Das Ergebnis ist die durchschnittliche Zielverzögerung pro Sample bzw. Frame.
In der Praxis vergleicht man die Zielverzögerung mit der tatsächlichen Verzögerung (jitterBufferDelay / jitterBufferEmittedCount). Liegt die tatsächliche Verzögerung deutlich über dem Ziel, baut der Puffer gerade Verzögerung ab. Liegt sie darunter, wird er gerade aufgefüllt. So lässt sich erkennen, wie der Empfänger bei einem Videoanruf oder Livestream zwischen Latenz und flüssiger Wiedergabe abwägt.
Rückgabewert
double): die aufsummierte Zielverzögerung aller bisher ausgegebenen Samples bzw. Frames in Sekunden. Fehlt die Eigenschaft, wird sie vom Browser nicht unterstützt oder es wurde noch nichts ausgegeben.Beispiele
Durchschnittliche Zielverzögerung auslesen
// pc ist eine bestehende, verbundene RTCPeerConnection
const logTargetDelay = async (pc) => {
const stats = await pc.getStats();
stats.forEach((report) => {
if (report.type !== 'inbound-rtp') return;
const { kind, jitterBufferTargetDelay, jitterBufferEmittedCount } = report;
if (jitterBufferTargetDelay === undefined || !jitterBufferEmittedCount) return;
const avgMs = (jitterBufferTargetDelay / jitterBufferEmittedCount) * 1000;
console.log(`${kind}: durchschnittliche Zielverzögerung ${avgMs.toFixed(1)} ms`);
});
};
await logTargetDelay(pc);
Aktuelle Zielverzögerung aus der Differenz zweier Messungen
// Kumulative Werte → Differenz zwischen zwei Abfragen bildet den aktuellen Zustand ab
const previous = new Map();
const sampleTargetDelay = async (pc) => {
const stats = await pc.getStats();
for (const report of stats.values()) {
if (report.type !== 'inbound-rtp' || report.jitterBufferTargetDelay === undefined) continue;
const prev = previous.get(report.id);
if (prev) {
const dDelay = report.jitterBufferTargetDelay - prev.jitterBufferTargetDelay;
const dCount = report.jitterBufferEmittedCount - prev.jitterBufferEmittedCount;
if (dCount > 0) {
console.log(`${report.kind}: Ziel aktuell ${((dDelay / dCount) * 1000).toFixed(1)} ms`);
}
}
previous.set(report.id, report);
}
};
const timer = setInterval(() => sampleTargetDelay(pc), 1000);
// später: clearInterval(timer);
Zielverzögerung mit tatsächlicher Verzögerung vergleichen
const compareDelays = async (receiver) => {
// getStats() am RTCRtpReceiver liefert nur die Statistiken dieses Empfängers
const stats = await receiver.getStats();
for (const r of stats.values()) {
if (r.type !== 'inbound-rtp' || !r.jitterBufferEmittedCount) continue;
const target = (r.jitterBufferTargetDelay / r.jitterBufferEmittedCount) * 1000;
const actual = (r.jitterBufferDelay / r.jitterBufferEmittedCount) * 1000;
const minimum = (r.jitterBufferMinimumDelay / r.jitterBufferEmittedCount) * 1000;
console.table({ ziel: target.toFixed(1), tatsaechlich: actual.toFixed(1), minimum: minimum.toFixed(1) });
}
};
// Wunschwert für den Puffer setzen (Millisekunden) und danach auswerten
const [videoReceiver] = pc.getReceivers().filter((r) => r.track.kind === 'video');
videoReceiver.jitterBufferTarget = 200;
setTimeout(() => compareDelays(videoReceiver), 5000);
// Wichtig · Fallstricke
- Kumulativer Wert: Der Wert wächst mit der Zeit immer weiter und wird nicht zurückgesetzt. Sinnvoll auswerten lässt er sich nur zusammen mit
jitterBufferEmittedCount, entweder als Gesamtdurchschnitt oder als Differenz zwischen zwei Messungen. - Einheit: Die Statistik zählt in Sekunden,
RTCRtpReceiver.jitterBufferTargetdagegen in Millisekunden. Beim Vergleich muss man umrechnen. - Division durch null: Solange noch nichts ausgegeben wurde, ist
jitterBufferEmittedCountgleich0. Das vorher prüfen, sonst ist das ErgebnisNaN. - Browser-Kompatibilität: Die Eigenschaft gehört zu den neueren Einträgen der WebRTC-Statistik-Spezifikation und ist vor allem in Chromium-Browsern verfügbar. In anderen Engines kann sie fehlen. Deshalb vor der Nutzung auf
undefinedprüfen. - Die Zielverzögerung ist das, was der Empfänger anstrebt, nicht die tatsächliche Verzögerung. Für die tatsächliche Pufferverzögerung wertet man
jitterBufferDelayaus. - Die Statistiken per
setIntervalnicht zu oft abfragen. Ein Intervall von etwa einer Sekunde reicht meist aus, denngetStats()ist nicht kostenlos.