Signatur
Beschreibung
Die schreibgeschützte Eigenschaft framesPerSecond eines RTCOutboundRtpStreamStats-Objekts enthält die Anzahl der codierten Frames, die der lokale Sender in der letzten Sekunde verschickt hat. Sie ist damit die tatsächlich gesendete Bildrate eines Video-Streams und kann niedriger sein als die Bildrate der Kamera, z. B. wenn der Encoder wegen knapper Bandbreite oder CPU-Last Frames verwirft.
Du erhältst den Wert über RTCPeerConnection.getStats() oder RTCRtpSender.getStats(): Im zurückgegebenen RTCStatsReport suchst du Einträge mit type === "outbound-rtp" und kind === "video". Die Eigenschaft ist nur für Video-Streams definiert; bei Audio-Streams fehlt sie.
Typische Einsatzzwecke sind Qualitäts-Dashboards, adaptive Steuerung (z. B. Auflösung per RTCRtpSender.setParameters() senken, wenn die Bildrate einbricht) und das Erkennen von Problemen durch Einschränkungen (qualityLimitationReason). Bei Simulcast gibt es pro Schicht (rid) einen eigenen outbound-rtp-Eintrag mit eigener Bildrate.
Rückgabewert
undefined, wenn der Stream kein Video ist oder noch keine Frames gesendet wurden.Beispiele
Gesendete Bildrate auslesen
// pc ist eine verbundene RTCPeerConnection mit Video-Track
const logSendFps = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'outbound-rtp' && stats.kind === 'video') {
console.log(`SSRC ${stats.ssrc}: ${stats.framesPerSecond ?? 'n/a'} fps`);
}
});
};
await logSendFps(pc);
Bildrate überwachen und Einbrüche erkennen
const [sender] = pc.getSenders().filter((s) => s.track?.kind === 'video');
const timer = setInterval(async () => {
const report = await sender.getStats();
for (const stats of report.values()) {
if (stats.type !== 'outbound-rtp') continue;
const fps = stats.framesPerSecond ?? 0;
if (fps < 15) {
console.warn(`Niedrige Bildrate: ${fps} fps – Grund: ${stats.qualityLimitationReason}`);
}
}
}, 2000);
// später: clearInterval(timer);
Simulcast-Schichten vergleichen
const report = await pc.getStats();
const layers = [...report.values()]
.filter((s) => s.type === 'outbound-rtp' && s.kind === 'video')
.map(({ rid, frameWidth, frameHeight, framesPerSecond }) => ({
rid, aufloesung: `${frameWidth}x${frameHeight}`, fps: framesPerSecond
}));
console.table(layers);
// Wichtig · Fallstricke
- Nur Video: Für Audio-
outbound-rtp-Einträge ist die Eigenschaft nicht vorhanden – immerkind === "video"prüfen und mit?? 0absichern. - Anfangswerte: Direkt nach Verbindungsaufbau oder bei pausiertem/stummgeschaltetem Track kann der Wert fehlen oder
0sein. - Gesendet ≠ erfasst: Die Kamera-Bildrate steht in
RTCVideoSourceStats.framesPerSecond(type === "media-source"). Eine Differenz deutet auf Encoder-Drosselung hin (siehequalityLimitationReason). - Eigene Berechnung: Für präzise Werte über frei gewählte Intervalle die Differenz von
framesSentbzw.framesEncodeddurch die Differenz vontimestampteilen. - Kompatibilität: In aktuellen Chromium-Browsern, Firefox und Safari verfügbar; ältere Versionen lieferten die Werte teils im veralteten
track-Statistiktyp.getStats()nicht zu häufig aufrufen (≥ 1 s Intervall), da es Ressourcen kostet.