Start · Sprachen · JavaScript · Referenz · RTCInboundRtpStreamStats.nackCount

RTCInboundRtpStreamStats.nackCount

Eigenschaft

Gibt an, wie viele NACK-Pakete (Negative Acknowledgement) der Empfänger dieses eingehenden RTP-Streams an den Sender geschickt hat.

seit JavaScript Baseline: Chrome, Edge, Firefox, Safari (neuere Ve Kategorie: webapi

Signatur

RTCInboundRtpStreamStats.nackCount

Beschreibung

Die schreibgeschützte Eigenschaft nackCount gehört zum Wörterbuch RTCInboundRtpStreamStats. Sie ist eine positive ganze Zahl und zählt, wie oft der lokale Empfänger ein NACK-Paket (RTCP Generic NACK, RFC 4585) an den entfernten Sender geschickt hat. Damit fordert er verloren gegangene RTP-Pakete erneut an.

Der Wert steigt nur an und wird nie zurückgesetzt. Ein NACK-Paket kann den Verlust mehrerer RTP-Pakete auf einmal melden. nackCount sagt also nichts darüber aus, wie viele Pakete fehlten, sondern nur, wie viele Anfragen verschickt wurden. Die Zahl der tatsächlich verlorenen Pakete steht in packetsLost.

In der Praxis nutzt man nackCount, um die Qualität einer Verbindung zu überwachen. Steigt der Wert schnell, deutet das auf Paketverluste im Netz hin. Oft folgen dann Bildfehler, Einfrieren oder zusätzliche Anfragen nach Keyframes (pliCount, firCount). Den Wert bekommt man über RTCPeerConnection.getStats() oder RTCRtpReceiver.getStats(). Dort sucht man die Einträge mit type === "inbound-rtp".

Rückgabewert

Typ
number | undefined
Beschreibung
Eine positive ganze Zahl (unsigned long): die Gesamtzahl der verschickten NACK-Pakete seit Beginn des Streams. Ist undefined, wenn der Browser den Wert nicht meldet.

Beispiele

nackCount aller eingehenden Streams auslesen

// pc ist eine bestehende, verbundene RTCPeerConnection
const logNackCounts = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'inbound-rtp') {
      console.log(`${stats.kind} (SSRC ${stats.ssrc}): ${stats.nackCount ?? 'n/a'} NACKs`);
    }
  });
};

await logNackCounts(pc);
video (SSRC 12345678): 42 NACKs audio (SSRC 87654321): 0 NACKs

NACK-Rate pro Sekunde für einen Video-Receiver überwachen

const monitorNackRate = (receiver, intervalMs = 2000) => {
  let lastCount = null;
  let lastTs = null;

  return setInterval(async () => {
    const report = await receiver.getStats();
    for (const stats of report.values()) {
      if (stats.type !== 'inbound-rtp' || stats.nackCount === undefined) continue;

      if (lastCount !== null) {
        const seconds = (stats.timestamp - lastTs) / 1000;
        const rate = (stats.nackCount - lastCount) / seconds;
        console.log(`NACK-Rate: ${rate.toFixed(2)}/s`);
        if (rate > 5) console.warn('Hoher Paketverlust – Netzqualität prüfen!');
      }
      lastCount = stats.nackCount;
      lastTs = stats.timestamp;
    }
  }, intervalMs);
};

const videoReceiver = pc.getReceivers().find((r) => r.track?.kind === 'video');
const timerId = monitorNackRate(videoReceiver);
// später: clearInterval(timerId);
NACK-Rate: 0.50/s NACK-Rate: 7.25/s Hoher Paketverlust – Netzqualität prüfen!

NACKs mit verlorenen Paketen vergleichen

const summarizeLoss = async (pc) => {
  const report = await pc.getStats();
  const summary = [];
  for (const s of report.values()) {
    if (s.type === 'inbound-rtp' && s.kind === 'video') {
      summary.push({
        ssrc: s.ssrc,
        packetsReceived: s.packetsReceived,
        packetsLost: s.packetsLost,
        nackCount: s.nackCount,
        pliCount: s.pliCount
      });
    }
  }
  console.table(summary);
  return summary;
};

await summarizeLoss(pc);
[{ ssrc: 12345678, packetsReceived: 15230, packetsLost: 57, nackCount: 31, pliCount: 2 }]

// Wichtig · Fallstricke

  • Kumulativer Zähler: nackCount zählt vom Beginn des Streams an. Für eine aussagekräftige Rate nimmt man die Differenz zweier Messungen und teilt sie durch die Differenz der timestamp-Werte.
  • Nicht gleich Paketverlust: Ein NACK kann mehrere Pakete betreffen, und manche Verluste lösen gar kein NACK aus. Das passiert zum Beispiel, wenn NACK nicht ausgehandelt wurde oder das Paket ohnehin zu spät käme. nackCount und packetsLost stimmen daher meist nicht überein.
  • Abhängig von der Aushandlung: NACKs werden nur verschickt, wenn im SDP a=rtcp-fb:… nack ausgehandelt wurde. Bei Audio ist das meist nicht der Fall, deshalb bleibt der Wert dort oft bei 0.
  • Browser-Unterstützung: Aktuelle Chromium-Browser, Firefox und Safari melden die Eigenschaft. Ältere Versionen führten sie teils nur im veralteten Typ "track" oder gar nicht. Deshalb vor der Nutzung auf undefined prüfen.
  • Die ausgehende Seite meldet den gleichen Wert als RTCOutboundRtpStreamStats.nackCount, dort gezählt als empfangene NACKs.