Signatur
Beschreibung
Die Methode requestFrame() gehört zur Schnittstelle CanvasCaptureMediaStreamTrack. Diesen Track erhält man über HTMLCanvasElement.captureStream(). Sie weist den Browser an, den aktuellen Inhalt des Canvas als nächsten Video-Frame in den Stream zu übernehmen.
Richtig nützlich wird die Methode, wenn der Stream mit canvas.captureStream(0) erzeugt wurde. Mit einer Bildrate von 0 nimmt der Browser keine Frames mehr von selbst auf, sondern nur noch auf ausdrücklichen Aufruf von requestFrame(). So legst du genau fest, wann ein Frame übertragen wird, etwa nur nach einer Zeichenoperation, bei Präsentationsfolien, Whiteboards oder Aufnahmen in festem Takt über MediaRecorder.
Ohne Argument (also bei captureStream()) wird bei jeder Canvas-Änderung automatisch ein Frame erzeugt. Mit fester Bildrate wird höchstens diese Rate genutzt. In beiden Fällen kann requestFrame() zusätzlich einen Frame erzwingen. Der Frame wird nicht sofort beim Aufruf aufgenommen, sondern beim nächsten Rendering-Schritt des Browsers.
Rückgabewert
undefined).Beispiele
Frames manuell nach jedem Zeichnen senden
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
// Bildrate 0: keine automatische Aufnahme
const stream = canvas.captureStream(0);
const [track] = stream.getVideoTracks();
const video = document.querySelector('video');
video.srcObject = stream;
const zeichneKreis = (x, y) => {
ctx.fillStyle = 'tomato';
ctx.beginPath();
ctx.arc(x, y, 20, 0, Math.PI * 2);
ctx.fill();
// Erst jetzt wird der neue Zustand übertragen
track.requestFrame();
};
canvas.addEventListener('click', (e) => zeichneKreis(e.offsetX, e.offsetY));
Aufnahme mit MediaRecorder in eigenem Takt
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const stream = canvas.captureStream(0);
const [track] = stream.getVideoTracks();
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
const chunks = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
console.log('Video-Größe:', blob.size, 'Bytes');
};
recorder.start();
let frame = 0;
const timer = setInterval(() => {
ctx.fillStyle = `hsl(${frame * 10}, 70%, 50%)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
track.requestFrame(); // genau ein Frame pro Intervall
if (++frame >= 30) {
clearInterval(timer);
recorder.stop();
}
}, 100);
Funktionsprüfung vor der Nutzung
const canvas = document.createElement('canvas');
const stream = canvas.captureStream?.(0);
const track = stream?.getVideoTracks()[0];
if (track && typeof track.requestFrame === 'function') {
track.requestFrame();
console.log('requestFrame() wird unterstützt');
} else {
console.log('Manuelle Frame-Anforderung nicht verfügbar');
}
// Wichtig · Fallstricke
- Nur sinnvoll mit
captureStream(0): Bei automatischer Aufnahme bringt ein zusätzlicher Aufruf meist nichts, weil der Browser Änderungen ohnehin erfasst. - Asynchron: Der Frame wird erst beim nächsten Rendering-Schritt aufgenommen. Mehrere Aufrufe innerhalb desselben Tasks ergeben in der Regel nur einen Frame.
- Canvas mit fremden Inhalten: Ist das Canvas durch ursprungsfremde Bilder ohne CORS verunreinigt („origin-clean“ = false), wirft schon
captureStream()einenSecurityError. - Beendete Tracks: Nach
track.stop()(readyState === 'ended') hat der Aufruf keine Wirkung mehr. - Kompatibilität: Wird in aktuellen Chromium-Browsern, in Firefox und ab Safari 15 unterstützt. In älteren Browsern gibt es die Methode nicht, daher vorher mit einer Funktionsprüfung absichern.
- Hintergrund-Tabs: Browser drosseln Timer wie
setIntervalin inaktiven Tabs. Dadurch können Aufnahmen ruckeln oder Lücken haben.