Zum Hauptinhalt springen

Erfahren Sie, wie Sie das verwenden requestVideoFrameCallback () para trabajar de manera más eficiente con videos en el navegador.

igraal_de-de


Aktualisiert

In dem Block befindet sich eine neue Web-API, die im definiert ist
HTMLVideoElement.requestVideoFrameCallback ()

especificación. los requestVideoFrameCallback () El método permite a los autores web registrar una devolución de llamada que se ejecuta en los pasos de renderizado cuando se envía un nuevo fotograma de vídeo al compositor. Esto está destinado a permitir a los desarrolladores realizar operaciones eficientes por cuadro de video en video, como procesamiento de video y pintura en un lienzo, análisis de video o sincronización con fuentes de audio externas.

Unterschied zu requestAnimationFrame ()

Vorgänge wie das Zeichnen eines Videorahmens auf einer Leinwand mit
drawImage ()

realizado a través de esta API se sincronizará como mejor esfuerzo con la velocidad de fotogramas del video que se reproduce en la pantalla. Diferente de
window.requestAnimationFrame (), die typischerweise etwa 60 Mal pro Sekunde feuert,
requestVideoFrameCallback () está vinculado a la velocidad de fotogramas de vídeo real, con una importante
excepción:

La tasa efectiva a la que se ejecutan las devoluciones de llamada es la tasa menor entre la tasa del video y la tasa del navegador. Esto significa que un video de 25 fps que se reproduce en un navegador que pinta a 60Hz dispararía devoluciones de llamada a 25Hz. Un video de 120 fps en ese mismo navegador de 60Hz dispararía devoluciones de llamada a 60Hz.

¿Lo que hay en un nombre?

Aufgrund seiner Ähnlichkeit mit window.requestAnimationFrame (), el método inicialmente fue vorgeschlagen als video.requestAnimationFrame (), aber ich bin zufrieden mit dem neuen Namen,
requestVideoFrameCallback (), que se acordó tras un larga discusión. Hurra, Fahrräder ¡por la victoria!

Soporte de navegador y detección de funciones

El método es
in Chrom implementiert
schon und
Mozilla-Leute mögen. Por lo que vale, también he presentado una
WebKit-Fehler pedirlo. La detección de características de la API funciona así:

if ( 'requestVideoFrameCallback' in HTMLVideoElement . Prototyp ) {
}}

Usando el método requestVideoFrameCallback ()

Wenn Sie jemals die verwendet haben requestAnimationFrame () método, inmediatamente se sentirá como en casa con el requestVideoFrameCallback () método. Usted registra una devolución de llamada inicial una vez y luego vuelve a registrarse cada vez que se activa la devolución de llamada.

const doSomethingWithTheFrame = (jetzt Metadaten) => {
Konsole . log (jetzt, Metadaten);
Video . requestVideoFrameCallback ( doSomethingWithTheFrame ) ;
} ;
Video . requestVideoFrameCallback ( doSomethingWithTheFrame ) ;

En la devolución de llamada, jetzt ist ein DOMHighResTimeStamp

y Metadaten ist ein VideoFrameMetadata

Wörterbuch mit folgenden Eigenschaften:

  • Präsentationszeitvom Typ DOMHighResTimeStamp: El momento en el que el agente de usuario envió el marco para su composición.
  • expectedDisplayTimevom Typ DOMHighResTimeStamp: Die Zeit, zu der der Benutzeragent erwartet, dass der Frame sichtbar ist.
  • Breitevom Typ lange nicht signiert: El ancho del fotograma de video, en píxeles de medios.
  • Höhevom Typ lange nicht signiert: La altura del fotograma de vídeo, en píxeles multimedia.
  • mediaTimevom Typ doppelt: La marca de tiempo de presentación de medios (PTS) en segundos del fotograma presentado (por ejemplo, su marca de tiempo en el video.currentTime línea de tiempo).
  • präsentierte Framesvom Typ lange nicht signiert: Recuento del número de fotogramas enviados para composición. Permite a los clientes determinar si se perdieron tramas entre instancias de VideoFrameRequestCallback.
  • VerarbeitungDauervom Typ doppelt: La duración transcurrida en segundos desde el envío del paquete codificado con la misma marca de tiempo de presentación (PTS) que esta trama (por ejemplo, igual que la mediaTime) al decodificador hasta que la trama decodificada esté lista para su presentación.

