Contenidos
Erfahren Sie, wie Sie das verwenden requestVideoFrameCallback ()
um effizienter mit Videos im Browser zu arbeiten.
Aktualisiert
In dem Block befindet sich eine neue Web-API, die im definiert ist
HTMLVideoElement.requestVideoFrameCallback ()
Spezifikation. das requestVideoFrameCallback ()
Mit dieser Methode können Webautoren einen Rückruf aufzeichnen, der die Rendering-Schritte durchläuft, wenn ein neuer Videorahmen an den Komponisten gesendet wird. Dies soll Entwicklern ermöglichen, effiziente Vorgänge pro Bild von Video zu Video auszuführen, z. B. Videoverarbeitung und Malen auf einer Leinwand, Videoanalyse oder Synchronisierung mit externen Audioquellen.
Unterschied zu requestAnimationFrame ()
Vorgänge wie das Zeichnen eines Videorahmens auf einer Leinwand mit
drawImage ()
Über diese API erstellte Daten werden nach bestem Wissen und Gewissen mit der Bildrate des auf dem Bildschirm abgespielten Videos synchronisiert. Anders als
window.requestAnimationFrame ()
, die typischerweise etwa 60 Mal pro Sekunde feuert,
requestVideoFrameCallback ()
ist an die tatsächliche Videobildrate gebunden, mit einem wichtigen
Ausnahme:
Die effektive Rate, mit der Rückrufe ausgeführt werden, ist die niedrigere Rate der Videorate und der Browserrate. Dies bedeutet, dass ein 25-fps-Video, das in einem Browser abgespielt wird, der mit 60 Hz malt, Rückrufe mit 25 Hz auslöst. Ein 120-fps-Video in demselben 60-Hz-Browser würde 60-Hz-Rückrufe auslösen.
Was ist in einem Namen?
Aufgrund seiner Ähnlichkeit mit window.requestAnimationFrame ()
war die Methode zunächst vorgeschlagen als video.requestAnimationFrame ()
, aber ich bin zufrieden mit dem neuen Namen,
requestVideoFrameCallback ()
, die nach a vereinbart wurde lange Diskussion. Hurra, Fahrräder für den Sieg!
Browserunterstützung und Funktionserkennung
Die Methode ist
in Chrom implementiert
schon und
Mozilla-Leute mögen. Für das, was es wert ist, habe ich auch eine eingereicht
WebKit-Fehler Danach fragen. Die API-Funktionserkennung funktioniert folgendermaßen:
if ( 'requestVideoFrameCallback' in HTMLVideoElement . Prototyp ) {
}}
Verwenden der requestVideoFrameCallback () -Methode
Wenn Sie jemals die verwendet haben requestAnimationFrame ()
Methode, werden Sie sich mit der sofort zu Hause fühlen requestVideoFrameCallback ()
Methode. Sie registrieren einen ersten Rückruf einmal und registrieren ihn dann jedes Mal neu, wenn der Rückruf ausgelöst wird.
const doSomethingWithTheFrame = (jetzt Metadaten) => {
Konsole . log (jetzt, Metadaten);
Video . requestVideoFrameCallback ( doSomethingWithTheFrame ) ;
} ;
Video . requestVideoFrameCallback ( doSomethingWithTheFrame ) ;
Im Rückruf jetzt
ist ein DOMHighResTimeStamp
y Metadaten
ist ein VideoFrameMetadata
Wörterbuch mit folgenden Eigenschaften:
Präsentationszeit
vom TypDOMHighResTimeStamp
: Die Zeit, zu der der Benutzeragent den Frame zur Komposition gesendet hat.expectedDisplayTime
vom TypDOMHighResTimeStamp
: Die Zeit, zu der der Benutzeragent erwartet, dass der Frame sichtbar ist.Breite
vom Typlange nicht signiert
: Die Breite des Videorahmens in Medienpixeln.Höhe
vom Typlange nicht signiert
: Die Höhe des Videorahmens in Multimedia-Pixeln.mediaTime
vom Typdoppelt
: Der Zeitstempel für die Medienanzeige (PTS) in Sekunden des angezeigten Frames (z. B. Ihr Zeitstempel in dervideo.currentTime
Zeitleiste).präsentierte Frames
vom Typlange nicht signiert
: Anzahl der Frames, die zur Komposition gesendet wurden. Ermöglicht Kunden zu bestimmen, ob Frames zwischen Instanzen von verloren gegangen sindVideoFrameRequestCallback
.VerarbeitungDauer
vom Typdoppelt
: Die verstrichene Dauer in Sekunden seit dem Senden des Pakets, das mit demselben Präsentationszeitstempel (PTS) wie dieser Frame codiert wurde (z. B. derselbe wie dermediaTime
) an den Decoder, bis der decodierte Rahmen zur Präsentation bereit ist.
Bei WebRTC-Anwendungen werden möglicherweise zusätzliche Eigenschaften angezeigt:
CaptureTime
vom TypDOMHighResTimeStamp
: Bei Videobildern, die von einer lokalen oder Remote-Quelle stammen, ist dies der Moment, in dem die Kamera das Bild aufgenommen hat. Für eine Remote-Quelle wird die Erfassungszeit mithilfe der Synchronisierung und Berichterstellung der RTCP-Senderuhr geschätzt, um RTP-Zeitstempel in Erfassungszeit umzuwandeln.receiveTime
vom TypDOMHighResTimeStamp
: Bei Video-Frames, die von einer Remote-Quelle stammen, ist dies die Zeit, zu der die Plattform den codierten Frame empfangen hat, dh die Zeit, zu der das letzte zu diesem Frame gehörende Paket über das Netzwerk empfangen wurde.rtpTimestamp
vom Typlange nicht signiert
: Der diesem Videorahmen zugeordnete RTP-Zeitstempel.
Beachten Sie, dass Breite
y Höhe
kann abweichen von videoWidth
y videoHöhe
In bestimmten Fällen (z. B. kann ein anamorphotisches Video rechteckige Pixel aufweisen).
Von besonderem Interesse in dieser Liste ist mediaTime
. In der Chromium-Implementierung verwenden wir die Audiouhr als unterstützte Zeitquelle video.currentTime
Inzwischen er mediaTime
wird direkt von der bevölkert Präsentationszeitstempel
des Rahmens. das mediaTime
Dies ist zu verwenden, wenn Sie die Frames auf reproduzierbare Weise genau identifizieren möchten, auch um genau die Frames zu identifizieren, die verloren gegangen sind.
Leider garantiert das Videoelement keine Bildgenauigkeit suchen. Dies war eine kontinuierliche Diskussionsthema.
WebCodecs es wird schließlich rahmengenaue Anwendungen ermöglichen.
Wenn die Dinge wie eine Kiste entfernt scheinen ...
Vertikale Synchronisierung (oder einfach vsync) ist eine Grafiktechnologie, die die Bildrate eines Videos und die Bildwiederholfrequenz eines Monitors synchronisiert. Wie requestVideoFrameCallback ()
Es läuft im Haupt-Thread, aber unter der Haube findet Video-Compositing im Composer-Thread statt. Alles von dieser API ist eine Bestleistung und wir bieten keine strengen Garantien. Was möglicherweise passiert, ist, dass die API im Vergleich zum Rendern eines Videobilders möglicherweise hinter einem vsync zurückbleibt. Ein vsync ist erforderlich, damit Änderungen, die über die API an der Webseite vorgenommen werden, auf dem Bildschirm angezeigt werden (wie bei window.requestAnimationFrame ()
). Also, wenn Sie weiter aktualisieren mediaTime
oder die Bildnummer auf Ihrer Webseite und vergleichen Sie sie mit den nummerierten Videobildern. Schließlich sieht das Video so aus, als ob es ein Bild vor Ihnen liegt.
Was tatsächlich passiert, ist, dass der Frame in vsync x bereit ist, der Rückruf ausgelöst wird und der Frame in vsync x + 1 verarbeitet wird und die am Rückruf vorgenommenen Änderungen in vsync x + 2 verarbeitet werden. Sie können überprüfen, ob der Rückruf erfolgt ist eine späte vsync (und der Frame wird bereits auf dem Bildschirm gerendert), indem überprüft wird, ob die metadata.expectedDisplayTime
ist circa jetzt
oder ein vsync in der Zukunft. Wenn es innerhalb von fünf bis zehn Mikrosekunden von ist jetzt
ist der Rahmen bereits gerendert; Wenn er expectedDisplayTime
Es ist ungefähr 16 Millisekunden in der Zukunft (vorausgesetzt, Ihr Browser / Bildschirm wird auf 60 Hz aktualisiert), dann ist es mit dem Frame synchronisiert.
Manifestation
Ich habe eine kleine erstellt
Glitch-Demo
Hier wird gezeigt, wie Frames mit genau der Framerate des Videos auf einer Leinwand gezeichnet werden und wo Frame-Metadaten zu Debugging-Zwecken aufgezeichnet werden. Die Kernlogik besteht nur aus ein paar Zeilen JavaScript.
let paintCount = 0 ;
let startTime = 0.0 ; const updateCanvas = (jetzt Metadaten) => {
if ( startTime === 0.0 ) {
startTime = now ;
}}
ctx . drawImage ( Video , 0 , 0 , Leinwand . Breite , Leinwand . Höhe ) ;
const elapsed = ( now - startTime ) / 1000.0 ;
const fps = ( ++ paintCount / elapsed) . toFixed ( 3 ) ;
fpsInfo . innerText = ` video fps: $ { fps } ` ;
metadataInfo . innerText = JSON . stringify ( Metadaten , null , 2 ) ;
Video . requestVideoFrameCallback ( updateCanvas ) ;
} ;
Video . requestVideoFrameCallback ( updateCanvas ) ;
Schlussfolgerungen
Ich habe lange Zeit eine Verarbeitung auf Frame-Ebene durchgeführt und keinen Zugriff auf die eigentlichen Frames gehabt, nur basierend auf video.currentTime
. Ich habe die Segmentierung von Videoaufnahmen in JavaScript grob implementiert. Sie können den Anhang noch lesen
Forschungsarbeit. Hatte die requestVideoFrameCallback ()
existierte damals, mein Leben wäre viel einfacher gewesen ...
Vielen Dank
das requestVideoFrameCallback
Die API wurde von spezifiziert und implementiert
Thomas Guilbert. Dieser Artikel wurde von überprüft Joe Medley
y Kayce Basques.
Heldenbild zum
Denise Jans auf Unsplash.