Signatur
Beschreibung
Die Eigenschaft width gehört zum Wörterbuch RTCVideoSourceStats. Dieses Wörterbuch erscheint im RTCStatsReport als Eintrag mit type === "media-source" und kind === "video". Der Wert ist eine ganze Zahl und gibt die Breite des zuletzt erfassten Frames der Quelle in Pixeln an. Gemessen wird also direkt an der Quelle, noch vor Skalierung und Kodierung.
Nützlich ist das vor allem, um die Auflösung, die die Kamera oder die Bildschirmfreigabe tatsächlich liefert, mit der gesendeten Auflösung zu vergleichen. Die gesendete Auflösung steht in RTCOutboundRtpStreamStats.frameWidth. Weicht sie ab, liegt das meist an der Bandbreitenanpassung, an CPU-Engpässen oder an scaleResolutionDownBy. Diese Ursachen lassen sich über qualityLimitationReason weiter eingrenzen.
Den Wert fragst du über RTCPeerConnection.getStats() oder RTCRtpSender.getStats() ab. Er ist eine Momentaufnahme. Wenn du Änderungen der Auflösung beobachten willst, frag die Statistiken in regelmäßigen Abständen ab, zum Beispiel jede Sekunde.
Rückgabewert
undefined), solange noch kein Frame erfasst wurde.Beispiele
Quellauflösung der Kamera auslesen
const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } });
const pc = new RTCPeerConnection();
const [track] = stream.getVideoTracks();
pc.addTrack(track, stream);
// Kurz warten, damit die Quelle Frames liefert
await new Promise((r) => setTimeout(r, 1000));
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'media-source' && stats.kind === 'video') {
console.log(`Quelle: ${stats.width}x${stats.height} @ ${stats.framesPerSecond ?? '?'} fps`);
}
});
Quell- und Sendeauflösung vergleichen
const checkDownscaling = async (sender) => {
const report = await sender.getStats();
let source, outbound;
report.forEach((s) => {
if (s.type === 'media-source' && s.kind === 'video') source = s;
if (s.type === 'outbound-rtp' && s.kind === 'video') outbound = s;
});
if (!source?.width || !outbound?.frameWidth) return null;
const ratio = outbound.frameWidth / source.width;
return {
quelle: source.width,
gesendet: outbound.frameWidth,
skalierung: ratio.toFixed(2),
grund: outbound.qualityLimitationReason
};
};
const sender = pc.getSenders().find((s) => s.track?.kind === 'video');
console.log(await checkDownscaling(sender));
Auflösungsänderungen überwachen (z. B. Bildschirmfreigabe)
let lastWidth;
const timer = setInterval(async () => {
const report = await pc.getStats();
for (const s of report.values()) {
if (s.type === 'media-source' && s.kind === 'video' && s.width !== lastWidth) {
console.log(`Neue Quellbreite: ${s.width}px (vorher ${lastWidth ?? '–'})`);
lastWidth = s.width;
}
}
}, 1000);
// Später aufräumen:
// clearInterval(timer);
// Wichtig · Fallstricke
- Browserunterstützung: Chromium-Browser und Safari liefern
width. Firefox kenntmedia-source-Statistiken nur eingeschränkt. Prüfe den Wert deshalb immer aufundefined. - Nicht mit
frameWidthverwechseln:widthbeschreibt die Quelle vor der Kodierung.RTCOutboundRtpStreamStats.frameWidthbeschreibt, was tatsächlich gesendet wird, undRTCInboundRtpStreamStats.frameWidth, was empfangen wird. - Keine Frames, kein Wert: Direkt nach
addTrack()oder bei einem stummgeschalteten bzw. deaktivierten Track (track.enabled = false) kann die Eigenschaft fehlen oder veraltet sein. - Drehung: Auf Mobilgeräten kann die gemeldete Breite je nach Gerätedrehung mit der Höhe vertauscht sein.
- Für die bloße Kameraeinstellung ohne Peer-Verbindung ist
MediaStreamTrack.getSettings().widtheinfacher. Dieser Wert zeigt aber die konfigurierte Breite, nicht die des zuletzt tatsächlich erfassten Frames.