‹ Volver al Blog

La tecnología detrás de los Zapping Music

26 Jan
por


Muchos nos preguntan por la tecnología detrás de nuestros 10 canales de música que están funcionando en vivo 24 horas al día en Zapping. Acá te contamos el desarrollo que hicimos para crear nuestro propio generador de canales de televisión lineales.

Desde hace varios años hemos buscado la manera más eficiente de crear canales lineales a partir de videos estáticos. En esta búsqueda hemos pasado por varios mecanismos que son importantes mencionar para entender cómo llegamos a la tecnología actual, donde contamos con 10 canales de video live streaming de música 24/7 gastando menos de 1% de cpu y generados de forma 100% automática.

Versión 0.1 (el MVP): FFmpeg 🔥 + Bash Script + Wowza

Al comenzar un desarrollo siempre intentamos encontrar el MVP. 

Partimos creando una biblioteca de videos musicales, catalogados y curados por nosotros. Nuestro primer software era bastante simple, un pequeño batch script que contenía líneas FFmpeg que permitieran editar los videos en manera masiva, agregándole la información de la canción y el artista.


Cada video de nuestra biblioteca tenía como nombre de archivo la nomenclatura: “Nombre de canción - Artista”.

El script recorría la carpeta de nuevos videos e interpretaba el nombre de cada archivo. Luego con FFmpeg obtenía la duración de cada video y así desplegaba un GC animado 5 segundos después del inicio y 30 segundos antes del final de cada video, con el nombre de la canción y el artista. Además, agregaba una versión animada del logo del canal en un video Alpha. Este fue uno de nuestros primeros experimentos trabajando en bruto con nuestro amigo FFmpeg 🔥. Los videos ya procesados quedaban almacenados en otra carpeta y se eliminaba el video de origen. Luego el script recorría la carpeta con las versiones generadas en 1080p y creaba 3 versiones adicionales (720p, 540p y 360p).

Otro script leía la carpeta con los videos ya editados y generaba las playlists con todos estos videos en orden aleatorio. Una playlist por cada calidad.

Por último, un servidor Wowza leía estos playlist y con una librería llamada “StreamPublisher” generaba un livestreaming ABR con el loop de videos que contenía cada carpeta. 

Con poco tiempo invertido ya teníamos nuestros canales funcionando 🙂, pero no todo es color de rosas. ¿Qué cosas no funcionaban bien con este MVP?.

  • Si queríamos cambiar la gráfica del canal (Logo del canal o GCs), teníamos que procesar nuevamente todos los videos y realizar nuevamente el encoding con la nueva gráfica. Esto hacía que cualquier cambio fuera muy lento y además nos obligaba a guardar el origen intacto y la biblioteca ya se volvía bastante pesada. 
  • Estábamos obligados a usar Wowza y, por tanto, Java con su JVM que no es particularmente óptima en el uso de recursos 🗑️. 
  • Para cambiar el orden del Loop necesitábamos reiniciar la instancia de wowza, botando momentáneamente a los clientes que estaban viendo el canal.
  • No teníamos acceso a saber qué video se estaba reproduciendo en el livestreaming, ya que pasaba por la “caja negra” de Wowza.

Versión 1 (beta) ahora vamos en serio: FFmpeg + Node.js 💪

Con cada vez más gente viendo Zapping Music, llegó la hora de tener una persona en nuestro equipo a cargo de la curatoría musical y visual, de manera que los canales tomaran más vida y se sintieran con el cariño que solo un ser humano le puede entregar. Queríamos que la gente se encontrara en Zapping con canales que realmente acompañen sus días con buena música.



Y creo que lo logramos 🎉❤️ !! 

¿Pero cómo lo hicimos? Con la primera versión del “playlistator” de Zapping


Playlistator 1.0 ♻️


Para darle vida a estos canales, creamos playlists más reducidas para nuestros canales que contenían videos especialmente seleccionados por secciones. 

Con una carpeta (categoría) que contiene videos previamente seleccionados, desde el administrador uno puede realizar el encoding de los videos, el resultante era un video que cumplía con un estándar en común: Video h264, 1080p a 30fps. Audio AAC 128 kbps.

Una vez procesados los videos, una función en NodeJS generaba un archivo con un conjunto aleatorio♻️ de videos por canal con el siguiente algoritmo:

1.- Tenemos un pool de videos por categoría y se van consumiendo según la cantidad de videos seleccionadas por vuelta. 


2.- Se puede afinar la regla personalizando el algoritmo y evitando que un video se repita en un mínimo de N videos. 


3.- Esto genera un gran playlist, con las debidas repeticiones y genera un archivo con el resultado. 

Y el live streaming?

