Signatur
Beschreibung
Die Methode cancelVideoFrameCallback() ist das Gegenstück zu HTMLVideoElement.requestVideoFrameCallback(). Sie nimmt die Kennung (Handle) entgegen, die requestVideoFrameCallback() zurückgegeben hat, und entfernt den zugehörigen Callback aus der Warteschlange des Videoelements. Das Prinzip entspricht dem Paar requestAnimationFrame()/cancelAnimationFrame().
Man braucht die Methode immer dann, wenn eine pro Frame laufende Verarbeitung beendet werden soll: zum Beispiel, wenn ein Canvas-Overlay, eine Frame-Analyse (etwa Bewegungserkennung oder Untertitel-Synchronisation) oder eine Statistik-Anzeige abgeschaltet wird, das Video aus dem DOM entfernt wird oder eine Komponente in einem Framework (React, Vue …) wieder ausgehängt wird.
Wichtig: Ein Video-Frame-Callback wird immer nur einmal ausgelöst. Wer fortlaufend reagieren will, registriert im Callback erneut – und bekommt dabei jedes Mal ein neues Handle. Zum Abbrechen muss also immer das zuletzt vergebene Handle an cancelVideoFrameCallback() übergeben werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $handle Pflicht | number | Die ganzzahlige Kennung, die ein vorheriger Aufruf von requestVideoFrameCallback() auf demselben Videoelement zurückgegeben hat. |
Rückgabewert
undefined zurück. Ein ungültiges oder bereits ausgeführtes Handle wird stillschweigend ignoriert.Beispiele
Einzelnen Callback registrieren und wieder stornieren
const video = document.querySelector('video');
const handle = video.requestVideoFrameCallback((now, metadata) => {
console.log('Frame angezeigt:', metadata.mediaTime);
});
// Doch nicht nötig – Callback wieder entfernen
video.cancelVideoFrameCallback(handle);
console.log('Callback storniert, Handle:', handle);
Fortlaufende Frame-Schleife starten und stoppen
const video = document.querySelector('video');
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
let handle = null;
const drawFrame = (now, metadata) => {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// Neu registrieren – neues Handle merken!
handle = video.requestVideoFrameCallback(drawFrame);
};
const start = () => {
if (handle === null) handle = video.requestVideoFrameCallback(drawFrame);
};
const stop = () => {
if (handle !== null) {
video.cancelVideoFrameCallback(handle);
handle = null;
}
};
document.querySelector('#start').addEventListener('click', start);
document.querySelector('#stop').addEventListener('click', stop);
Aufräumen mit Feature-Erkennung und Fallback
const video = document.querySelector('video');
const supportsVFC = 'requestVideoFrameCallback' in HTMLVideoElement.prototype;
const watchFrames = (onFrame) => {
let id;
if (supportsVFC) {
const loop = (now, meta) => { onFrame(meta.mediaTime); id = video.requestVideoFrameCallback(loop); };
id = video.requestVideoFrameCallback(loop);
return () => video.cancelVideoFrameCallback(id);
}
// Fallback: requestAnimationFrame
const loop = () => { onFrame(video.currentTime); id = requestAnimationFrame(loop); };
id = requestAnimationFrame(loop);
return () => cancelAnimationFrame(id);
};
const stopWatching = watchFrames((t) => console.log(t.toFixed(2)));
video.addEventListener('ended', stopWatching, { once: true });
// Wichtig · Fallstricke
- Immer das aktuelle Handle stornieren: Bei wiederholter Registrierung im Callback ändert sich das Handle jedes Mal. Wird ein altes Handle übergeben, läuft die Schleife weiter.
- Handles gelten nur für das Element, auf dem sie erzeugt wurden – ein Handle von Video A storniert auf Video B nichts.
- Ungültige Handles werfen keinen Fehler; ein fehlgeschlagener Abbruch fällt daher leicht nicht auf.
- Callbacks feuern nur, wenn tatsächlich neue Frames zusammengesetzt werden (pausiertes oder verstecktes Video liefert keine). Trotzdem beim Aushängen von Komponenten stornieren, um Speicherlecks durch Closures zu vermeiden.
- Kompatibilität: Chromium-Browser seit Version 83, Safari seit 15.4, Firefox erst seit Version 132. Vorher per
'requestVideoFrameCallback' in HTMLVideoElement.prototypeprüfen und ggf. aufrequestAnimationFrame()ausweichen.