HTMLVideoElement: requestVideoFrameCallback() Methode
Baseline 2024Newly available
Since October 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Die requestVideoFrameCallback()
-Methode der HTMLVideoElement
-Schnittstelle registriert eine Rückruffunktion, die ausgeführt wird, wenn ein neues Videoframe an den Kompositor gesendet wird. Dies ermöglicht Entwicklern, effiziente Operationen auf jedem Videoframe durchzuführen.
Syntax
requestVideoFrameCallback(callback)
Parameter
callback
-
Die Rückruffunktion, die ausgeführt wird, wenn ein neues Videoframe an den Kompositor gesendet wird. Diese enthält zwei Parameter:
now
-
Ein
DOMHighResTimeStamp
, der den Zeitpunkt repräsentiert, an dem der Rückruf aufgerufen wurde. metadata
-
Ein Objekt mit den folgenden Eigenschaften:
expectedDisplayTime
-
Ein
DOMHighResTimeStamp
, der den Zeitpunkt repräsentiert, an dem der Browser erwartet, dass das Frame sichtbar ist. height
-
Eine Zahl in Medienpixeln, die die Höhe des Videoframes repräsentiert (die sichtbaren dekodierten Pixel, ohne Anpassungen des Seitenverhältnisses).
mediaTime
-
Eine Zahl in Sekunden, die den Mediapräsentationszeitstempel des dargestellten Frames repräsentiert. Dies entspricht dem Zeitstempel des Frames auf der
HTMLMediaElement.currentTime
Zeitleiste. presentationTime
-
Ein
DOMHighResTimeStamp
, der den Zeitpunkt repräsentiert, an dem der Browser das Frame zur Komposition übermittelt hat. presentedFrames
-
Eine Zahl, die die Anzahl der bisher zur Komposition übermittelten Frames zusammen mit dem aktuellen Rückruf darstellt. Dies kann verwendet werden, um zu erkennen, ob zwischen Rückrufinstanzen Frames verpasst wurden.
processingDuration
-
Eine Zahl in Sekunden, die die Dauer zwischen der Übermittlung des kodierten Pakets mit demselben Präsentationszeitstempel wie dieses Frame an den Decoder (d.h. dem
mediaTime
) und dem dekodierten Frame, das zur Präsentation bereit ist, darstellt. width
-
Eine Zahl in Medienpixeln, die die Breite des Videoframes darstellt (die sichtbaren dekodierten Pixel, ohne Anpassungen des Seitenverhältnisses).
Zusätzliche Metadaten-Eigenschaften könnten innerhalb von
requestVideoFrameCallback()
-Rückrufen in WebRTC-Anwendungen verfügbar sein:captureTime
-
Ein
DOMHighResTimeStamp
, der den Zeitpunkt repräsentiert, an dem das Frame erfasst wurde. Dies gilt für Videoframes aus einer lokalen oder entfernten Quelle. Bei einer entfernten Quelle wird die Erfassungszeit mithilfe der Synchronisation der Uhren und RTCP-Senderberichte geschätzt, um RTP-Zeitstempel in Erfassungszeit umzuwandeln. receiveTime
-
Ein
DOMHighResTimeStamp
, der den Zeitpunkt repräsentiert, an dem das kodierte Frame von der Plattform empfangen wurde. Dies gilt für Videoframes aus einer entfernten Quelle. Insbesondere entspricht dies dem Zeitpunkt, an dem das letzte Paket zu diesem Frame über das Netzwerk empfangen wurde. rtpTimestamp
-
Eine Zahl, die den RTP-Zeitstempel darstellt, der mit diesem Videoframe verbunden ist.
Hinweis:>width
und height
können in bestimmten Fällen von HTMLVideoElement.videoWidth
und HTMLVideoElement.videoHeight
abweichen (zum Beispiel, wenn ein anamorphes Video rechteckige Pixel hat).
Rückgabewert
Eine Zahl, die eine eindeutige Callback-ID darstellt.
Diese kann an HTMLVideoElement.cancelVideoFrameCallback()
übergeben werden, um die Rückrufregistrierung abzubrechen.
Beschreibung
Typische Anwendungsfälle für requestVideoFrameCallback()
umfassen Videoverarbeitung und -malerei auf einer Leinwand, Videoanalyse und Synchronisation mit externen Audioquellen. Verarbeitung pro Frame wurde früher auf weniger effiziente oder genaue Weise durchgeführt, indem Operationen auf der aktuellen Videoanzeige jedes Mal ausgeführt wurden, wenn das timeupdate
Ereignis ausgelöst wurde. Diese Technik bot keinen Zugriff auf die tatsächlichen Videoframes.
requestVideoFrameCallback()
wird auf die gleiche Weise verwendet wie Window.requestAnimationFrame()
. Man verwendet es, um eine Rückruffunktion auszuführen, die eine Operation durchführt, wenn das nächste Videoframe an den Kompositor gesendet wird. Der Rückruf endet, indem requestVideoFrameCallback()
erneut aufgerufen wird, um den Rückruf auszuführen, wenn das nächste Videoframe komponiert wird, und so weiter. Allerdings ist requestVideoFrameCallback()
in mehrerer Hinsicht speziell für Videooperationen konzipiert:
requestVideoFrameCallback()
bietet zuverlässigen Zugriff auf jedes einzelne Videoframe.requestAnimationFrame()
versucht, die Display-Aktualisierungsrate anzupassen, die typischerweise 60Hz beträgt.requestVideoFrameCallback()
hingegen versucht, die Video-Framerate anzupassen. Genauer gesagt, der Rückruf wird mit der niedrigeren der beiden Raten zwischen Video-Framerate und Browser-Aktualisierungsrate ausgeführt. Zum Beispiel würde ein Video mit einer Framerate von 25fps, das in einem Browser abgespielt wird, der mit 60Hz malt, Rückrufe mit einer Rate von 25Hz auslösen. Ein Video mit einer Framerate von 120fps, das im selben 60Hz-Browser läuft, würde Rückrufe mit 60Hz auslösen.requestVideoFrameCallback()
macht nützliche Videometadaten in der Rückruffunktion verfügbar.
Ein Punkt, den Sie beachten sollten, ist, dass requestVideoFrameCallback()
keine strengen Garantien bietet, dass die Ausgabe Ihres Rückrufs synchron mit der Video-Framerate bleibt. Es kann sein, dass er ein vertikales Synchronisation (v-sync) später ausgelöst wird, nachdem das neue Videoframe präsentiert wurde. (V-sync ist eine Grafiktechnologie, die die Framerate eines Videos mit der Bildwiederholfrequenz eines Monitors synchronisiert.)
Die API läuft auf dem Hauptthread, während die Videokomposition wahrscheinlich auf einem separaten Kompositionsthread erfolgt. Sie müssen die Zeit berücksichtigen, die für den Abschluss dieser Operationen erforderlich ist, sowie die Zeit, die das Video selbst und das Ergebnis Ihrer requestVideoFrameCallback()
-Operation benötigen, um auf dem Bildschirm angezeigt zu werden.
Sie können den now
-Callback-Parameter und die expectedDisplayTime
-Metadateneigenschaft vergleichen, um festzustellen, ob Ihr Rückruf ein v-sync zu spät ist. Wenn expectedDisplayTime
innerhalb von etwa fünf bis zehn Mikrosekunden von now
liegt, ist das Frame bereits gerendert. Wenn die expectedDisplayTime
ungefähr sechzehn Millisekunden in der Zukunft liegt (vorausgesetzt, Ihr Browser/Bildschirm aktualisiert mit 60Hz), dann ist der Rückruf ein v-sync aus.
Beispiele
Zeichnen von Videoframes auf eine Leinwand
Dieses Beispiel zeigt, wie requestVideoFrameCallback()
verwendet wird, um die Frames eines Videos auf ein <canvas>
-Element mit genau derselben Bildrate wie das Video zu zeichnen. Es protokolliert auch die Frame-Metadaten zur DOM für Debugging-Zwecke.
if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) {
const video = document.createElement("video");
const fpsInfo = document.createElement("div");
const metadataInfo = document.createElement("div");
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org
// Poster from peach.blender.org
video.src =
"https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4";
video.poster =
"https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217";
video.width = 640;
video.controls = true;
document.body.append(video, fpsInfo, metadataInfo, canvas);
let paintCount = 0;
let startTime = 0.0;
const updateCanvas = (now, metadata) => {
if (startTime === 0.0) {
startTime = now;
}
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const elapsed = (now - startTime) / 1000.0;
const fps = (++paintCount / elapsed).toFixed(3);
fpsInfo.innerText = `video fps: ${fps}`;
metadataInfo.innerText = JSON.stringify(metadata, null, 2);
// Re-register the callback to run on the next frame
video.requestVideoFrameCallback(updateCanvas);
};
// Initial registration of the callback to run on the first frame
video.requestVideoFrameCallback(updateCanvas);
} else {
alert("Your browser does not support requestVideoFrameCallback().");
}
Sehen Sie sich die requestVideoFrameCallback Demo für eine funktionierende Implementierung des obigen Codes an.
Spezifikationen
Specification |
---|
HTMLVideoElement.requestVideoFrameCallback() # dom-htmlvideoelement-requestvideoframecallback |
Browser-Kompatibilität
Siehe auch
- Das
<video>
-Element HTMLVideoElement.cancelVideoFrameCallback()
- Effiziente Per-Frame-Operationen auf Video mit
requestVideoFrameCallback()
durchführen auf developer.chrome.com (2023)