Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.retransmittedPacketsSent

RTCOutboundRtpStreamStats.retransmittedPacketsSent

Eigenschaft

Gibt die Gesamtzahl der RTP-Pakete an, die für die Quelle (SSRC) dieses ausgehenden Streams erneut übertragen wurden.

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

Signatur

RTCOutboundRtpStreamStats.retransmittedPacketsSent

Beschreibung

Die Eigenschaft retransmittedPacketsSent eines RTCOutboundRtpStreamStats-Objekts ist ein Zähler (nicht negative Ganzzahl). Er gibt an, wie viele Pakete der Sender für diesen RTP-Stream seit Beginn der Verbindung erneut übertragen hat. Solche Neuübertragungen entstehen meist als Antwort auf NACK-Meldungen (Negative Acknowledgement) der Gegenseite, wenn dort Pakete verloren gegangen sind.

Neu übertragene Pakete laufen entweder über einen eigenen RTX-Stream (siehe rtxSsrc) oder über dieselbe SSRC. In beiden Fällen werden sie diesem Stream zugerechnet. Außerdem sind sie auch in packetsSent enthalten. Das Verhältnis retransmittedPacketsSent / packetsSent zeigt also, welcher Anteil des gesendeten Verkehrs aus Neuübertragungen besteht.

Den Wert erhältst du über RTCPeerConnection.getStats() oder RTCRtpSender.getStats(), indem du Einträge mit type === "outbound-rtp" auswählst. Er eignet sich gut für Qualitätsmonitoring: Steigen die Neuübertragungen, ist das Netz verlustbehaftet oder überlastet. Die Anwendung kann dann zum Beispiel Bitrate oder Auflösung senken.

Rückgabewert

Typ
number | undefined
Beschreibung
Gesamtzahl der erneut übertragenen Pakete als ganze Zahl (in der Spezifikation unsigned long long). Der Wert steigt nur an. Er ist undefined, wenn keine Neuübertragung ausgehandelt wurde oder der Browser das Feld nicht liefert.

Beispiele

Neuübertragungen aller ausgehenden Streams auslesen

// pc ist eine bestehende, verbundene RTCPeerConnection
const logRetransmissions = async (pc) => {
  const stats = await pc.getStats();
  stats.forEach((report) => {
    if (report.type === 'outbound-rtp') {
      console.log(
        `${report.kind} (SSRC ${report.ssrc}): ` +
        `${report.retransmittedPacketsSent ?? 'n/a'} von ${report.packetsSent} Paketen neu gesendet`
      );
    }
  });
};

await logRetransmissions(pc);
video (SSRC 1234567890): 42 von 18230 Paketen neu gesendet audio (SSRC 987654321): n/a von 9120 Paketen neu gesendet

Neuübertragungsrate pro Intervall überwachen

// Differenz zwischen zwei Messungen: Wie viel Prozent war zuletzt Neuübertragung?
const monitorRetransmissionRate = (sender, intervalMs = 2000) => {
  let prev = null;
  return setInterval(async () => {
    const stats = await sender.getStats();
    for (const r of stats.values()) {
      if (r.type !== 'outbound-rtp' || r.retransmittedPacketsSent === undefined) continue;
      if (prev) {
        const sent = r.packetsSent - prev.packetsSent;
        const resent = r.retransmittedPacketsSent - prev.retransmittedPacketsSent;
        const rate = sent > 0 ? (resent / sent) * 100 : 0;
        console.log(`Neuübertragungsrate: ${rate.toFixed(2)} %`);
        if (rate > 5) console.warn('Hohe Neuübertragungsrate – Bitrate reduzieren?');
      }
      prev = { packetsSent: r.packetsSent, retransmittedPacketsSent: r.retransmittedPacketsSent };
    }
  }, intervalMs);
};

const [videoSender] = pc.getSenders().filter((s) => s.track?.kind === 'video');
const timer = monitorRetransmissionRate(videoSender);
// später: clearInterval(timer);
Neuübertragungsrate: 0.35 % Neuübertragungsrate: 6.10 % Hohe Neuübertragungsrate – Bitrate reduzieren?

Mit NACKs der Gegenseite und Bytes vergleichen

const stats = await pc.getStats();
const outbound = [...stats.values()].find(
  (r) => r.type === 'outbound-rtp' && r.kind === 'video'
);

if (outbound) {
  const { nackCount = 0, retransmittedPacketsSent = 0, retransmittedBytesSent = 0 } = outbound;
  console.log(`Empfangene NACKs: ${nackCount}`);
  console.log(`Neu gesendete Pakete: ${retransmittedPacketsSent}`);
  console.log(`Neu gesendete Bytes: ${retransmittedBytesSent}`);
}
Empfangene NACKs: 37 Neu gesendete Pakete: 42 Neu gesendete Bytes: 48710

// Wichtig · Fallstricke

  • Kumulativer Zähler: Der Wert zählt seit Beginn des Streams immer weiter. Aussagen über die aktuelle Netzqualität bekommst du nur über die Differenz zwischen zwei Messungen.
  • In packetsSent enthalten: Neu übertragene Pakete werden auch in packetsSent gezählt. Wer „Nutzpakete“ berechnen will, muss sie abziehen.
  • Nicht immer vorhanden: Das Feld fehlt, wenn keine Neuübertragung ausgehandelt wurde (kein NACK/RTX im SDP). Das betrifft vor allem Audio-Streams, bei denen Browser üblicherweise keine Neuübertragungen nutzen. Prüfe den Wert deshalb immer auf undefined.
  • Browser-Unterstützung: Chromium-basierte Browser (Chrome, Edge) liefern den Wert zuverlässig. Firefox und Safari unterstützen ihn gar nicht oder nur teilweise. Prüfe das Feld deshalb zur Laufzeit, statt es vorauszusetzen.
  • Bei Simulcast gibt es pro Ebene (rid) einen eigenen outbound-rtp-Eintrag mit eigenem Zähler. Für einen Gesamtwert musst du die Werte aufsummieren.