1. Introducción a las API de Canvas y HTML5 Video
Hola a todos en React Summit. Hoy vamos a hablar sobre las API de Canvas y HTML5 Video y algunas cosas geniales que puedes hacer con ellas. Soy Dylan Javary de Mux, donde proporcionamos Video para Desarrolladores. Nos enfocamos en crear API fáciles de usar para video. Si estás interesado, hablemos.
Esto es una prueba. Hola a todos en React Summit. Estoy muy emocionado de hablarles aquí hoy. Vamos a hablar sobre las API de Canvas y HTML5 video, y algunas cosas geniales que descubrimos que puedes hacer con ellas.
Así que una breve introducción, soy Dylan Javary, trabajo en Mux. Si no has oído hablar de Mux, Mux es Video para Desarrolladores. Tal vez conozcas a Stripe, Stripe es pagos para desarrolladores, o conoces a Twilio, que son llamadas telefónicas y mensajes de texto para desarrolladores. Nos gusta ser como esas empresas, donde estamos construidos pensando primero en los desarrolladores y tratamos de crear excelentes API fáciles de usar, pero lo hacemos para video. Creamos todo tipo de herramientas, productos y API para desarrolladores que trabajan con video. No voy a hablar mucho más sobre Mux hoy, pero si estás interesado, ven a hablar conmigo.
2. Introducción a la Aplicación React y al Componente Reproductor
Me encantaría hablar contigo. Comencemos con una demostración simple de una aplicación React utilizando el componente reproductor y el canvas. El componente reproductor es un elemento de video que utiliza la tecnología HLS para la transmisión de video.
Me encantaría hablar contigo. Genial, así que ahora vamos a ver algo de código. Tengo este código sandbox configurado. Por cierto, Code Sandbox es una gran herramienta. Se ha convertido en una de mis piezas de software favoritas. Creo que hay algunas personas de Code Sandbox aquí en esta conferencia, así que un saludo para todos ustedes. Me encanta este producto. Y lo compartiré después para que puedas hacer un fork, jugar con el código, hacer tus propias cosas.
Y empecemos con una demostración muy sencilla. Esta es una aplicación React muy sencilla. Tenemos algunas rutas diferentes. Estos cinco ejemplos diferentes que voy a mostrar utilizan React Router y React DOM. Y empecemos con el primero. Empecemos con una demostración simple. Aquí tenemos simple.js. Este es el componente que estamos renderizando. Tenemos este componente reproductor y luego tenemos este canvas. Y ahora mismo, no puedes ver el canvas en la página, pero eso es lo que haremos. Lo manipularemos y haremos cosas divertidas a medida que avancemos.
Así que rápidamente, echemos un vistazo a este componente reproductor. Este componente reproductor es... En realidad, solo es un elemento video. Pero si estás familiarizado con los video... ¿Cuántos de ustedes han utilizado video en Internet? Ya sea transmisión de video, video a pedido o transmisión en vivo, algo así. Es posible que hayas utilizado el elemento video antes y tal vez hayas utilizado un archivo MP4 y eso puede funcionar. Pero cuando realmente quieres hacer una transmisión de video correctamente, lo que necesitas hacer es utilizar algo como HLS. HLS es una tecnología que te permite descargar videos en segmentos y en diferentes tasas de bits y niveles de calidad según el ancho de banda del usuario. Eso es algo que Mux hace por ti. No vamos a profundizar demasiado en eso. Pero eso es lo que estamos utilizando aquí en este reproductor de video.
3. Explorando el Elemento de Video HTML5 y el Canvas
Entonces, este es el elemento de video HTML5 con JavaScript adicional para capacidades HLS. Cuando se dispara el evento de reproducción, se llama a la función onPlayCallback. El video se duplica en un elemento de lienzo debajo. El código utiliza el elemento de video y un contexto de lienzo para manipular y dibujar imágenes en el lienzo. La función drawImage copia cada fotograma del elemento de video en el lienzo. Vamos a dar un paso más y ver el ejemplo de filtro.
Entonces, esto es... En realidad, solo es el elemento de video HTML5. Y luego adjuntamos algo de JavaScript adicional para darle capacidades HLS. Y luego, cuando se dispara el evento de reproducción, ese evento de reproducción es cuando comienza la reproducción en el video, y vamos a llamar a esta función onPlayCallback.
Entonces, volvamos al componente que está renderizando esta página. Ampliemos un poco aquí. Asegurémonos de que puedas ver eso. Entonces, aquí mismo, tenemos el reproductor, onPlayCallback. Y cuando eso se dispara, veamos qué sucede. Lo que vemos es que este video se reproduce en el elemento de video. Y luego se duplica en este elemento de lienzo justo debajo.
Veamos un poco de este código. Entonces, cuando se llama a onPlay, obtenemos el elemento de video, y creamos este contexto, esta referencia de contexto. Lo que esto es, es una especie de controlador para el elemento de lienzo. Y luego podemos llamar a funciones en ese contexto que nos permite manipular ese elemento de lienzo, cambiar cómo se muestra, y eso es como nuestro gancho para manipular el lienzo real en sí. Entonces, en onPlay, llamamos a requestAnimationFrame, llamamos a updateCanvas. Y lo que eso va a hacer es simplemente llamar a esta línea, drawImage, le pasamos ese elemento de video. Y esto le dice al lienzo que simplemente dibuje esta imagen en el lienzo. Y estas son las dimensiones. Estas son las coordenadas donde comenzar y estas son las dimensiones para dibujar. Y esto se llama recursivamente en realidad. Entonces, cada vez que se ejecuta esto, solicitamosAnimationFrame nuevamente, y luego la función de devolución de llamada llama a updateCanvas nuevamente. Entonces puedes ver lo que está sucediendo. Simplemente estamos dibujando eso, básicamente estamos copiando ese elemento de video en el lienzo y justo debajo. Así es como funciona eso. Una rápida demostración de lo que hicimos allí. Elemento de video, copiar cada fotograma, dibujarlos en el lienzo, bastante simple, ¿verdad?
Entonces, ahora vamos a dar un paso más. Vamos a ver este ejemplo de filtro. Entonces, lo que hace el filtro, podría reproducir, está bien, algo similar, pero puedes ver que algo más está sucediendo aquí. Lo que estamos haciendo es lo mismo, la función de devolución de llamada updateCanvas.
4. Manipulando el Canvas y los Fotogramas de Video
Podemos manipular y trabajar con datos de imagen en bruto desde el lienzo. Al iterar a través de los datos de imagen y ajustar los valores de color, podemos lograr efectos como escala de grises. Además, podemos agregar texto encima del lienzo, lo que permite modificaciones en tiempo real. Esto abre posibilidades para la manipulación interactiva de video utilizando las APIs del navegador. Veamos más ejemplos, incluyendo la extracción de fotogramas individuales de un video y su manipulación. El video que estamos utilizando es Big Buck Bunny, un ejemplo popular en la comunidad de transmisión de video.
Y lo que hacemos es dibujar esa imagen en el lienzo. Extraemos los datos de imagen del lienzo. Y ahora tenemos datos de imagen en bruto con los que realmente podemos manipular y trabajar. Y vamos a iterar a través de esos datos de imagen y vamos a jugar con los valores de color. Podemos promediar, si promediamos los valores de rojo, verde y azul, eso nos dará este efecto de escala de grises. Así que en realidad estamos manipulando la imagen fotograma a fotograma del video, y luego volviéndola a dibujar en el lienzo. Y puedes ver que tiene ese efecto. Y puedes ver que este lienzo siempre se mantiene sincronizado con el fotograma del video que el elemento de video está reproduciendo.
Muy genial, ¿verdad? Así que veamos los pasos que hicimos allí donde llevamos esto un poco más lejos. Entonces, en lugar de simplemente dibujar cada fotograma en el lienzo, después de hacer eso, extraemos el fotograma, manipulamos los colores a una escala de grises, y luego lo volvemos a dibujar en el lienzo. Muy bien. Ahora tenemos algunos ejemplos más. Veamos qué más podemos hacer. Cada vez será mejor. Layla, esta es la perra de mi compañero de trabajo Phil. Y veamos este ejemplo. Entonces, ahora en la función de actualización del lienzo, dibujamos la imagen, y luego simplemente vamos a agregar este texto Phil en el lienzo. Entonces, lo que estamos haciendo allí es simplemente agregar texto encima del lienzo. Así que estamos renderizando la imagen del video en el lienzo, y luego simplemente agregando texto encima. Ahora puedes imaginar que esto podría ser bastante útil, ¿verdad? Si tenemos un video, y ese video lo estamos reproduciendo, si simplemente presionamos este elemento de video y lo reproducimos y lo dibujamos en el lienzo, entonces podemos hacer todas estas cosas geniales como agregar texto en tiempo real, hacer todas estas cosas geniales en tiempo real, fotograma a fotograma en el lado del cliente en el navegador, todo con estas APIs del navegador. Ahí es donde agregamos un nombre. Veamos qué más podemos hacer.
Muy bien. Ahora veamos este. Esto se llama clasificar. Entonces, lo que hemos visto es que podemos obtener fotogramas individuales del video en tiempo real, dibujarlos en un lienzo, y antes de dibujarlos en el lienzo, podemos manipularlos, ¿verdad? Entonces, ¿qué más podemos hacer? Cuando tenemos un fotograma en bruto de un video, pensemos en qué más podemos hacer. Entonces, este video, si no reconoces este video, es Big Buck Bunny. Es como el ejemplo canónico de `Hola Mundo` en el mundo de la transmisión de video. He visto este video demasiadas veces y es un buen ejemplo.
5. Detección de Objetos en Tiempo Real y Casos de Uso
En esta demostración de clasificación, ejecutamos la detección de objetos mediante aprendizaje automático en cada fotograma de video, dibujando rectángulos alrededor de los objetos detectados. Utilizamos el modelo TensorFlow Cocoa SSD para detectar objetos en tiempo real. Al extraer datos de imagen del lienzo, podemos mapear las predicciones y dibujar cuadros con etiquetas en el video. Aunque no es perfecto para contenido animado, puede detectar objetos de la vida real con precisión. Esto abre posibilidades para la detección de objetos en tiempo real en transmisiones de video en vivo. Veamos más casos de uso.
Para los propósitos de esta demostración de clasificación, vamos a reproducir el video. Y si observas lo que está sucediendo, en cada fotograma del video, ejecutamos una funcionalidad de detección de objetos mediante aprendizaje automático en cada fotograma de imagen, y puedes ver que, y luego dibujamos el rectángulo después de detectar el objeto en el fotograma. Y en este momento cree que es una persona, avancemos un poco más, ahora cree que es un pájaro. Así que en realidad estamos detectando fotograma a fotograma, qué está sucediendo con los objetos en este video. Veamos el código. Dibujamos la imagen en el contexto, extraemos los datos de imagen. Y estos son los mismos datos de imagen en los que estábamos manipulando los colores, pero aquí tenemos esta llamada adicional, que es model.detect y pasamos esos datos de imagen. Entonces, model es algo que proviene de este modelo TensorFlow Cocoa SSD, que es este modelo TensorFlow que realizará la detección de objetos en imágenes. Está diseñado para trabajar con imágenes. Y cuando pasamos estos datos de imagen que hemos extraído del lienzo, se ejecutará la detección de objetos y nos devolverá un conjunto de predicciones que ellos llaman así, ¿de acuerdo? Ahora, una vez que tenemos un conjunto de predicciones, podemos pasarlas a esta función de contorno que mapeará esas predicciones. Tiene las coordenadas X, Y, el ancho y la altura de esta caja delimitadora. Y luego podemos dibujar esas cajas con las etiquetas directamente en ese elemento de lienzo que ya estamos utilizando para renderizar el video. Así que puedes ver que cree que es un pájaro, sigue creyendo que es un pájaro. Y un perro, vimos que había un perro por un segundo, aquí cree que es una pelota deportiva. Entonces, ya sabes, no es la detección de objetos más precisa para este contenido animado. Ahora es una oveja, se parece a una oveja, pero en realidad podemos hacer cosas bastante geniales. Y recuerda, esto sucede en tiempo real. Así que ni siquiera necesariamente, muchas veces cuando haces detección de imágenes en un video, lo harías fuera de banda, en un servidor, una vez que el video esté finalizado. Pero imagina que esto fuera una transmisión en vivo, ¿verdad? Si estamos lidiando con una transmisión en vivo de video, podríamos ejecutar esto en el cliente y detectar objetos en tiempo real. Y, ya sabes, las posibilidades son infinitas y podemos hacer todo tipo de cosas con la detección que estamos haciendo. Veamos otro ejemplo de clasificación. Vamos a mostrar nuevamente a Laila, la perra de Phil, y puedes ver aquí, TensorFlow para un video en vivo real. Es el tipo de perro, en realidad es bastante bueno detectando cosas de la vida real, cosas animadas, conejos gigantes animados, tal vez no tanto, pero un perro sí puede detectarlo. Así que eso es una revisión rápida de lo que hicimos allí. La parte clave a tener en cuenta es que una vez que obtenemos imágenes en un lienzo, podemos extraer esos datos de imagen en bruto. Y luego este círculo rojo donde estamos haciendo detección de objetos en tiempo real, reemplazar eso con cualquier cosa, ¿verdad? Manipular los colores, agregar superposiciones de texto. Y luego podemos volver a dibujar eso en el lienzo y utilizar todas las APIs del lienzo que están disponibles. Eso es lo que hicimos allí. Ahora, echemos un vistazo rápido a algunos casos de uso del mundo real.
6. Mejorando el Sitio Web de Marketing con Video Interactivo
Recientemente hicimos una actualización de diseño en nuestro sitio web de marketing, agregando una demostración de API en la sección principal. Anteriormente, teníamos un solo video, pero esta vez queríamos que fuera más interactivo. Al usar una estrategia de copiar fotogramas de un elemento de video y renderizarlos en elementos de lienzo, logramos los efectos deseados. Este enfoque eliminó la necesidad de transmisión doble, evitó problemas de sincronización de reproducción y permitió una experiencia más interactiva. Si estás interesado en video, ¡hablemos!
Nosotros en Mux, en realidad usamos esto en nuestro sitio web de marketing recientemente. Así que recientemente hicimos una actualización de diseño en nuestro sitio web de marketing y tenemos esta demostración de API en la sección principal y puedes ver qué está sucediendo aquí. Antes, en nuestro sitio de marketing antes de esta iteración, teníamos una demostración de API similar pero era todo un solo video. Así que puedes imaginar si todo esto aquí fuera solo un video con este dispositivo y el navegador emergiendo, eso funcionaba bastante bien pero esta vez queríamos mejorarlo.
Lo que estábamos pensando es que te darás cuenta de que cuando paso el cursor sobre esto, emerge. Si paso el cursor sobre el navegador y el navegador emerge puedo copiar texto aquí. Puedo interactuar con él. Eso es lo que queremos hacer. Digamos que un desarrollador viene aquí y quiere copiar este texto o, ya sabes, simplemente hacerlo más interactivo. También tenemos estos colores que se desbordan en el fondo que queremos que se desborden fuera de los límites de este elemento y se desborden en la cabecera superior y se desborden en la parte inferior. Y si esto fuera solo un video estático no podríamos obtener ese efecto.
Entonces, la forma en que logramos esto tengo un ejemplo de storybook aquí. Entonces, la forma en que realmente pudimos hacer esto es a través de la estrategia que describí. Así que en realidad inspeccionamos estos elementos. De acuerdo, inspeccionamos estos elementos. Puedes ver que esto aquí es un lienzo. Permíteme reproducir esto. Y luego vemos que esto aquí es otro lienzo. Y luego, si miramos más abajo aquí en el DOM, podemos ver que hay un elemento video. Entonces este es el elemento video que está transmitiendo el video. Y luego estamos copiando los fotogramas de ese video y renderizándolos en estos dos elementos de lienzo en tiempo real. Entonces, los beneficios de esa estrategia, alternativamente, podríamos sacar el mismo diseño y tener este navegador como un elemento video y este dispositivo como otro elemento video. Y eso funcionaría bien. Excepto que la desventaja de eso es, en primer lugar, estamos transmitiendo el mismo video dos veces, lo que duplicará el ancho de banda, más ancho de banda para el usuario. Más datos de video que se descargan parece innecesario y repetitivo. En segundo lugar, los dos videos podrían desincronizarse, ¿verdad? Como si un video se almacenara en búfer y tienes una conexión lenta y el otro aún no se ha almacenado en búfer, entonces puede haber una sincronización de reproducción por lo que probablemente tendríamos que escribir algo de JavaScript que mantenga los cabezales de reproducción alineados y sincronizados y eso parece un poco defectuoso, no es una gran solución. Entonces, lo que hicimos es aplicar la estrategia de tomar este elemento video, tomar los fotogramas de ese elemento video, y renderizarlos en el lienzo. Y de esa manera, estos dos lienzos siempre estarán sincronizados. Solo estamos descargando el video una vez. Funciona bien y reproduzcamos esto una vez más. Y esa es la solución a la que llegamos. Entonces, te darás cuenta de que ahora puedo pasar el cursor sobre esto, pasar el cursor sobre esto y los dispositivos emergen y es más interactivo. Puedo copiar código y ahora este video, este es un video de feliz cumpleaños para React Summit. Es un video que encontré en línea de niños llorando cuando soplan las velas de su cumpleaños y es bastante divertido. Así que feliz cumpleaños React Summit. Estoy emocionado de estar aquí, emocionado de hablar con todos ustedes. Y si tienes algo de qué hablar sobre video, me encantaría charlar. Si estás agregando video a tu producto, construyendo video, haciendo cosas geniales, por favor, charla conmigo y gracias por tenerme. Encuéntrame en Twitter, DylanJAJ y eso es todo. Gracias.