Bei WebRTC-Anwendungen werden möglicherweise zusätzliche Eigenschaften angezeigt:

  • CaptureTimevom Typ DOMHighResTimeStamp: Para los fotogramas de video que provienen de una fuente local o remota, este es el momento en el que la cámara capturó el fotograma. Para una fuente remota, el tiempo de captura se estima mediante la sincronización del reloj y los informes del remitente RTCP para convertir las marcas de tiempo RTP en tiempo de captura.
  • receiveTimevom Typ DOMHighResTimeStamp: Para las tramas de video que provienen de una fuente remota, esta es la hora a la que la plataforma recibió la trama codificada, es decir, la hora a la que se recibió el último paquete perteneciente a esta trama a través de la red.
  • rtpTimestampvom Typ lange nicht signiert: La marca de tiempo RTP asociada con este fotograma de vídeo.

Beachten Sie, dass Breite y Höhe kann abweichen von videoWidth y videoHöhe en ciertos casos (por ejemplo, un video anamórfico puede tener píxeles rectangulares).

De especial interés en esta lista es mediaTime. En la implementación de Chromium, usamos el reloj de audio como fuente de tiempo que respalda video.currentTimeInzwischen er mediaTime está poblado directamente por el 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.

Desafortunadamente, el elemento de video no garantiza una precisión de cuadro suchen. Dies war eine kontinuierliche tema de discusión.
WebCodecs eventualmente permitirá aplicaciones con precisión de cuadros.

Si las cosas parecen un cuadro de distancia …

La sincronización vertical (o simplemente vsync) es una tecnología de gráficos que sincroniza la frecuencia de cuadros de un video y la frecuencia de actualización de un monitor. Ya que requestVideoFrameCallback () se ejecuta en el hilo principal, pero, bajo el capó, la composición de video ocurre en el hilo del compositor, todo desde esta API es un mejor esfuerzo y no ofrecemos ninguna garantía estricta. Lo que puede estar sucediendo es que la API puede retrasarse un vsync en relación con el momento en que se procesa un fotograma de video. Se necesita un vsync para que los cambios realizados en la página web a través de la API aparezcan en la pantalla (igual que window.requestAnimationFrame ()). Also, wenn Sie weiter aktualisieren mediaTime o el número de fotograma en su página web y compárelo con los fotogramas de video numerados, eventualmente el video se verá como si estuviera un fotograma por delante.

Lo que realmente está sucediendo es que el marco está listo en vsync x, la devolución de llamada se activa y el marco se procesa en vsync x + 1, y los cambios realizados en la devolución de llamada se procesan en vsync x + 2. Puede verificar si la devolución de llamada es un vsync tardío (y el marco ya está renderizado en la pantalla) verificando si el metadata.expectedDisplayTime ist circa jetzt o un vsync en el futuro. Si está dentro de unos cinco a diez microsegundos de jetzt, el marco ya está renderizado; Si el expectedDisplayTime es aproximadamente dieciséis milisegundos en el futuro (suponiendo que su navegador / pantalla se actualice a 60Hz), entonces está sincronizado con el marco.

Manifestación

He creado un pequeño
demostración en Glitch
que muestra cómo se dibujan los fotogramas en un lienzo exactamente a la velocidad de fotogramas del video y dónde se registran los metadatos del fotograma para fines de depuración. La lógica central es solo un par de líneas de 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

He realizado procesamiento a nivel de fotogramas durante mucho tiempo, sin tener acceso a los fotogramas reales, solo en función de video.currentTime. Implementé la segmentación de tomas de video en JavaScript de una manera aproximada; todavía puedes leer el adjunto
trabajo de investigación. Tenía el requestVideoFrameCallback () existía en ese entonces, mi vida hubiera sido mucho más simple …

Vielen Dank

das requestVideoFrameCallback Die API wurde von spezifiziert und implementiert
Thomas Guilbert. Este artículo fue revisado por Joe Medley
y Kayce Basques.
Imagen de héroe zum
Denise Jans auf Unsplash.