Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.totalPacketSendDelay

RTCOutboundRtpStreamStats.totalPacketSendDelay

Eigenschaft

Gesamtzeit in Sekunden, die alle gesendeten RTP-Pakete eines ausgehenden Streams lokal gepuffert wurden, bevor sie übertragen wurden.

seit JavaScript Nicht Baseline: Chromium-Browser und Safari; Firef Kategorie: webapi

Signatur

RTCOutboundRtpStreamStats.totalPacketSendDelay

Beschreibung

Die Eigenschaft totalPacketSendDelay gehört zum Statistik-Wörterbuch RTCOutboundRtpStreamStats, also zu den Einträgen mit type === "outbound-rtp", die RTCPeerConnection.getStats() oder RTCRtpSender.getStats() liefern. Der Wert ist eine Gleitkommazahl in Sekunden. Für jedes gesendete Paket wird die Zeit addiert, die zwischen der Erzeugung durch den RTP-Packetizer und der Übergabe an den Netzwerk-Socket des Betriebssystems vergangen ist.

Ein einzelner Wert sagt wenig aus, weil er über die gesamte Lebensdauer des Streams wächst. Hilfreich wird er erst, wenn man ihn durch packetsSent teilt. Das ergibt die durchschnittliche Sendeverzögerung pro Paket. Noch genauer ist die Differenz zweier Messungen: Δ totalPacketSendDelay / Δ packetsSent zeigt die aktuelle Verzögerung im jeweiligen Zeitfenster.

Typische Einsätze sind die Fehlersuche bei Latenz und die Überwachung des Pacers bzw. der Staukontrolle. Steigt die lokale Pufferzeit, erzeugt der Encoder in der Regel mehr Daten, als die geschätzte Bandbreite zulässt. Dann lohnt es sich, Bitrate oder Auflösung zu senken, zum Beispiel über RTCRtpSender.setParameters().

Rückgabewert

Typ
number | undefined
Beschreibung
Kumulierte Pufferzeit aller bisher gesendeten Pakete in Sekunden als Gleitkommazahl. Der Wert ist undefined, wenn der Browser die Kennzahl nicht erhebt.

Beispiele

Durchschnittliche Sendeverzögerung pro Paket ermitteln

// pc ist eine bestehende, verbundene RTCPeerConnection
const logSendDelay = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type !== 'outbound-rtp' || stats.packetsSent === 0) return;
    if (stats.totalPacketSendDelay === undefined) {
      console.log(`${stats.kind}: totalPacketSendDelay nicht unterstützt`);
      return;
    }
    const avgMs = (stats.totalPacketSendDelay / stats.packetsSent) * 1000;
    console.log(`${stats.kind}: Ø ${avgMs.toFixed(2)} ms lokale Pufferzeit`);
  });
};

await logSendDelay(pc);
video: Ø 4.37 ms lokale Pufferzeit audio: Ø 0.12 ms lokale Pufferzeit

Aktuelle Verzögerung im Intervall überwachen (Differenzen)

const monitorSendDelay = (sender, intervalMs = 2000) => {
  let prev = null;
  return setInterval(async () => {
    const report = await sender.getStats();
    for (const stats of report.values()) {
      if (stats.type !== 'outbound-rtp') continue;
      if (prev) {
        const dPackets = stats.packetsSent - prev.packetsSent;
        const dDelay = stats.totalPacketSendDelay - prev.totalPacketSendDelay;
        if (dPackets > 0) {
          const ms = (dDelay / dPackets) * 1000;
          console.log(`Aktuell: ${ms.toFixed(1)} ms pro Paket`);
          if (ms > 50) console.warn('Pacer staut – Bitrate reduzieren?');
        }
      }
      prev = stats;
    }
  }, intervalMs);
};

const [videoSender] = pc.getSenders().filter((s) => s.track?.kind === 'video');
const timerId = monitorSendDelay(videoSender);
// später: clearInterval(timerId);
Aktuell: 3.8 ms pro Paket Aktuell: 62.4 ms pro Paket Pacer staut – Bitrate reduzieren?

Bei hoher Verzögerung die Bitrate automatisch senken

const adaptBitrate = async (sender, avgDelayMs) => {
  if (avgDelayMs < 50) return;
  const params = sender.getParameters();
  if (!params.encodings?.length) return;
  const current = params.encodings[0].maxBitrate ?? 2_500_000;
  params.encodings[0].maxBitrate = Math.round(current * 0.8);
  await sender.setParameters(params);
  console.log(`maxBitrate gesenkt auf ${params.encodings[0].maxBitrate} bit/s`);
};

await adaptBitrate(videoSender, 75);
maxBitrate gesenkt auf 2000000 bit/s

// Wichtig · Fallstricke

  • Einheit Sekunden: Der Wert wird in Sekunden angegeben, nicht in Millisekunden. Für eine lesbare Anzeige mit 1000 multiplizieren.
  • Kumulierter Wert: Der Wert wächst über die gesamte Lebensdauer des Streams. Für aktuelle Aussagen immer Differenzen zwischen zwei Messungen bilden und durch die Differenz von packetsSent teilen.
  • Nur die lokale Verzögerung: Gemessen wird nur die Zeit bis zur Übergabe an den Socket. Netzwerklaufzeit, Jitter und Verzögerungen beim Empfänger sind nicht enthalten. Dafür gibt es roundTripTime und die Werte von RTCRemoteInboundRtpStreamStats.
  • Browser-Kompatibilität: Chromium-basierte Browser und Safari unterstützen die Eigenschaft. In Firefox fehlt sie je nach Version. Den Wert daher vor der Verwendung auf undefined prüfen.
  • Wenn packetsSent den Wert 0 hat, führt die Division zu NaN oder Infinity. Diesen Fall abfangen.
  • Abfrage-Intervall: getStats() ist asynchron und nicht kostenlos. Ein Abfrage-Intervall unter etwa einer Sekunde bringt kaum Nutzen.