Video Summary and Transcription
Esta charla explora los desafíos y soluciones en la codificación de video con códecs web. Discute el dibujo y la grabación de video en la web, la captura y codificación de fotogramas de video, e introduce la API de WebCodecs. La charla también cubre la configuración del codificador de video, la comprensión de los códecs y contenedores, y el proceso de codificación de video con muxing usando ffmpeg. El orador comparte su experiencia en la construcción de una herramienta de edición de video en el navegador y muestra Slantit, una herramienta para hacer videos de productos.
1. Introducción a la codificación de video con Web Codecs
Bienvenidos a mi charla sobre cómo llevar al límite la codificación de video con web codecs. Mi nombre es Akash Hameedwasia. Escribo código en Razorpay. También me encanta construir productos en la web y contribuir al open-source. Quizás me conozcas por algunos de mis proyectos mencionados aquí, Blaze, Untabbed, Dyod, o Slanted.
Espero que todos estén pasando un gran momento en JS Nation 2023. Bienvenidos a mi charla sobre cómo llevar al límite la codificación de video con web codecs. Mi nombre es Akash Hameedwasia. Escribo código en Razorpay. También me encanta construir productos en la web y contribuir al open-source. Quizás me conozcas por algunos de mis proyectos mencionados aquí, Blaze, Untabbed, Dyod, o Slanted. Si no conoces estos proyectos, te sugiero fuertemente que los revises. También puedes conectarte conmigo en mi Twitter, GitHub, o también revisar mis charlas pasadas, blogs pasados, y también varios proyectos en mi sitio web personal, AkashHameedwasia.com.
2. Construyendo una Herramienta de Edición de Video en el Navegador
En esta charla, compartiré los aprendizajes que tuve mientras construía una herramienta de edición de video en el navegador. Encontré desafíos con la codificación de video, audio, muxing y codecs, pero finalmente descubrí todo.
Entonces, antes de comenzar nuestro viaje para entender cómo usar los web codecs, aquí hay una pequeña historia de fondo. Hace un tiempo, estaba construyendo una herramienta de edición de video en el navegador que me permitiría hacer videos de productos realmente atractivos muy rápidamente. Hay varias herramientas de edición de video por ahí, pero están basadas en el escritorio, así que tienes que descargarlas y son bastante grandes. Y luego tienes que aprender a usarlas, y luego toman mucho tiempo para exportar un video. Pensé, ¿por qué no?, hagamos una herramienta simple. Porque tengo muchas necesidades de edición de video para todos mis proyectos. Construyamos un editor de video simple en el navegador para que pueda usarlo para exportar videos realmente Ahora, todo iba bien hasta que empecé a escribir code para el proceso de exportación. Me quedé atascado en un montón de lugares. Codificación de video, audio, navegación, muxing, codecs, un montón de jerga, muchos lugares para quedarse atascado. Pero finalmente pude descubrir todo, y esto es lo que quiero compartir con ustedes en esta charla, todos los aprendizajes que tuve de cómo abordar la construcción de algo como esto.
3. Dibujando y Grabando Video en la Web
Comencemos discutiendo cómo dibujar un video en la web. Existen diferentes formas de renderizar fotogramas de video, como animaciones CSS, manipulación del DOM de JavaScript, SVG y HTML Canvas. HTML Canvas proporciona flexibilidad y permite diversas funcionalidades. Para grabar los fotogramas y guardarlos como un video, podemos usar la API de captura de transmisión en HTML5 canvas. Esta API nos permite crear un objeto de grabación de medios y adjuntar oyentes de eventos para almacenar y procesar los datos grabados. Sin embargo, este método tiene sus limitaciones, incluyendo la falta de una tasa de fotogramas constante.
Entonces, comencemos una discussion primero discutiendo cómo dibujar algo como un video en la web. Entonces, video puede simplemente definirse como un conjunto de fotogramas de imagen que cambian a una tasa constante. Ahora, cada fotograma de este video puede renderizarse de varias maneras. Por lo tanto, puedes usar CSS animations para definir los fotogramas individuales. Puedes modificar el DOM directamente usando JavaScript. También puedes usar algo como SVG, esto es algo que los archivos Lottie usan para renderizar las animations de Lottie en el navegador. O también puedes usar algo llamado HTML Canvas.
Ahora, la API de HTML Canvas es un poco verbosa, pero también te da mucha flexibilidad para hacer muchas cosas variadas. Y te sugiero fuertemente que uses HTML5 canvas para hacer algo como esto. Y como verás en la charla, la API de canvas permite varias cosas que podemos hacer, que los otros métodos de renderizado no pueden.
Entonces, una vez que tienes los fotogramas renderizados en la pantalla para crear un video a partir de ellos, simplemente es cuestión de grabarlo y guardarlo como un archivo de video. Suena fácil en la diapositiva, pero ¿cómo grabas algo en la pantalla usando JavaScript? Bueno, si estás usando HTML5 canvas, ya tienes suerte porque canvas ya permite la captura de video. Y esto es posible a través de la API de captura de transmisión, que es parte del estándar de la API de grabación de transmisión de medios.
Entonces, aquí tienes algo de code que te muestra cómo puedes hacer algo con la captura de transmisión. Define una función llamada grabar, que toma una duración, y creamos una transmisión a partir del elemento canvas usando la captura de transmisión. El primer parámetro es la tasa de fotogramas. Aquí simplemente lo estoy estableciendo en 30 para 30 fotogramas por segundo. Luego paso esa transmisión y creo un nuevo objeto de grabador de medios. Este grabador es lo que usaremos para grabar el video de canvas. Antes de que podamos empezar a grabar, necesitamos adjuntar a los oyentes de eventos en el grabador. El primero es data disponible. Así que cada vez que hay algunos data disponibles en el grabador, en lugar de, ya sabes, transmitir por la red o hacer algo, simplemente almacenamos esos data dentro de un array de fragmentos. Luego adjuntamos otro oyente de eventos, que es el oyente de eventos de parada. Así que cuando el grabador se detiene, hemos tomado todos los fragmentos acumulados de data, procesado como un archivo blob y lo descargamos como un blob de tipo video/webinar. Y una vez que los oyentes de eventos están adjuntos, simplemente es cuestión de iniciar el grabador y detenerlo después de que haya transcurrido la duración.
Ahora, este code parece muy simple, ¿verdad? Y realmente esperaba que todo este proceso fuera tan simple. Pero tristemente, no lo es. Este método completo de usar la captura de transmisión, no está realmente bien adaptado para este caso de uso. Y hay cuatro razones para ello. La primera es que no hay una tasa de fotogramas constante con este enfoque.
4. Capturando y Codificando Fotogramas de Video
La función de captura de transmisión permite capturar fotogramas de video, pero carece de una tasa de fotogramas constante y la opción de cambiar el formato de video de salida. La fiabilidad y calidad de la salida dependen del rendimiento del dispositivo. Para superar estas limitaciones, podemos capturar y codificar individualmente los fotogramas del lienzo nosotros mismos. Utilizando pseudocódigo, podemos buscar el lienzo en cada fotograma, capturarlo como una imagen y almacenar los fotogramas en un array. Luego, podemos codificar el array de imágenes en un archivo de video utilizando bibliotecas como WAMI.js, un codificador WebM JavaScript en tiempo real.
La función de captura de transmisión que vimos toma un parámetro, que es la tasa de fotogramas. Pero en realidad es la tasa de fotogramas máxima en la que el video debe ser capturado. Ahora, si el dispositivo en el que el lienzo, ya sabes, está renderizando los fotogramas, si es un dispositivo de bajo rendimiento, el navegador podría decidir eliminar fotogramas para mejorar el performance de renderizado de los fotogramas en el lienzo. Y esto es, ya sabes, lleva a una menor fiabilidad. Podrías tener, ya sabes, el mismo code trabajando en dos dispositivos diferentes, dándote dos salidas diferentes.
Así que no hay una tasa de fotogramas constante, el navegador podría en cualquier momento decidir eliminar fotogramas para aumentar el performance. No hay opción para cambiar el formato del video, siempre produce una salida del formato WebM, que no es realmente común con al menos, ya sabes, otros softwares de reedición si estás tratando de hacer algo con ellos. Hay una baja fiabilidad como mencioné, el code podría darte dos salidas diferentes en dos dispositivos diferentes debido al performance de ambos. Y la salida también es de calidad decente, nada demasiado genial, podría ser mala porque de los fotogramas que se eliminan. Pero sí, honestamente depende del performance del dispositivo.
Ahora, podría parecer que estoy tratando de criticar las APIs de grabación de medios aquí, pero honestamente no están diseñadas para exportaciones de video tan precisas y de alta calidad. Las APIs de grabación de medios son mucho más adecuadas para aplicaciones en tiempo real donde un compromiso de calidad es aceptable siempre y cuando estés obteniendo velocidades más altas. Entonces, si la captura de transmisión no puede funcionar, ¿podemos capturar y codificar individualmente los fotogramas de el lienzo nosotros mismos? Así que aquí hay un pseudocódigo con esta idea. Así que aquí lo que hago es en el bucle, busco el lienzo en cada fotograma, lo capturo como una imagen, y luego proceso todos los fotogramas de la animation a un solo archivo de video. El bucle comienza buscando el lienzo en el fotograma. Así que aquí lo he buscado en el fotograma uno. Luego capturo el fotograma como una imagen usando la función toDataUrl. Y luego le doy image-webp para capturarlo como un archivo de imagen WebP. Y luego, una vez que la imagen está lista, la empujo dentro del array de imágenes. Luego, busco el siguiente fotograma, lo capturo como una imagen y lo almaceno en el array de imágenes. Y una vez que eso se ha hecho para todos los fotogramas, salgo del bucle y con ese array de imágenes que tengo, puedo pasarlo a una función de codificación para codificarlo como un archivo de video y descargarlo en el dispositivo del usuario.
Ahora la verdadera pregunta aquí es, ¿cómo codificas un array de imágenes a un video? Ahora este no es un problema fácil de resolver porque hasta ahora, los navegadores no han tenido una forma nativa de permitirte tomar un array de imágenes y convertirlo en un solo archivo de video. Hay varias bibliotecas por ahí, y en este punto también me gustaría mencionar a WAMI.js. WAMI es un codificador WebM JavaScript en tiempo real. Apareció en Hacker News hace 11 años, lo cual es algo loco. Pero lo que hace es que esencialmente toma instantáneas del lienzo como imágenes y las codifica a un archivo de video. Y esto es exactamente lo que estamos tratando de hacer. Tomar un lienzo, renderizar el fotograma, capturarlo como imagen, codificarlos como un archivo de video. Así es como se ve la función para codificar usando WAMI. Así que WAMI expone una función llamada fromImageArray, toma un array de imágenes, que son los fotogramas individuales de tu video.
5. Descubriendo un Nuevo Estándar Interesante
Puedes definir la tasa de fotogramas de tu video y descargarlo. Las bibliotecas de JavaScript para codificar videos tienen pros y contras. Los pros incluyen una salida de alta calidad y una tasa de fotogramas constante. Los contras incluyen un proceso lento y sincrónico, falta de aceleración de hardware, formatos de video limitados y falta de soporte de audio. Sin embargo, descubrí un nuevo estándar interesante que resuelve estos problemas.
Y luego defines la tasa de fotogramas de tu video, que en mi caso es 30, y te dará un archivo de video que puedes descargar en el dispositivo del usuario. Puedes ver WAMI en su repositorio de GitHub aquí.
Ahora, he probado muchas de estas bibliotecas de JavaScript para codificar un video a partir de fotogramas de imagen, pero he descubierto que todas ellas comparten el mismo conjunto de pros y contras.
Pasando a los pros. El primer pro es que obtienes una salida de alta calidad, porque estamos haciendo manualmente, ya sabes, la búsqueda, capturando como imagen y luego codificando. Obtenemos una salida de alta calidad. Obtenemos una tasa de fotogramas constante porque no hay forma de que se pueda perder un fotograma ya que estamos buscando manualmente y asegurándonos de que se capture cada fotograma. Todo el proceso también fue relativamente fácil. Mientras tengas una buena biblioteca como WAMI para hacer el proceso de codificación, el resto del código fue realmente sencillo de entender.
Ahora, pasando a la lista de contras. Aquí es donde la lista es en realidad más larga, y eso es bastante desafortunado. El primer contra es que el proceso es muy lento. Y esto se debe a que todo el proceso es sincrónico. La función de dos datos URL que vimos, es en realidad sincrónica. También es intensiva en términos de rendimiento. También es intensiva en términos de cálculo. Por lo tanto, lleva tiempo darte ese archivo de imagen. No hay aceleración de hardware. Así que incluso si tu hardware soporta algunas optimizaciones para hacer el proceso de codificación de video, tu JavaScript no será capaz de aprovechar estas optimizaciones para hacer este proceso de codificación de video más rápido. Y eso de nuevo conduce a un lento rendimiento. También no hay elección de los formatos de video. Estás atrapado en el formato WebM y no hay soporte para añadir audio. La mayoría de estas bibliotecas de JavaScript sólo te permiten codificar un conjunto de imágenes a un archivo de video, pero no te permiten añadir audio también en ese archivo de video.
¿Y ahora qué? Parece que hemos llegado a un callejón sin salida. Y honestamente, en este punto, me había rendido. Probé muchas bibliotecas de JS, muchos enfoques para resolver este problema, pero la mayoría de ellos tenían algún contra que llevaba a una salida de mala calidad. Pero finalmente me topé con este nuevo estándar interesante que apareció en los navegadores, pero no suficientes personas han estado hablando de él. También hay muy poca documentación en línea sobre él. Y espero que esta charla llene ese vacío y te dé el conocimiento que necesitas para trabajar con este estándar interesante. Este nuevo estándar que ha aterrizado es redoble de tambores.
6. Introducción a WebCodecs
WebCodecs son un conjunto de APIs que te proporcionan acceso de bajo nivel a los fotogramas individuales de una transmisión de video. Te permite realizar el proceso de codificación y decodificación en fotogramas individuales en varios formatos. WebCodecs es asíncrono y acelerado por hardware, proporcionando un alto rendimiento. Admite la codificación y decodificación de video y audio, con un enfoque en la codificación de video en esta charla.
Es WebCodecs. Entonces, ¿qué es WebCodecs? WebCodecs son un conjunto de APIs que te proporcionan acceso de bajo nivel a los fotogramas individuales de una transmisión de video. Así que lo que WebCodecs te permite hacer es una vez que tienes acceso a estos fotogramas individuales, te permite realizar el proceso de codificación y decodificación en fotogramas individuales en varios formatos. Lo bueno de WebCodecs es que es asíncrono y también está acelerado por hardware. Así que obtienes un alto rendimiento debido a estas dos características. Y WebCodecs es más que solo video. También admite audio. Puedes hacer codificación de video, decodificación, codificación de audio, decodificación. Las APIs son vastas. Pero en esta charla, solo me centraré en los aspectos de codificación de video de WebCodecs.
7. Proceso de Codificación de Video y Uso de WebCodecs
La API de WebCodecs proporciona acceso de bajo nivel a fotogramas individuales, lo que la hace útil para construir editores de video o audio. El proceso de codificación de video implica definir la fuente de entrada, convertirla en un objeto de fotograma de video y pasarlo a un codificador de video para codificar múltiples fotogramas en un solo fragmento de video codificado. Nos centraremos en el aspecto de almacenamiento del fragmento de video codificado. Para codificar videos usando WebCodecs, creamos un codificador de video y usamos devoluciones de llamada para manejar los fragmentos de video codificados y los errores.
Ahora, el otro día estaba revisando el artículo de WebCodecs en MDN. Este es el primer párrafo del artículo, y hay una parte de este artículo que me emocionó mucho cuando lo vi por primera vez. No sé si lo notaste, pero esto es de lo que estoy hablando. Entonces, lo que esencialmente dice es que la API de WebCodecs proporciona acceso de bajo nivel a fotogramas individuales y es útil para construir aplicaciones como editores de video o audio. Y esto es exactamente lo que estoy construyendo. Así que sentí que estaba en el camino correcto y que usar WebCodecs eventualmente me llevaría a la solución correcta del proceso de exportación.
Entonces, veamos el proceso de codificación de video a un alto nivel. Todo el proceso se divide en realidad en tres partes. La primera parte es definir tu fuente de entrada. Aquí es donde defines cómo ingresas los data al codificador de video. Ahora hay tres formas de codificar o renderizar data que WebCodecs puede usar. La primera es usar Canvas para dibujar tus fotogramas. La segunda es usar ImageBitmap, la tercera es MediaStreamTracks y también puedes usar ArrayBuffers para definir data de píxeles individuales manualmente, pero en esta charla usaré Canvas. Por eso es por lo que te sugerí que usaras Canvas en primer lugar.
Entonces, una vez que tienes lista tu fuente de entrada, el siguiente paso es convertir esa fuente de entrada en un objeto de fotograma de video. Este objeto de fotograma de video se pasa a un codificador de video que creamos y ese codificador de video toma múltiples fotogramas de video y los codifica en un solo fragmento de video codificado. Una vez que el fragmento de video codificado está listo, podemos hacer varias cosas con él. Podemos transmitirlo por la red, podemos transmitirlo por almacenamiento, podemos almacenarlo en algún otro lugar. Podemos hacer varias cosas con él. Pero en nuestra charla solo nos centraremos en el aspecto de almacenamiento de este fragmento de video codificado. Entonces, finalmente, veamos algo de code para codificar videos usando web codecs.
El primer paso en todo este proceso es crear un codificador de video. El constructor de esta clase de codificador de video toma dos devoluciones de llamada. La primera es output. Entonces, esto se llama cada vez que el codificador de video tiene un fragmento de video codificado listo. Y podemos hacer algo con este fragmento. Podemos transmitirlo por la red, podemos almacenarlo. También hay una devolución de llamada de error. Entonces, cada vez que ocurre un error, se llamará a esta devolución de llamada. Ahora, como mencioné, ya que estamos interesados en almacenar este fragmento para procesarlo más tarde, crearemos un array de fragmentos y almacenaremos todos los fragmentos dentro de este array y lo procesaremos más tarde.
8. Configurando el Codificador de Video
Para el manejo de errores, se utiliza un registro de consola. El codificador de video necesita ser configurado con varias opciones como el códec, la aceleración de hardware, la tasa de fotogramas y el modo de latencia. El códec es la opción más importante. Encontrar el códec correcto no es tan fácil como WebM MP4 AVI. El códec de video no es lo mismo que el formato de archivo de video.
Para el manejo de errores simplemente he puesto un registro en la console. Puedes manejarlo de una mejor manera.
El siguiente paso es realmente configurar el codificador de video. Así que hemos creado el codificador, pero aún no lo hemos configurado a nuestras opciones o a nuestros ajustes que nosotros design. Así que aquí es donde lo hacemos. Llamamos a la configuración con varias opciones. Algunas de las más importantes se mencionan aquí. La primera opción es el códec. Lo discutiremos en gran detalle. Por ahora simplemente lo he establecido como VP8. La segunda opción es la aceleración de hardware. Aquí es donde puedes decirle al navegador que prefiera la aceleración de hardware si el dispositivo la soporta o puedes optar por omitirla o dejar que el navegador decida por sí mismo. La tercera opción es la tasa de fotogramas. Aquí es donde indicas cuál es la tasa de fotogramas de tu video. En este caso es 30. La siguiente opción es el modo de latencia. Aquí es donde indicas si prefieres la calidad o la velocidad del proceso de codificación. Si prefieres la velocidad puedes establecer esto como tiempo real y entonces básicamente tendrás algún compromiso con la calidad pero obtendrás mayor velocidad. Así que eso podría ser útil para aplicaciones en tiempo real. Pero como estoy más interesado en salidas de alta calidad, estableceré el modo de latencia en calidad. Luego hay varias otras opciones con altura o tasa de bits. Pero la opción más importante de todas es en realidad la primera, que es el códec.
Entonces, ¿cómo encontrar el códec correcto? No es tan fácil como WebM MP4 AVI. Obviamente esperaba que fuera tan fácil, pero no lo es. Los códecs en sí, parecen cadenas aleatorias. Ejemplo VP8, AVC1, 420. Blah Blah Blah. Es completamente aleatorio. Parece que son estas cadenas mágicas que simplemente funcionan. Lo principal que quiero que te lleves de esta diapositiva es que el códec de video no es lo mismo que el formato de archivo de video.
9. Entendiendo los Códecs y Contenedores
El códec es un algoritmo para convertir y comprimir los fotogramas individuales del video. La transmisión de video se procesa aún más y se pasa a un multiplexor para crear un contenedor de video. Los videos contienen audio, subtítulos y datos visuales, que son combinados por el multiplexor en un solo contenedor. Los códecs y contenedores deben ser compatibles. Los navegadores admiten diferentes códecs, por lo que la compatibilidad puede variar. Para obtener más información sobre la compatibilidad de los códecs, consulte los enlaces proporcionados.
Y esto es lo que me confundió mucho en todo este viaje. Siempre pensé que el códec es lo mismo que WebM, MP4, AVA, pero son realmente muy diferentes y para entender cuán diferentes son, permíteme darte una introducción a todo el proceso de codificación de video.
Entonces, todo el proceso comienza con los fotogramas individuales. Los fotogramas individuales son los fotogramas de tu video. Hay tres fotogramas en esta demostración. Todos estos fotogramas se pasan a lo que se llama un algoritmo de codificación. Ahora, el trabajo del algoritmo de codificación es tomar los fotogramas, convertirlos, comprimir y almacenarlos en una única transmisión de video. Entonces, este algoritmo de codificación, en otras palabras, se llama códec. Toma fotogramas de video, los convierte, los comprime y almacena los fotogramas en una transmisión de video. Entonces, la salida del códec es una única transmisión de video. Y esto no es lo que se almacena en tu disco duro.
La transmisión de video se procesa aún más y se pasa a lo que se llama un multiplexor para crear lo que se llama un contenedor de video. Entonces, el contenedor de video es lo que contiene tu transmisión de video y este contenedor de video finalmente se almacena en tu disco duro. Entonces, el archivo mp4 que ves, en realidad es un contenedor que internamente tiene transmisión de video data que tiene los datos de los fotogramas individuales.
Ahora te preguntarás por qué necesitamos un multiplexor. ¿No podría el codificador hacer también este paso por nosotros? Bueno, eso es porque los videos no son solo datos visuales, tienen audio, tienen subtítulos y todos estos son parte de un solo archivo. Y la magia de tener todo dentro de un solo archivo es posible gracias al multiplexor. El multiplexor combina o multiplexa varias transmisiones de data en un solo contenedor. Y como puedes ver aquí, este único contenedor video.mp4 tiene video transmisión de data, audio transmisión data, subtítulos y es el trabajo del multiplexor combinar todos ellos juntos.
Entonces, ¿qué es un códec de nuevo? Bueno, el códec es simplemente un algoritmo para convertir y comprimir los fotogramas individuales del video. Un códec y un contenedor deben ser compatibles entre sí para usarlos correctamente. Entonces, si estás usando un contenedor, digamos el contenedor webm, tienes que usar el códec VP8 o AV1 porque el contenedor webm solo puede almacenar transmisiones de video y ponerlo en ese códec. De manera similar, si quieres usar mp4, tienes que usar el códec AVC o el códec AV1. Y las cadenas de ejemplo que he mencionado aquí, estas son las cadenas que tienes que pasar en el parámetro del códec de la función de configuración.
Ahora, para complicar aún más todo el proceso, cada navegador admite un conjunto diferente de códecs. Entonces, este navegador que estás usando podría admitir algún códec, que podría no ser admitido en otro navegador. Entonces sí, eso también fragmenta un poco toda esta API. Pero no voy a profundizar en los códecs ahora, he dejado dos enlaces aquí, que puedes consultar para entender la compatibilidad de varios códecs y lo que significan los números individuales en esas cadenas de códec. Así que te sugiero encarecidamente que los revises. Volviendo al code, esta es la función de configuración.
10. Proceso de Codificación de Video y Muxing con ffmpeg
He configurado el códec como AVC1. Pasamos el lienzo a fotograma de video para crear un fotograma de video. Cerramos el fotograma de video. Una vez que todos los fotogramas de video se han renderizado, vaciamos los datos del fotograma del codificador, cerramos el codificador y concatenamos los datos del fragmento en un solo búfer de matriz. WebCodecs solo maneja los primeros tres pasos del proceso de codificación de video. El muxing de un video en la Web no está bien documentado, pero podemos usar ffmpeg como un muxer para muxar la transmisión de video final al contenedor de video.
He configurado el códec como AVC1. Dado que estoy usando el códec AVC, tengo la opción de pasar algunas opciones más para el formato AVC en sí. Así que aquí estoy indicando que use el formato Annex B, que es simplemente un formato de procesamiento de video. De nuevo, no profundizaré en lo que es. Básicamente tienes opciones para configurar el propio códec también.
Ahora, después de todo este paso, tenemos el codificador de video listo con nosotros que puede tomar fotogramas de video y codificar el video. El siguiente paso es realmente pasar por cada fotograma de nuestro video, renderizarlos en el lienzo y luego convertir ese lienzo en un fotograma de video. Así que pasamos el lienzo a fotograma de video para crear un fotograma de video. También requiere una opción de marca de tiempo, que es básicamente el momento en el que el fotograma aparece en el video. Así que aquí estoy calculando la marca de tiempo a partir del fotograma y la tasa de fotogramas, y como la marca de tiempo está en microsegundos, también lo multipliqué por 1 millón. Así que obtenemos un fotograma de video y luego lo pasamos al codificador de video usando la función ENCODE.
Como nuestro trabajo con el fotograma de video ha terminado, en el siguiente paso cierro el fotograma de video y Esto sigue ocurriendo en cada iteración para todos los fotogramas que tenemos en nuestro video. Ahora, una vez que todos los fotogramas de video se han renderizado y se han pasado al codificador de video, podemos vaciar todos los datos del fotograma del codificador para que los procese y cree los fragmentos, y luego cerramos el codificador porque el trabajo con el codificador ha terminado. Recuerda que habíamos adjuntado una devolución de llamada en el codificador de video cuando lo creamos. Estaba empujando los data en el array de fragmentos. Bueno, con esos datos de fragmento, ya que el array de fragmentos es en realidad un array de arrays, podemos concatenar o aplanar ese array en un solo búfer de matriz y esta función de concatenar búfer básicamente hace eso. Ahora no voy a profundizar en lo que hace concat buffer, pero esencialmente está aplanando el array de fragmentos, combinando múltiples búferes de matriz en un solo búfer de matriz. Hay varios algoritmos en línea que puedes encontrar para hacer esta operación.
Ahora, después de esta operación, podrías pensar que el búfer de video que tenemos simplemente podemos descargarlo, ¿verdad? Eso es el final. Pero no, recuerda el proceso de codificación de video de nuevo. Había varios pasos en esto y WebCodecs solo maneja los primeros tres pasos que es tomar los fotogramas individuales, pasarlos a través de un códec y darte una transmisión de video. El siguiente paso de pasarla a través de un muxer tenemos que manejarlo por nuestra cuenta. Ahora, esta parte no está documentada en ninguna parte, al menos es muy difícil encontrar en línea cómo proceder con el muxing de un video en la Web. Y después de mucho buscar, después de mucho ensayo y error y hacer muchas cosas, pude finalmente averiguar cómo muxar un video de manera confiable en la Web. Y aquí es donde nuestra discussion se desplaza a esta biblioteca de hace una década llamada ffmpeg. No hay discussion de codificación de video que esté completa sin esta biblioteca. Así que ffmpeg es una biblioteca de hace una década escrita en C++ y C para codificar, decodificar, video, audio, y hacer cualquier cosa relacionada con multimedia. Y gracias a WebAssembly, ahora podemos usar ffmpeg en el navegador. Así que aquí estaré usando ffmpeg.wasm para usar ffmpeg en el navegador como un muxer para muxar la final transmisión de video al contenedor de video.
11. Codificación de un Video en el Navegador
Hay varias compilaciones disponibles, pero encontré que esta es la mejor. El siguiente paso es realmente leer la salida después de que se haya realizado el proceso de muxing y eliminar los archivos porque ya no los necesitamos. Y así es como codificas un video en el navegador. La lista de ventajas que obtienes con este enfoque es una salida de alta calidad, una tasa de fotogramas constante, un proceso rápido, aceleración de hardware, soporte para cualquier formato de video y la capacidad de agregar audio. El único inconveniente es que es relativamente difícil, pero espero que esta charla lo haya facilitado para ti. WebCodecs es compatible con todos los navegadores excepto Firefox, y espero que Firefox obtenga soporte pronto. WebAssembly es compatible con todos los navegadores.
Hay varias compilaciones disponibles, pero encontré que esta es la mejor. Así que prueba ffmpeg.wasm. Una vez que ffmpeg.wasm está instalado en el proyecto, llamamos a la función create ffmpeg de la biblioteca. Luego llamamos a load en ese objeto para cargar el archivo WebAssembly. Luego usamos la función ffmpeg.fs para acceder al sistema de archivos y escribir el búfer de video, la transmisión de video dentro del sistema de archivos. El nombre aquí se establece como raw.h264. H264 básicamente le dice a ffmpeg qué códec usamos para codificar esta transmisión en particular. Luego ejecutamos el comando ffmpeg. Este comando que tengo aquí es básicamente para muxing una transmisión de video al contenedor de video final. Muxing, en sí mismo, es un proceso muy barato. Sucede realmente rápido. Así que no hay cuello de botella de performance que pueda ocurrir aquí.
El siguiente paso es realmente leer la salida después de que se haya realizado el proceso de muxing y eliminar los archivos porque ya no los necesitamos. Ese archivo de salida que tenemos, simplemente lo convertimos en un blob y descargamos ese archivo en el dispositivo del usuario. Y así es como codificas un video en el navegador. Puede parecer que hay muchos pasos, pero honestamente, la lista de ventajas que obtienes con este enfoque, literalmente llenará la pantalla. Te lo mostraré ahora. Así que la primera ventaja es que obtienes una salida de alta calidad porque estamos, de nuevo, renderizando cada fotograma, capturándolos y luego codificándolos, obtenemos una salida de alta calidad. Obtenemos una tasa de fotogramas constante porque no hay lugar donde se puedan soltar los fotogramas. Todo el proceso es realmente rápido porque la mayoría de las APIs son asíncronas y también soporta aceleración de hardware. Puedes usar cualquier formato de video siempre que el códec que quieras esté soportado en el navegador. Y también soporta la adición de audio. La adición de audio ocurre en la capa de muxing. Así que el muxer FMPEG que estamos usando, ya soporta incluir audio en ese único comando, por lo que puedes inyectar fácilmente un audio en el video final también.
Ahora, el único inconveniente con todo este proceso es que es relativamente difícil, pero fue difícil para mí y espero que esta charla realmente lo haya facilitado para ti. Así que esto también ya no es cierto. Espero que esto se haya vuelto completamente fácil para ti. Ahora, hablando de soporte de navegador, WebCodecs en realidad es compatible con todos los navegadores excepto Firefox, lo cual es algo triste. Así que realmente espero que incluso Firefox obtenga soporte para WebCodecs pronto. WebAssembly es compatible con todos los navegadores.
12. Construyendo Slantit: Una Herramienta para Crear Videos de Productos
Podemos usar libremente las bibliotecas FFmpeg y Wasm para hacer cosas increíbles en la Web. Construí una herramienta llamada Slantit para hacer videos de productos atractivos rápidamente en el navegador. El video en el fondo es un ejemplo de un video hecho con Slantit. Puedes probar Slantit en slantit.app. Utiliza el mismo proceso de codificación de video que discutimos. Gracias por su atención y la oportunidad de hablar sobre los códecs web. Conéctate conmigo en Twitter, GitHub y mi sitio web personal.
Entonces, podemos usar libremente las bibliotecas FFmpeg y Wasm para hacer cosas increíbles en la Web. Recuerda, estaba construyendo una herramienta para hacer videos de productos. Finalmente terminé construyéndola y quiero compartirla contigo para que incluso puedas probarla. Se llama Slantit. Te permite hacer videos de productos atractivos realmente rápido en tu navegador.
Entonces, el video que ves en el fondo, eso es Slantit hecho con Slantit. Así que grabé, ya sabes, una grabación de pantalla de mí usando Slantit y luego usé Slantit para editarlo, agregar estos efectos de transiciones 3D y hacer un video de producto realmente bonito para Slantit. Puedes ver Slantit en slantit.app y sí, utiliza el mismo proceso de codificación de video que discutimos en esta charla.
Entonces sí, realmente espero que lo pruebes, des tu opinión y sí, eso nos lleva al final de la charla. Realmente espero que hayas aprendido algo de la charla y también quiero agradecer a las personas que seleccionaron esta charla y me dieron la oportunidad de hablar sobre los códecs web en esta amplia plataforma. Entonces sí, gracias. Puedes conectarte conmigo. Puedes seguirme en Twitter. Tengo un GitHub y mi sitio web personal también. Entonces sí, espero hablar contigo. Gracias por ver.
Comments