Signatur
Beschreibung
Die Eigenschaft jitterBufferDelay eines RTCInboundRtpStreamStats-Objekts (Typ "inbound-rtp") ist ein fortlaufend steigender Zähler vom Typ number in Sekunden. Für jedes Audio-Sample bzw. jeden vollständigen Video-Frame, der den Jitter-Puffer verlässt, wird die Zeit zwischen dem Eintreffen des ersten zugehörigen RTP-Pakets und der Ausgabe aus dem Puffer (Weitergabe an Decoder bzw. Wiedergabe) aufaddiert.
Der Jitter-Puffer gleicht schwankende Paketlaufzeiten im Netz aus, indem er Daten kurz zurückhält. Das sorgt für flüssige Wiedergabe, kostet aber Latenz. Mit jitterBufferDelay lässt sich messen, wie viel zusätzliche Verzögerung dadurch auf der Empfängerseite entsteht – nützlich für Qualitäts-Dashboards, Latenzanalysen und das Erkennen instabiler Netzverbindungen.
Da der Wert kumuliert ist, sagt er allein wenig aus. Die durchschnittliche Pufferverzögerung erhält man, indem man ihn durch jitterBufferEmittedCount teilt. Für die Verzögerung in einem bestimmten Zeitraum bildet man die Differenzen beider Zähler zwischen zwei getStats()-Abfragen.
Rückgabewert
undefined sein, wenn der Browser den Wert nicht liefert.Beispiele
Durchschnittliche Jitter-Puffer-Verzögerung auslesen
// pc ist eine verbundene RTCPeerConnection
const logJitterBuffer = async (pc) => {
const stats = await pc.getStats();
stats.forEach((report) => {
if (report.type !== 'inbound-rtp') return;
const { kind, jitterBufferDelay, jitterBufferEmittedCount } = report;
if (!jitterBufferEmittedCount) return;
const avgMs = (jitterBufferDelay / jitterBufferEmittedCount) * 1000;
console.log(`${kind}: Ø ${avgMs.toFixed(1)} ms im Jitter-Puffer`);
});
};
await logJitterBuffer(pc);
Aktuelle Verzögerung per Intervall-Differenz messen
// Mittelwert nur über die letzten 2 Sekunden statt seit Verbindungsbeginn
const previous = new Map();
const sampleJitter = async (pc) => {
const stats = await pc.getStats();
for (const report of stats.values()) {
if (report.type !== 'inbound-rtp') continue;
const prev = previous.get(report.id);
if (prev) {
const deltaDelay = report.jitterBufferDelay - prev.jitterBufferDelay;
const deltaCount = report.jitterBufferEmittedCount - prev.jitterBufferEmittedCount;
if (deltaCount > 0) {
const ms = (deltaDelay / deltaCount) * 1000;
console.log(`${report.kind} (aktuell): ${ms.toFixed(1)} ms`);
}
}
previous.set(report.id, {
jitterBufferDelay: report.jitterBufferDelay,
jitterBufferEmittedCount: report.jitterBufferEmittedCount,
});
}
};
const timer = setInterval(() => sampleJitter(pc), 2000);
// Später: clearInterval(timer);
Warnung bei hoher Puffer-Latenz für einen Empfänger
const checkReceiver = async (receiver, limitMs = 150) => {
const stats = await receiver.getStats();
const inbound = [...stats.values()].find((r) => r.type === 'inbound-rtp');
if (!inbound?.jitterBufferEmittedCount) return;
const avgMs = (inbound.jitterBufferDelay / inbound.jitterBufferEmittedCount) * 1000;
if (avgMs > limitMs) {
console.warn(`Hohe Puffer-Latenz (${Math.round(avgMs)} ms) – Netz instabil?`);
}
};
const [audioReceiver] = pc.getReceivers().filter((r) => r.track.kind === 'audio');
await checkReceiver(audioReceiver);
// Wichtig · Fallstricke
- Einheit Sekunden: Der Wert ist in Sekunden angegeben, nicht in Millisekunden – für Anzeigen mit 1000 multiplizieren.
- Kumulativer Zähler: Der Wert wächst über die gesamte Lebensdauer des Streams. Ohne Division durch
jitterBufferEmittedCount(oder Differenzbildung zwischen Abfragen) ist er nicht als Latenz interpretierbar. - Division durch null vermeiden: Direkt nach dem Verbindungsaufbau ist
jitterBufferEmittedCountoft0. - Audio vs. Video: Bei Audio wird pro Sample gezählt (nicht pro Paket), bei Video pro vollständigem Frame. Werte beider Medienarten sind daher nicht direkt vergleichbar.
- Nicht die Gesamtlatenz: Netzlaufzeit (siehe
roundTripTimeimremote-inbound-rtp-Bericht), Dekodierung und Rendering sind nicht enthalten. - Kompatibilität: Von Chromium-Browsern, Firefox und Safari unterstützt; ältere Versionen liefern den Wert teils nur für Audio oder gar nicht. Immer auf
undefinedprüfen. BeiRTCPeerConnection.getStats()gibt es den Bericht nur, wenn tatsächlich Daten empfangen werden.