Start · Sprachen · JavaScript · Referenz · RTCVideoSourceStats.frames

RTCVideoSourceStats.frames

Eigenschaft

Gibt die Gesamtzahl der Frames an, die eine lokale Videoquelle während ihrer gesamten Lebensdauer an die WebRTC-Verbindung geliefert hat.

seit JavaScript WebRTC Statistics API; Chromium und Safari, in Fir Kategorie: webapi

Signatur

RTCVideoSourceStats.frames

Beschreibung

Die schreibgeschützte Eigenschaft frames gehört zum Dictionary RTCVideoSourceStats. Dieses erhält man über RTCPeerConnection.getStats() oder RTCRtpSender.getStats() als Eintrag mit type === "media-source" und kind === "video". Der Wert ist ein fortlaufender Zähler (unsigned long). Er zählt, wie viele Frames die Quelle, also meist die Kamera oder die Bildschirmfreigabe hinter einem MediaStreamTrack, bisher an den Sender geliefert hat.

Der Zähler steigt nur an und bezieht sich auf die Quelle, nicht auf das, was tatsächlich kodiert oder gesendet wurde. Deshalb eignet er sich gut für die Fehlersuche. Vergleicht man ihn mit framesEncoded oder framesSent aus den outbound-rtp-Statistiken, sieht man, ob Frames schon in der Kamera fehlen oder erst beim Encoder verloren gehen, etwa durch CPU-Überlastung oder Bandbreitenanpassung.

Für eine aktuelle Bildrate misst man den Unterschied zwischen zwei Abfragen und teilt ihn durch den Unterschied der timestamp-Werte (in Millisekunden). Der absolute Wert allein zeigt nur, wie viel die Quelle seit ihrem Start insgesamt geliefert hat.

Rückgabewert

Typ
number
Beschreibung
Eine nicht negative ganze Zahl (unsigned long): Gesamtzahl der Frames, die die Videoquelle seit Beginn geliefert hat. Fehlt die Unterstützung, ist die Eigenschaft undefined.

Beispiele

Frame-Zähler der Kameraquelle auslesen

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

// Kurz warten, damit die Quelle Frames liefert
await new Promise((r) => setTimeout(r, 2000));

const report = await sender.getStats();
for (const stats of report.values()) {
  if (stats.type === 'media-source' && stats.kind === 'video') {
    console.log(`Quelle ${stats.trackIdentifier}: ${stats.frames} Frames`);
  }
}
Quelle 3f2a…: 60 Frames

Aktuelle Bildrate aus zwei Abfragen berechnen

const getVideoSource = async (pc) => {
  const report = await pc.getStats();
  return [...report.values()].find(
    (s) => s.type === 'media-source' && s.kind === 'video'
  );
};

const measureFps = async (pc, intervalMs = 1000) => {
  const a = await getVideoSource(pc);
  await new Promise((r) => setTimeout(r, intervalMs));
  const b = await getVideoSource(pc);
  if (!a || !b || a.frames === undefined) return null;
  const deltaFrames = b.frames - a.frames;
  const deltaSec = (b.timestamp - a.timestamp) / 1000;
  return deltaFrames / deltaSec;
};

console.log(`Quelle liefert ${(await measureFps(pc)).toFixed(1)} fps`);
Quelle liefert 29.9 fps

Verlorene Frames zwischen Quelle und Encoder erkennen

const checkEncoderLoss = async (sender) => {
  const report = await sender.getStats();
  let source, outbound;
  for (const s of report.values()) {
    if (s.type === 'media-source' && s.kind === 'video') source = s;
    if (s.type === 'outbound-rtp' && s.kind === 'video') outbound = s;
  }
  if (!source || !outbound) return;
  const lost = source.frames - outbound.framesEncoded;
  const ratio = (lost / source.frames) * 100;
  console.log(`Nicht kodiert: ${lost} Frames (${ratio.toFixed(1)} %)`);
};

setInterval(() => checkEncoderLoss(sender), 5000);
Nicht kodiert: 12 Frames (0.8 %)

// Wichtig · Fallstricke

  • Browser-Unterstützung: Chromium-basierte Browser und Safari liefern frames. Firefox stellt media-source-Statistiken nur teilweise bereit. Prüfen Sie deshalb immer mit stats.frames !== undefined, ob der Wert vorhanden ist.
  • Der Wert ist ein Zähler über die ganze Lebensdauer und keine Rate. Für die Bildrate brauchen Sie zwei Messungen und die Differenz der timestamp-Werte. Alternativ gibt es framesPerSecond.
  • Wird der Track mit RTCRtpSender.replaceTrack() ausgetauscht, kann ein neues media-source-Objekt mit eigener ID entstehen, dessen Zähler wieder bei 0 beginnt. Vergleichen Sie Messungen daher über dieselbe id oder dieselbe trackIdentifier.
  • Kodierte oder gesendete Frames können weniger sein als frames, zum Beispiel wegen CPU-Überlastung, Bandbreitenanpassung oder deaktiviertem Track (track.enabled = false). Das ist erwartetes Verhalten und kein Fehler der Statistik.
  • Es gibt Werte nur für lokale Quellen, also Sender. Für empfangene Videos nutzen Sie RTCInboundRtpStreamStats.framesDecoded bzw. framesReceived.