Signatur
Beschreibung
Die Eigenschaft frameHeight gehört zum Wörterbuch RTCOutboundRtpStreamStats. Sie gibt die Höhe des zuletzt codierten Frames eines ausgehenden Videostreams in Pixeln an. Du bekommst den Wert über RTCPeerConnection.getStats() oder RTCRtpSender.getStats(), und zwar in den Berichten mit type === "outbound-rtp".
Der Wert kann von der Auflösung der Quelle (z. B. der Kamera) abweichen. Der Encoder skaliert die Auflösung dynamisch herunter, wenn die Bandbreite knapp oder die CPU ausgelastet ist, oder wenn scaleResolutionDownBy bzw. Simulcast-Ebenen gesetzt sind. Vergleiche frameHeight mit frameWidth, framesPerSecond und qualityLimitationReason, dann siehst du, ob und warum die gesendete Qualität reduziert wurde.
Die Eigenschaft gibt es nur bei Videostreams (kind === "video"). Bei Audiostreams fehlt sie. Bevor der erste Frame codiert ist, ist sie ebenfalls undefined.
Rückgabewert
undefined bei Audio oder wenn noch kein Frame codiert wurde.Beispiele
Gesendete Auflösung auslesen
// pc ist eine bestehende RTCPeerConnection mit Video-Track
const logOutboundResolution = async (pc) => {
const stats = await pc.getStats();
stats.forEach((report) => {
if (report.type === "outbound-rtp" && report.kind === "video") {
console.log(`Gesendet: ${report.frameWidth}x${report.frameHeight}`);
}
});
};
await logOutboundResolution(pc);
Herunterskalierung durch den Encoder erkennen
const checkDownscaling = async (sender) => {
const sourceHeight = sender.track.getSettings().height;
const stats = await sender.getStats();
for (const report of stats.values()) {
if (report.type !== "outbound-rtp" || report.frameHeight === undefined) continue;
if (report.frameHeight < sourceHeight) {
console.warn(
`Skaliert: ${sourceHeight}p → ${report.frameHeight}p (Grund: ${report.qualityLimitationReason})`
);
}
}
};
const [videoSender] = pc.getSenders().filter((s) => s.track?.kind === "video");
await checkDownscaling(videoSender);
Simulcast-Ebenen periodisch überwachen
const monitorSimulcast = (sender, intervalMs = 2000) => {
const id = setInterval(async () => {
const stats = await sender.getStats();
const layers = [...stats.values()]
.filter((r) => r.type === "outbound-rtp")
.map((r) => `${r.rid ?? "-"}: ${r.frameHeight ?? "?"}p`);
console.log(layers.join(" | "));
}, intervalMs);
return () => clearInterval(id); // Stopp-Funktion
};
const stop = monitorSimulcast(videoSender);
// später: stop();
// Wichtig · Fallstricke
- Nur Video: Bei
outbound-rtp-Berichten mitkind === "audio"gibt es die Eigenschaft nicht. Prüfe deshalb immerkind, oder sichere den Zugriff gegenundefinedab. - Nicht die Quellauflösung:
frameHeightist die codierte Höhe. Die Auflösung der Quelle bekommst du übertrack.getSettings()oder über denmedia-source-Bericht (RTCVideoSourceStats.height). - Momentaufnahme: Der Wert gilt nur für den letzten Frame und kann sich jederzeit ändern, etwa bei Bandbreitenanpassung. Wenn du Qualität überwachen willst, frage den Wert regelmäßig ab.
- Simulcast: Jede Ebene liefert einen eigenen
outbound-rtp-Bericht mit eigenerframeHeight. Die Ebenen unterscheidest du überrid. - Kompatibilität: Die Eigenschaft wird in aktuellen Chromium-Browsern, Firefox und Safari unterstützt. In älteren Versionen stand der Wert teils in veralteten
track-Berichten. Diese sind inzwischen entfernt.