Start · Sprachen · JavaScript · Referenz · RTCRtpSender.getStats()

RTCRtpSender.getStats()

Methode

Fordert asynchron einen <code>RTCStatsReport</code> mit Statistiken zum ausgehenden RTP-Datenstrom dieses Senders an.

seit JavaScript Baseline: Chrome 67+, Firefox 55+, Safari 12+, Edg Kategorie: webapi

Signatur

RTCRtpSender.prototype.getStats()

Beschreibung

getStats() liefert ein Promise auf einen RTCStatsReport. Dieser enthält nur die Statistiken, die zum RTCRtpSender gehören, also zu dem Datenstrom, den der Sender über seine RTCPeerConnection verschickt. Enthalten sind vor allem Einträge vom Typ outbound-rtp und remote-inbound-rtp (Rückmeldungen der Gegenseite per RTCP) sowie die zugehörigen Einträge codec, transport, candidate-pair und media-source.

Im Unterschied zu RTCPeerConnection.prototype.getStats() müssen Sie das Ergebnis nicht selbst nach Track oder Sender filtern. Die Methode eignet sich deshalb gut, um für eine bestimmte Audio- oder Videospur die Senderate, die Bildrate, die Auflösung, verlorene Pakete oder die Laufzeit (Round-Trip-Time) zu überwachen.

Der RTCStatsReport ist ein Map-ähnliches Objekt. Die Schlüssel sind Statistik-IDs, die Werte sind Objekte mit den Feldern type, id und timestamp sowie typabhängigen Messwerten. Raten wie Bitrate oder Bildrate berechnen Sie aus der Differenz zweier Messungen, zum Beispiel bytesSent geteilt durch den Zeitabstand der timestamp-Werte.

Rückgabewert

Typ
Promise<RTCStatsReport>
Beschreibung
Promise, das mit einem RTCStatsReport erfüllt wird. Der Bericht enthält die Statistik-Objekte, die zu diesem Sender gehören. Ist dem Sender kein Track zugeordnet oder wurde die Verbindung noch nicht ausgehandelt, kann der Bericht leer oder unvollständig sein.

Beispiele

Ausgehende Video-Statistiken eines Senders auslesen

const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const sender = pc.addTrack(track, stream);

// ... Signalisierung / Verbindungsaufbau ...

const report = await sender.getStats();
report.forEach((stat) => {
  if (stat.type === 'outbound-rtp') {
    console.log(`Gesendet: ${stat.bytesSent} Bytes, ${stat.packetsSent} Pakete`);
    console.log(`Auflösung: ${stat.frameWidth}x${stat.frameHeight} @ ${stat.framesPerSecond} fps`);
  }
});
Gesendet: 1843200 Bytes, 1650 Pakete Auflösung: 1280x720 @ 30 fps

Bitrate periodisch berechnen

const monitorBitrate = (sender, intervalMs = 1000) => {
  let last = null;
  return setInterval(async () => {
    const report = await sender.getStats();
    for (const stat of report.values()) {
      if (stat.type !== 'outbound-rtp') continue;
      if (last) {
        const bits = (stat.bytesSent - last.bytesSent) * 8;
        const seconds = (stat.timestamp - last.timestamp) / 1000;
        console.log(`Bitrate: ${Math.round(bits / seconds / 1000)} kbit/s`);
      }
      last = stat;
    }
  }, intervalMs);
};

const timerId = monitorBitrate(sender);
// später: clearInterval(timerId);
Bitrate: 1480 kbit/s Bitrate: 1512 kbit/s

Paketverlust und RTT aus Rückmeldung der Gegenseite

const getQuality = async (sender) => {
  const report = await sender.getStats();
  const remote = [...report.values()].find((s) => s.type === 'remote-inbound-rtp');
  if (!remote) return null;
  return {
    rttMs: Math.round((remote.roundTripTime ?? 0) * 1000),
    fractionLost: remote.fractionLost,
    packetsLost: remote.packetsLost,
  };
};

console.log(await getQuality(sender));
{ rttMs: 42, fractionLost: 0.01, packetsLost: 12 }

Aktiven Codec ermitteln

const report = await sender.getStats();
const outbound = [...report.values()].find((s) => s.type === 'outbound-rtp');
const codec = outbound && report.get(outbound.codecId);
console.log(codec?.mimeType, codec?.clockRate);
video/VP8 90000

// Wichtig · Fallstricke

  • Raten gibt es nicht direkt: Werte wie bytesSent sind kumulative Zähler. Eine Bitrate berechnen Sie aus zwei Messungen und deren timestamp-Differenz (in Millisekunden).
  • Simulcast: Bei Simulcast enthält der Bericht mehrere outbound-rtp-Einträge, einen pro Encoding. Sie unterscheiden die Einträge über rid bzw. ssrc.
  • Verzögerte Werte: remote-inbound-rtp erscheint erst, wenn RTCP-Receiver-Reports eingegangen sind, also meist einige Sekunden nach dem Verbindungsaufbau.
  • Unterschiede zwischen Browsern: Nicht jeder Browser liefert alle Felder. framesPerSecond, qualityLimitationReason oder encoderImplementation fehlen zum Beispiel in manchen Browsern. Prüfen Sie Felder vor der Verwendung, etwa mit ?. oder ??.
  • Veraltete API: Die alte callback-basierte Form von getStats() in Chrome ist veraltet. Verwenden Sie ausschließlich die Promise-Variante.
  • Leistung: Rufen Sie getStats() nicht zu oft auf. Ein Intervall von etwa 1 s ist üblich, weil jeder Aufruf intern Daten sammelt.
  • Datenschutz: Statistiken wie candidate-pair können Netzwerkdetails wie IP-Adressen enthalten. Behandeln Sie diese Daten vertraulich, bevor Sie sie an Telemetriedienste senden.