Start · Sprachen · JavaScript · Referenz · RTCRemoteInboundRtpStreamStats.fractionLost

RTCRemoteInboundRtpStreamStats.fractionLost

Eigenschaft

Liefert den Anteil der RTP-Pakete (0 bis 1), die laut dem letzten RTCP-Empfängerbericht der Gegenstelle im letzten Berichtsintervall für diese SSRC verloren gingen.

seit JavaScript WebRTC-Statistik-API; Chromium und Safari; Firefox Kategorie: webapi

Signatur

RTCRemoteInboundRtpStreamStats.fractionLost

Beschreibung

Die schreibgeschützte Eigenschaft fractionLost gehört zum Wörterbuch RTCRemoteInboundRtpStreamStats. Solche Statistikobjekte erhältst du über RTCPeerConnection.getStats() oder RTCRtpSender.getStats(). Du erkennst sie am Eintrag type === "remote-inbound-rtp". Das Objekt beschreibt, wie die Gegenstelle einen von dir gesendeten RTP-Strom empfängt. Die Werte kommen aus den RTCP-Empfängerberichten (Receiver Reports, RR) bzw. Senderberichten (Sender Reports, SR), die der Empfänger zurückschickt.

Der Wert ist eine Gleitkommazahl zwischen 0 (kein Verlust) und 1 (alle Pakete verloren). Er bezieht sich nur auf das letzte Berichtsintervall und ist nicht kumuliert. Technisch stammt er aus dem 8-Bit-Feld „fraction lost“ des RTCP-Berichts (RFC 3550), geteilt durch 256. Deshalb hat er nur eine Auflösung von etwa 0,4 %.

Damit eignet sich fractionLost gut für eine aktuelle Einschätzung der Verbindungsqualität, zum Beispiel für Qualitätsanzeigen in Videokonferenzen, für eine Bitraten-Anpassung oder zum Protokollieren von Netzwerkproblemen. Für Gesamtzahlen seit Beginn der Verbindung nimmst du stattdessen packetsLost. Diese Eigenschaft erbt das Wörterbuch von RTCReceivedRtpStreamStats.

Rückgabewert

Typ
number | undefined
Beschreibung
Anteil der verlorenen Pakete im letzten Berichtsintervall als Wert zwischen 0 und 1. Der Wert ist undefined, solange noch kein RTCP-Bericht der Gegenstelle eingetroffen ist oder wenn der Browser die Eigenschaft nicht unterstützt.

Beispiele

Paketverlust aller gesendeten Ströme auslesen

// pc ist eine bestehende, verbundene RTCPeerConnection
const logFractionLost = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'remote-inbound-rtp') {
      const percent = ((stats.fractionLost ?? 0) * 100).toFixed(1);
      console.log(`${stats.kind} (SSRC ${stats.ssrc}): ${percent} % Verlust`);
    }
  });
};

await logFractionLost(pc);
audio (SSRC 1234567890): 0.0 % Verlust video (SSRC 987654321): 3.1 % Verlust

Qualitätsanzeige mit regelmäßiger Abfrage

const rateQuality = (fraction) => {
  if (fraction === undefined) return 'unbekannt';
  if (fraction < 0.02) return 'gut';
  if (fraction < 0.1) return 'mittel';
  return 'schlecht';
};

const startMonitoring = (pc, sender, intervalMs = 2000) => {
  const timer = setInterval(async () => {
    const report = await sender.getStats();
    for (const stats of report.values()) {
      if (stats.type === 'remote-inbound-rtp') {
        console.log(`Qualität: ${rateQuality(stats.fractionLost)}`);
      }
    }
  }, intervalMs);
  // Überwachung beenden, sobald die Verbindung geschlossen wird
  pc.addEventListener('connectionstatechange', () => {
    if (pc.connectionState === 'closed') clearInterval(timer);
  });
  return () => clearInterval(timer);
};

const videoSender = pc.getSenders().find((s) => s.track?.kind === 'video');
const stop = startMonitoring(pc, videoSender);
Qualität: gut Qualität: mittel

Bitrate bei hohem Verlust drosseln

const adaptBitrate = async (sender) => {
  const report = await sender.getStats();
  const remote = [...report.values()].find((s) => s.type === 'remote-inbound-rtp');
  if (!remote || remote.fractionLost === undefined) return;

  const params = sender.getParameters();
  if (!params.encodings?.length) return;
  const current = params.encodings[0].maxBitrate ?? 1_500_000;

  if (remote.fractionLost > 0.1) {
    params.encodings[0].maxBitrate = Math.max(150_000, Math.round(current * 0.7));
    await sender.setParameters(params);
    console.log('Bitrate reduziert auf', params.encodings[0].maxBitrate);
  }
};

await adaptBitrate(videoSender);
Bitrate reduziert auf 1050000

// Wichtig · Fallstricke

  • Werte zwischen 0 und 1, keine Prozentwerte: Für eine Anzeige in Prozent musst du den Wert mit 100 multiplizieren.
  • Nur das letzte Intervall: Der Wert ändert sich nur, wenn ein neuer RTCP-Bericht eintrifft. Das passiert typischerweise alle paar Sekunden. Wenn du öfter abfragst, bekommst du mehrmals denselben Wert. Mit timestamp kannst du prüfen, ob ein Bericht neu ist.
  • Anfangs undefined: Direkt nach dem Verbindungsaufbau gibt es noch keinen remote-inbound-rtp-Eintrag bzw. keinen Wert. Sieh dafür immer einen Ersatzwert vor, z. B. mit ?? 0.
  • Doppelte Pakete: Wenn Pakete doppelt ankommen, würde die Berechnung eine negative Verlustrate ergeben. Laut RFC 3550 wird sie dann auf 0 gesetzt. Ein Wert von 0 heißt also nicht zwingend, dass das Netz einwandfrei arbeitet.
  • Richtung beachten: remote-inbound-rtp beschreibt den Verlust beim Empfang durch die Gegenstelle, also für deine gesendeten Daten. Den Verlust bei Paketen, die du selbst empfängst, findest du in den inbound-rtp-Statistiken über packetsLost.
  • Browser-Unterstützung: Chromium-basierte Browser und Safari unterstützen die Eigenschaft. In Firefox ist die Unterstützung von remote-inbound-rtp-Feldern historisch lückenhaft. Prüfe den Wert vor der Verwendung daher immer auf undefined.