Start · Sprachen · JavaScript · Referenz · RTCInboundRtpStreamStats.jitterBufferTargetDelay

RTCInboundRtpStreamStats.jitterBufferTargetDelay

Eigenschaft

Aufsummierte Zielverzögerung des Jitter-Puffers in Sekunden für alle ausgegebenen Samples bzw. Frames eines eingehenden RTP-Streams.

seit JavaScript WebRTC Statistics (W3C); Chromium-Browser, Unterst Kategorie: webapi

Signatur

RTCInboundRtpStreamStats.jitterBufferTargetDelay

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

Typ
number
Beschreibung
Eine Gleitkommazahl (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);
audio: durchschnittliche Zielverzögerung 62.4 ms video: durchschnittliche Zielverzögerung 85.0 ms

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);
audio: Ziel aktuell 58.3 ms audio: Ziel aktuell 71.9 ms

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);
┌──────────────┬─────────┐ │ ziel │ '198.7' │ │ tatsaechlich │ '204.2' │ │ minimum │ '198.7' │ └──────────────┴─────────┘

// 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.jitterBufferTarget dagegen in Millisekunden. Beim Vergleich muss man umrechnen.
  • Division durch null: Solange noch nichts ausgegeben wurde, ist jitterBufferEmittedCount gleich 0. Das vorher prüfen, sonst ist das Ergebnis NaN.
  • 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 undefined prü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 jitterBufferDelay aus.
  • Die Statistiken per setInterval nicht zu oft abfragen. Ein Intervall von etwa einer Sekunde reicht meist aus, denn getStats() ist nicht kostenlos.