Start · Sprachen · JavaScript · Referenz · RTCInboundRtpStreamStats.jitterBufferMinimumDelay

RTCInboundRtpStreamStats.jitterBufferMinimumDelay

Eigenschaft

Summe (in Sekunden) der minimal erreichbaren Jitter-Puffer-Verzögerungen aller ausgegebenen Samples. Berücksichtigt nur Netzwerkeinflüsse wie Jitter und Paketverlust.

seit JavaScript WebRTC Statistics API: Chromium-Browser; in andere Kategorie: webapi

Signatur

RTCInboundRtpStreamStats.jitterBufferMinimumDelay

Beschreibung

Die schreibgeschützte Eigenschaft jitterBufferMinimumDelay eines RTCInboundRtpStreamStats-Objekts (Statistiktyp "inbound-rtp") ist ein kumulativer Wert in Sekunden. Jedes Mal, wenn ein Audio-Sample oder Video-Frame den Jitter-Puffer verlässt, addiert der Browser die zu diesem Zeitpunkt minimal nötige Pufferverzögerung zu diesem Wert. Gleichzeitig erhöht er jitterBufferEmittedCount um eins.

„Minimal“ bedeutet: Der Wert berücksichtigt nur Netzwerkeinflüsse wie Jitter und Paketverlust. Andere Einflüsse auf die Zielverzögerung sind nicht enthalten, zum Beispiel die Audio-Video-Synchronisation (Lippensynchronität) oder ein per RTCRtpReceiver.jitterBufferTarget gesetzter Zielwert. Damit unterscheidet er sich von jitterBufferTargetDelay, in das all diese Faktoren einfließen.

Um die durchschnittliche minimale Verzögerung zu erhalten, teilt man den Wert durch jitterBufferEmittedCount. Für aktuelle Werte statt eines Mittels über die ganze Sitzung bildet man die Differenzen zwischen zwei getStats()-Aufrufen. Vergleicht man das Ergebnis mit jitterBufferTargetDelay, sieht man, wie viel zusätzliche Latenz nicht vom Netzwerk kommt, sondern etwa von der Synchronisation.

Rückgabewert

Typ
number | undefined
Beschreibung
Summe der minimalen Jitter-Puffer-Verzögerungen in Sekunden (Gleitkommazahl) über alle ausgegebenen Samples. Der Wert ist undefined, wenn der Browser die Eigenschaft nicht unterstützt.

Beispiele

Durchschnittliche minimale Pufferverzögerung auslesen

// pc ist eine verbundene RTCPeerConnection
const logMinDelay = async (pc) => {
  const stats = await pc.getStats();
  stats.forEach((report) => {
    if (report.type !== 'inbound-rtp') return;
    const { kind, jitterBufferMinimumDelay, jitterBufferEmittedCount } = report;
    if (jitterBufferMinimumDelay === undefined || !jitterBufferEmittedCount) return;
    const avgMs = (jitterBufferMinimumDelay / jitterBufferEmittedCount) * 1000;
    console.log(`${kind}: minimale Pufferverzögerung Ø ${avgMs.toFixed(1)} ms`);
  });
};

await logMinDelay(pc);
audio: minimale Pufferverzögerung Ø 42.3 ms video: minimale Pufferverzögerung Ø 61.8 ms

Aktuellen Wert per Differenz zwischen zwei Messungen berechnen

const prev = new Map();

const sampleMinDelay = async (pc) => {
  const stats = await pc.getStats();
  for (const r of stats.values()) {
    if (r.type !== 'inbound-rtp' || r.jitterBufferMinimumDelay === undefined) continue;
    const last = prev.get(r.id);
    if (last) {
      const dDelay = r.jitterBufferMinimumDelay - last.delay;
      const dCount = r.jitterBufferEmittedCount - last.count;
      if (dCount > 0) {
        console.log(`${r.kind} (letzte Sekunde): ${(dDelay / dCount * 1000).toFixed(1)} ms`);
      }
    }
    prev.set(r.id, { delay: r.jitterBufferMinimumDelay, count: r.jitterBufferEmittedCount });
  }
};

const timer = setInterval(() => sampleMinDelay(pc), 1000);
// später: clearInterval(timer);
audio (letzte Sekunde): 38.9 ms

Nicht netzwerkbedingte Zusatzverzögerung ermitteln

const analyzeDelay = async (pc) => {
  const stats = await pc.getStats();
  for (const r of stats.values()) {
    if (r.type !== 'inbound-rtp' || !r.jitterBufferEmittedCount) continue;
    const n = r.jitterBufferEmittedCount;
    const minMs = (r.jitterBufferMinimumDelay / n) * 1000;
    const targetMs = (r.jitterBufferTargetDelay / n) * 1000;
    const actualMs = (r.jitterBufferDelay / n) * 1000;
    console.table({
      kind: r.kind,
      minimal: minMs.toFixed(1),
      ziel: targetMs.toFixed(1),
      tatsaechlich: actualMs.toFixed(1),
      zusatzDurchSync: (targetMs - minMs).toFixed(1)
    });
  }
};

await analyzeDelay(pc);
kind: video, minimal: 60.2, ziel: 95.0, tatsaechlich: 97.4, zusatzDurchSync: 34.8

// Wichtig · Fallstricke

  • Kumulativ, nicht momentan: Der Wert ist eine laufende Summe in Sekunden. Allein ist er nicht aussagekräftig. Teile ihn immer durch jitterBufferEmittedCount oder bilde Differenzen zwischen zwei Messungen.
  • Einheit: Sekunden, nicht Millisekunden. Für die Anzeige mit 1000 multiplizieren.
  • Division durch null: Solange noch keine Samples ausgegeben wurden, ist jitterBufferEmittedCount gleich 0. Das vorher prüfen, sonst entsteht NaN.
  • Abgrenzung: jitterBufferDelay ist die tatsächliche Verzögerung, jitterBufferTargetDelay die angestrebte (inklusive Synchronisation und jitterBufferTarget). jitterBufferMinimumDelay ist die rein netzwerkbedingte Untergrenze.
  • Kompatibilität: Die Eigenschaft wird vor allem von Chromium-basierten Browsern geliefert. In Firefox und Safari kann sie fehlen. Deshalb vor der Nutzung auf undefined prüfen.
  • Nach einem Neustart des Streams (neue SSRC) beginnt ein neues inbound-rtp-Objekt mit eigener id. Zwischengespeicherte Vergleichswerte müssen deshalb pro id geführt werden.