Bueno acá nuevamente viene al ataque nuestro buen amigo FFmpeg

Con el playlist ya generado, se corre una instancia en FFmpeg con un loop infinito, la que también realiza el encoding en múltiples calidades y lo envía a nuestro segmentador HLS por RTMP, el cual en ese entonces era Wowza (Quizás podemos hablar más del segmentador en otro post)

Y eso es todo 🙂... ¿pero y ahora?, ¿qué estaba mal?

Para comenzar, tener los archivos estáticos y realizar el encoding de los mismos videos día a día y enviarlos por RTMP para segmentarlos en HLS no es particularmente lo más ecológico 🐢.

Dijiste ecológico? ... Si gastar más ciclos de CPU consume más watts de energía, no es tan solo poco óptimo sino también poco ecológico.

Gastábamos 10% de GPU ejecutando el encoding en vivo de cada canal en 3 calidades (720, 540, 360) una y otra vez, procesando los mismos videos del loop. Esto no nos dejaba dormir tranquilos a nosotros ni a las tortuguitas del planeta.


V1.1 Zapping Music: Live Streaming adaptativo con <1% de uso de CPU

Había llegado el momento de que el software dejara de ser un Beta, ya habíamos logrado nuestro propósito con nuestros zappiners, el algoritmo del Playlistator ♻️ ya había sufrido optimizaciones y ahora se tenía que hacer una versión con todas las leyes de desarrollo de Zapping.

¿Y cuáles son esas leyes?

Al momento de desarrollar nuestra tecnología, tenemos como principio que se cumpla con varios requisitos técnicos y quizás algunos filosóficos. 

  • No malgastar recursos de proceso/energía en la ejecución de los algoritmos y funciones.
  • Lograr respuestas rápidas y eficientes en cualquier solicitud a servicios que atiendan usuarios (no más de 50 ms de ejecución)       
  • Ante una falla o caída, los servicios deben ser capaces de levantarse por sí solos.

El punto A y B ha sido clave para encontrar maneras de desarrollar mejor nuestro servicio, empujándonos a encontrar soluciones más eficientes para los distintos desafíos que vamos enfrentando.

Y como decimos internamente, un desarrollo poco eficiente puede terminar “matando tortuguitas en el mar”,  por lo que la consigna queda tipo: “Oye este algoritmo está perfecto, no mata tortuguitas”

No matar tortuguitas 🔫🚫🐢 = Cumplir con A y B 



Para lograr esto, agregamos a la instancia FFmpeg de nuestro Playlistator ♻️ no solo el encoding de los videos, sino también la segmentación HLS de todos los videos.  Con esto eliminamos del flujo a Wowza, ahorrándonos un transporte y la JVM de Java. 

Así, cuando se procesan los videos que entran a la biblioteca, nuestra instancia FFmpeg transforma de inmediato todos los videos a segmentos HLS en las distintas calidades. Gastando ese proceso de codificación por video solo 1 vez. 

💡 Esta nueva forma nos permite poder agregar otras calidades y codecs para el encoding, ya que sabemos que solamente gastaremos ese proceso 1 vez y no las 24 horas del día para generar el livestreaming.

El nacimiento de: Vod-to-live power by Nodejs

Finalmente, creamos un servicio con NodeJS que genera un live streaming HLS a partir del playlist generado inicialmente con nuestro Playlistator ♻️. Este programa solo va iterando sobre la lista y moviéndose en los distintos canales.

¡Logramos menos de 1% de CPU! Para generar tooooodos los canales que queramos sin necesidad de tener que adquirir nuevo equipamiento. Full estable, full compatible con toda nuestra plataforma.

¿Cuántos canales podríamos tener en una sola CPU?... ni idea solo nos limita la velocidad de lectura de los discos, probablemente más de cien con un NVME.

¿Entretenido no? Tener 100 canales de TV en un solo equipo? 😂

También como son nuestros servicios, Nodejs sabe qué video está entregando en vivo, podemos potenciar nuestro EPG para decirle a nuestros clientes qué video están viendo en cada momento. Cargamos la información en un Redis para que luego nuestro servicio de EPG se alimente y minuto a minuto le diga a todos nuestros usuarios que está sonando 🙂… y en realidad podríamos decirles qué sonó exactamente a todas las horas del día.



Y que viene para el futuro?

De aquí en adelante, la integración con APIs para enriquecer el contenido está a la vuelta de la esquina, también poder retroceder en estos canales y quizás alguna que otra sorpresa 🙂. ¿Te imaginas mandar a Spotify esa canción que estás viendo en Zapping Music? ¿Ver en la tele más información del disco o del artista? ¿Ver más videos del mismo artista?





🤓 Sigue leyendo