Start · Sprachen · JavaScript · Referenz · RTCInboundRtpStreamStats.totalSamplesReceived

RTCInboundRtpStreamStats.totalSamplesReceived

Eigenschaft

Gibt die Gesamtzahl der Audio-Samples an, die über diesen eingehenden RTP-Stream empfangen wurden, einschließlich der verschleierten Samples (<code>concealedSamples</code>).

seit JavaScript Chrome 67+, Edge 79+, Firefox (teilweise), Safari Kategorie: webapi

Signatur

RTCInboundRtpStreamStats.totalSamplesReceived

Beschreibung

Die Eigenschaft totalSamplesReceived gehört zu einem RTCInboundRtpStreamStats-Objekt. Solche Objekte liefert RTCPeerConnection.getStats() bzw. RTCRtpReceiver.getStats() als Einträge mit type === "inbound-rtp". Der Wert ist ein fortlaufender Zähler. Er erfasst alle Audio-Samples, die der Decoder ausgegeben hat. Dazu gehören auch Samples, die der Jitter-Buffer wegen Paketverlust künstlich erzeugt hat (Concealment).

Die Eigenschaft gibt es nur bei Audio-Streams (kind === "audio"). Bei Stereo-Audio zählen die Samples beider Kanäle zusammen als ein Sample, der Zähler steigt also pro Zeitpunkt und nicht pro Kanal. Bei 48 kHz wächst der Wert um etwa 48.000 pro Sekunde.

Am meisten bringt der Wert zusammen mit concealedSamples und silentConcealedSamples. Das Verhältnis concealedSamples / totalSamplesReceived ist eine gängige Kennzahl für die Audioqualität. Wenn sie steigt, gehen Pakete verloren oder kommen zu spät an, und der Nutzer hört Aussetzer. Weil es ein kumulativer Zähler ist, bildet man für Live-Werte die Differenz zwischen zwei Messungen.

Beispiele

Empfangene Samples eines Audio-Streams auslesen

// pc ist eine bestehende, verbundene RTCPeerConnection
const logAudioSamples = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'inbound-rtp' && stats.kind === 'audio') {
      console.log(`Empfangene Samples: ${stats.totalSamplesReceived}`);
      console.log(`Davon verschleiert: ${stats.concealedSamples}`);
    }
  });
};

logAudioSamples(pc);
Empfangene Samples: 1440000 Davon verschleiert: 3120

Concealment-Rate als Qualitätskennzahl berechnen

const getConcealmentRate = async (receiver) => {
  const report = await receiver.getStats();
  for (const stats of report.values()) {
    if (stats.type === 'inbound-rtp' && stats.kind === 'audio') {
      const { totalSamplesReceived = 0, concealedSamples = 0 } = stats;
      if (totalSamplesReceived === 0) return 0;
      return concealedSamples / totalSamplesReceived;
    }
  }
  return null;
};

const [audioReceiver] = pc.getReceivers().filter((r) => r.track.kind === 'audio');
const rate = await getConcealmentRate(audioReceiver);
console.log(`Concealment-Rate: ${(rate * 100).toFixed(2)} %`);
Concealment-Rate: 0.22 %

Live-Monitoring über Differenzen zwischen zwei Messungen

let previous = null;

const monitorAudio = async (pc) => {
  const report = await pc.getStats();
  for (const stats of report.values()) {
    if (stats.type !== 'inbound-rtp' || stats.kind !== 'audio') continue;

    if (previous) {
      const deltaTotal = stats.totalSamplesReceived - previous.totalSamplesReceived;
      const deltaConcealed = stats.concealedSamples - previous.concealedSamples;
      const rate = deltaTotal > 0 ? deltaConcealed / deltaTotal : 0;
      if (rate > 0.05) {
        console.warn(`Schlechte Audioqualität: ${(rate * 100).toFixed(1)} % verschleiert`);
      } else {
        console.log(`Samples in der letzten Sekunde: ${deltaTotal}`);
      }
    }
    previous = stats;
  }
};

const intervalId = setInterval(() => monitorAudio(pc), 1000);
// Später: clearInterval(intervalId);
Samples in der letzten Sekunde: 48000

// Wichtig · Fallstricke

  • Nur Audio: Bei Video-Streams (kind === "video") gibt es die Eigenschaft nicht. Deshalb vorher immer kind prüfen oder einen Standardwert setzen.
  • Kumulativ: Der Zähler wird nie zurückgesetzt, solange der Stream besteht. Für aktuelle Qualitätswerte also Differenzen zwischen zwei getStats()-Aufrufen bilden und nicht die Absolutwerte vergleichen.
  • Enthält verschleierte Samples: Ein steigender Wert heißt nicht, dass echte Audiodaten angekommen sind. Die tatsächlich empfangenen Samples sind ungefähr totalSamplesReceived - concealedSamples.
  • Kanäle: Bei Mehrkanal-Audio zählt ein Sample pro Zeitpunkt, nicht pro Kanal.
  • Browser-Kompatibilität: Chromium-basierte Browser und Safari unterstützen die Eigenschaft. In Firefox kann sie fehlen oder anders gefüllt sein. Beim Zugriff am besten mit einem Standardwert absichern (stats.totalSamplesReceived ?? 0).
  • Die Statistiken werden intern nur in bestimmten Abständen aktualisiert. Zu häufiges Abfragen (z. B. öfter als alle 100 ms) liefert keine genaueren Werte und kostet unnötig Rechenzeit.