Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.frameWidth

RTCOutboundRtpStreamStats.frameWidth

Eigenschaft

Liefert die Breite des zuletzt kodierten Video-Frames in Pixeln für einen ausgehenden RTP-Stream.

seit JavaScript Chrome 80+, Firefox 112+, Safari 13.1+ (nur Video- Kategorie: webapi

Signatur

RTCOutboundRtpStreamStats.frameWidth

Beschreibung

Die Eigenschaft frameWidth des Wörterbuchs RTCOutboundRtpStreamStats ist eine positive ganze Zahl. Sie gibt die Breite des letzten kodierten Frames in Pixeln an, also die Auflösung, mit der der Encoder das Video tatsächlich verschickt. Das ist nicht unbedingt die Auflösung der Kameraquelle.

Die Eigenschaft ist nützlich, um die tatsächliche Sendequalität zu überwachen. WebRTC senkt die Auflösung automatisch, wenn die Bandbreite oder die CPU knapp wird. Vergleichst du frameWidth mit den Einstellungen des Tracks (MediaStreamTrack.getSettings().width), erkennst du solche Anpassungen. Mit qualityLimitationReason siehst du zusätzlich, was die Anpassung ausgelöst hat.

Den Wert liest du aus dem RTCStatsReport, den RTCPeerConnection.getStats() oder RTCRtpSender.getStats() liefert. Die Einträge haben den Typ "outbound-rtp". Die Eigenschaft gibt es nur bei Video-Streams (kind === "video"). Solange noch kein Frame kodiert wurde, fehlt sie.

Rückgabewert

Typ
number | undefined
Beschreibung
Positive ganze Zahl: Breite des letzten kodierten Frames in Pixeln. Bei Audio-Streams oder solange noch kein Frame kodiert wurde, ist der Wert undefined.

Beispiele

Sendeauflösung aus getStats() auslesen

// pc ist eine bestehende, verbundene RTCPeerConnection
const logOutboundResolution = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'outbound-rtp' && stats.kind === 'video') {
      console.log(`Sende ${stats.frameWidth}x${stats.frameHeight} @ ${stats.framesPerSecond ?? '?'} fps`);
    }
  });
};

await logOutboundResolution(pc);
Sende 1280x720 @ 30 fps

Automatische Auflösungsanpassung erkennen

const sender = pc.getSenders().find((s) => s.track?.kind === 'video');
const sourceWidth = sender.track.getSettings().width;

const checkDownscaling = async () => {
  const report = await sender.getStats();
  for (const stats of report.values()) {
    if (stats.type !== 'outbound-rtp' || stats.frameWidth === undefined) continue;
    if (stats.frameWidth < sourceWidth) {
      console.warn(
        `Auflösung reduziert: ${sourceWidth}px -> ${stats.frameWidth}px ` +
        `(Grund: ${stats.qualityLimitationReason})`
      );
    }
  }
};

const timer = setInterval(checkDownscaling, 2000);
// später: clearInterval(timer);
Auflösung reduziert: 1920px -> 960px (Grund: bandwidth)

Simulcast-Ebenen nach Breite auflisten

const listSimulcastLayers = async (pc) => {
  const report = await pc.getStats();
  const layers = [...report.values()]
    .filter((s) => s.type === 'outbound-rtp' && s.kind === 'video')
    .map((s) => ({ rid: s.rid ?? '-', width: s.frameWidth ?? 0 }))
    .sort((a, b) => a.width - b.width);
  console.table(layers);
  return layers;
};

await listSimulcastLayers(pc);
[{ rid: 'q', width: 320 }, { rid: 'h', width: 640 }, { rid: 'f', width: 1280 }]

// Wichtig · Fallstricke

  • Nur für Video: Bei kind === "audio" fehlt die Eigenschaft. Prüfe also immer auf undefined, bevor du rechnest.
  • Nicht dasselbe wie die Quellauflösung: frameWidth ist die Breite nach dem Kodieren. Sie kann durch scaleResolutionDownBy, Simulcast oder die Bandbreitenanpassung kleiner sein als die Breite der Kamera.
  • Momentaufnahme: Der Wert gilt nur für den letzten Frame. Wenn du Verläufe brauchst, frage getStats() regelmäßig ab. Zu häufiges Abfragen, etwa unter 1 Sekunde, kostet unnötig CPU.
  • Simulcast: Jede Ebene hat einen eigenen outbound-rtp-Eintrag mit einer eigenen frameWidth. Unterscheide die Ebenen über rid.
  • Kompatibilität: Chromium-Browser und Safari unterstützen die Eigenschaft schon lange, Firefox erst seit neueren Versionen. Ältere Browser liefern die Werte teils nur im veralteten track-Statistiktyp.