Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.retransmittedBytesSent

RTCOutboundRtpStreamStats.retransmittedBytesSent

Eigenschaft

Gesamtzahl der Nutzlast-Bytes, die für diesen ausgehenden RTP-Stream erneut gesendet wurden (Retransmissions, z. B. per RTX nach NACK).

seit JavaScript Chrome 107+, Edge 107+, Safari 17+; Firefox: nicht Kategorie: webapi

Signatur

RTCOutboundRtpStreamStats.retransmittedBytesSent

Beschreibung

Die Eigenschaft retransmittedBytesSent eines RTCOutboundRtpStreamStats-Objekts gibt an, wie viele Nutzlast-Bytes (ohne RTP-Header und Padding) für die mit diesem Stream verknüpfte SSRC bisher erneut übertragen wurden. Retransmissions entstehen typischerweise, wenn der Empfänger per RTCP-NACK verlorene Pakete anfordert und der Sender sie über einen RTX-Stream oder dieselbe SSRC neu sendet.

Der Wert ist eine Teilmenge von bytesSent: Die erneut gesendeten Bytes werden auch dort mitgezählt. Das Verhältnis retransmittedBytesSent / bytesSent ist deshalb eine gute Kennzahl dafür, wie viel Bandbreite durch Paketverlust „verschwendet“ wird. Zusammen mit retransmittedPacketsSent lässt sich die Qualität der Netzwerkverbindung aus Sicht des Senders beurteilen.

Man erhält das Objekt über RTCPeerConnection.getStats() oder RTCRtpSender.getStats(); relevant sind die Einträge mit type === "outbound-rtp". Da es sich um einen kumulativen Zähler handelt, muss man für Raten (z. B. Bytes pro Sekunde) die Differenz zwischen zwei Messungen durch die Differenz der timestamp-Werte teilen.

Rückgabewert

Typ
number | undefined
Beschreibung
Nicht negative Ganzzahl (unsigned long long) mit der kumulativen Anzahl erneut gesendeter Nutzlast-Bytes seit Beginn des Streams. undefined, wenn der Browser die Kennzahl nicht liefert (z. B. keine RTX-Aushandlung oder fehlende Unterstützung).

Beispiele

Retransmissions aller ausgehenden Streams auslesen

const logRetransmissions = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === "outbound-rtp") {
      console.log(
        `${stats.kind} (SSRC ${stats.ssrc}): ` +
        `${stats.retransmittedBytesSent ?? 0} von ${stats.bytesSent} Bytes erneut gesendet`
      );
    }
  });
};

// pc ist eine verbundene RTCPeerConnection
await logRetransmissions(pc);
video (SSRC 1234567890): 48210 von 2150000 Bytes erneut gesendet

Retransmission-Anteil pro Sender berechnen

const retransmissionRatio = async (sender) => {
  const report = await sender.getStats();
  for (const stats of report.values()) {
    if (stats.type === "outbound-rtp" && stats.bytesSent > 0) {
      const ratio = (stats.retransmittedBytesSent ?? 0) / stats.bytesSent;
      return Math.round(ratio * 10000) / 100; // Prozent, 2 Nachkommastellen
    }
  }
  return null;
};

const [videoSender] = pc.getSenders().filter((s) => s.track?.kind === "video");
console.log(`Retransmission-Anteil: ${await retransmissionRatio(videoSender)} %`);
Retransmission-Anteil: 2.24 %

Retransmission-Rate in kbit/s überwachen

const monitorRetransmitRate = (sender, intervalMs = 2000) => {
  let previous = null;
  return setInterval(async () => {
    const report = await sender.getStats();
    const stats = [...report.values()].find((s) => s.type === "outbound-rtp");
    if (!stats || stats.retransmittedBytesSent === undefined) return;

    if (previous) {
      const bytes = stats.retransmittedBytesSent - previous.retransmittedBytesSent;
      const seconds = (stats.timestamp - previous.timestamp) / 1000;
      const kbps = (bytes * 8) / 1000 / seconds;
      console.log(`Retransmissions: ${kbps.toFixed(1)} kbit/s`);
      if (kbps > 100) console.warn("Hoher Paketverlust – Bitrate reduzieren?");
    }
    previous = stats;
  }, intervalMs);
};

const timer = monitorRetransmitRate(pc.getSenders()[0]);
// später: clearInterval(timer);
Retransmissions: 12.4 kbit/s

// Wichtig · Fallstricke

  • Kumulativer Zähler: Der Wert wächst nur an. Für Raten immer die Differenz zweier Messungen bilden und durch die timestamp-Differenz (Millisekunden) teilen.
  • Teilmenge von bytesSent: Nicht zu bytesSent addieren – die Bytes sind dort bereits enthalten. Header- und Padding-Bytes sind in beiden Werten nicht enthalten (siehe headerBytesSent).
  • Nur bei aktiver Retransmission: Ohne ausgehandeltes RTX bzw. NACK-Unterstützung (bei Audio meist der Fall) bleibt der Wert 0 oder fehlt ganz. Defensiv mit ?? 0 auslesen.
  • Browser-Kompatibilität: Unterstützt in Chromium-basierten Browsern und Safari; Firefox liefert die Eigenschaft derzeit nicht. Vor der Nutzung auf undefined prüfen.
  • Bei Simulcast gibt es pro Layer (rid) einen eigenen outbound-rtp-Eintrag – für Gesamtwerte die Einträge aufsummieren.