BUZZK goes live! (o cómo el Modo Kiosko se transforma en videostream)

Buzzk Social en Sala Sonora de Bilbao

Ya contamos con varias instalaciones desplegadas con nuestro software de digital signage (señalización digital) Buzzk para espacios públicos, como bares, restaurantes o comercios. Es un software con cierta madurez, que está basado en HTML 5 y requiere de clientes relativamente ligeros, ya que únicamente hace falta una navegador web con aceleración 3D.

Tradicionalmente, hemos venimos utilizando Odroid o Raspberry Pi 2 como anfitriones de nuestros Buzzk. Son económicos y fiables y su configuración en modo kiosko resulta muy sencillo con ciertas herramientas open source… Matchbox, Unclutter o Chromium son algunos ejemplos muy habituales en este tipo de instalaciones. Pero hace varias semanas se nos planteó el reto de integrar nuestro sistema de digital signage en otro sistema de digital signage algo old school, ya desplegado en una instalación bastante grande. Se trataba de cerca de una docena de pantallas con sus correspondientes equipos “ligeros” controlados desde un servidor… con un sistema propietario, montado con una interfaz bastante soviética en HTML y corriendo todo ello sobre PHP (¡Cómo nos gusta PHP!).

Añadiendo streaming de video a Buzzk

El problema es que era una instalación propietaria que cuenta con una licencia un tanto restrictiva y que no le permitía configurar una simple URL como contenido a consumir. El sistema soporta imágenes, vídeos, ficheros swf… infinidad de opciones bastante complicadas a priori, pero la versión en cuestión no tenía un campo URL para invocar a nuestro pequeño cliente Buzzk… Aunque por debajo corrían sobre Linux y un navegador web, la configuración resultaba bastante compleja y, por supuesto, no teníamos acceso a los equipos de ninguna manera más o menos sana.

Dicho rápidamente: teníamos un «marronaco». Había que mostrar nuestro cliente Buzzk en un sistema hermético del que el cliente no quiere desprenderse. Algo complicado. Aunque, de repente, vimos la luz: esos clientes eran capaces de reproducir un video-stream sobre http. La misión era crear un stream de vídeo en directo, directamente con la salida de nuestro navegador:

  1. Lanzar un navegador con Buzzk corriendo sobre unas X
  2. Capturar en tiempo real la salida de ese DISPLAY
  3. Generar un stream live hacia el sistema «hostil» de digital signage
  4. Que el sistema hostil entienda y reproduzca nuestro stream (obvio)

X descabezadas

La idea inicial era levantar un servidor X real en nuestro servidor y, desde ahí, capturar el stream que posteriormente se mostraría a través de un servidor de video al los clientes «reales» del sistema. Pero se nos antojaba algo demasiado «manual»: el servidor necesitaría una tarjeta gráfica concreta, deberíamos forzar la resolución gráfica… Nos parecía algo poco tolerante a errores, excesivamente «real» para nuestro propósito.

Entonces nos acordamos de XvFb. XvFb es parte de la implementación XFree86 de un servidor X11 normal y corriente, con la particularidad de que utiliza la memoría para realizar todas las operaciones gráficas. No necesita ningún hardware específico y es 100% parametrizable. En otras palabras, es como un servidor X fantasma. Es bastante utilizado para realizar tests de integración con Selenium o herramientas similares.

Su ejecución es simple:

/usr/bin/Xvfb :10 -screen 0 1024x768x24

Con las X levantadas, ya solo nos quedaba configurar el ~/.xinitrc para arrancar gestor de ventanas, el chromium en modo kiosk… pero esa es otra historia que ya contaremos en otra ocasión.

Y voilá! ya tenemos nuestro buzzk ejecutándose en modo fantasma en nuestro pequeño servidor.

Si quieres probarlo, lo tendrás seguro disponible en el sistema de paquetes de tu distribución de Linux favorita.

Video Stream

Como (casi) siempre que tenemos que tirar de temas de vídeo, echamos mano de ffmpeg… en este caso, le tocaba arrancar a ffserver.

Necesitamos que el stream generado (f.mpg), sea de calidad suficiente (no teníamos problemas de ancho de banda), y en esta ocasión no necesitábamos sonido…
Después de varias pruebas, comprobamos que esta configuración cumplía con un mínimo de calidad más que aceptable:

HttpPort 8090
HTTPBindAddress 0.0.0.0

MaxHTTPConnections 2000

MaxClients 20

MaxBandwidth 200000
CustomLog -

<Feed f.ffm>
File /tmp/f.ffm
FileMaxSize 10000K
</Feed>

<Stream buzzk.mpg>
Feed f.ffm
Format mpeg
VideoCodec mpeg1video
VideoFrameRate 25
VideoSize xga
VideoBitRate 516
VideoBufferSize 1024
VideoGopSize 1
NoAudio StartSendOnKey
VideoHighQuality
</Stream>

Más información sobre como tunear ffserver, aquí.

Con ffserver corriendo, solo hace falta un “agente” pusheador que genere ese Feed. Gracias al device x11grab de ffmpeg, es relativamente sencillo capturar el DISPLAY que está generando xvfb. Solo nos quedaba ajustar los parámetros de captura, y se lo enchufamos al ffserver:

/usr/bin/ffmpeg -re -override_ffserver -f x11grab -s 1024x768 -r 28 -i :10 -q:v 2 -an -qmin 1 -qmax 31 -cpu-used 0 -quality good -b:v 128k  http://127.0.0.1:8090/f.ffm

Básicamente le indicamos al ffmpeg que capture la salida del servidor x11, en el DISPLAY :10, a una resolución xga (1024×768) a 28 frames por segundo, y que lo «pushee» hacía el Feed f.ffm que está escuchando desde el ffserver.
Dicho y hecho, funcionaba perfectamente con el seevidor Xvfb. Incluso las transiciónes CSS3 se visualizan perfectamente en nuestro reproductor de vídeo.

Únicamente nos queda probar que el stream funciona correctamente. Utilizamos nuestro reproductor multimedia favorito (VLC por ejemplo) y ya tenemos buzzk en directo:

vlc http://localhost:8090/buzzk.mpg

Orquestando todos las ejecuciones

Finalmente solo nos queda ejecutar todo esto, y ejecutarlo en un este orden concreto.
1. ffserver
2. Servidor X11 (Xvfb)
3. Cliente Chromium
4. ffmpeg pusheador

Y para esto nada mejor que montar 4 ficheritos «.service» con systemd. Por ejemplo, el «pusher» ffmpeg es lanzado después de que haya arrancado el servidor X, así como el ffserver:

[Unit]
Description=Buzzk Stream (pusher)
Requires=buzzk-xserver.service, buzzk-ffserver.service


[Service]
User=irontec
EnvironmentFile=/etc/default/buzzk
ExecStart=/usr/bin/ffmpeg -re -override_ffserver -f x11grab -s ${RESOLUTION} -r 28 -i ${DISPLAY} -q:v 2 -an -qmin 1 -qmax 31 -cpu-used 0 -quality good -b:v 128k  http://127.0.0.1:8090/f.ffm
ExecStop=/bin/kill -9 $MAINPID
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Si te gusta nuestro blog, ¡vótanos!

Conclusión: pronto más marketing tecnológico

 

Xvfb nos ha dejado bastante buen sabor de boca y es más que probable que esta no sea la última instalación con este software… Tenemos varios proyectos en la cabeza: desde integrar de alguna manera el photocall con Chromecast, hasta visualizar el SmartWall en una smartTV sin necesidad de ningún cliente adicional. Responsables de marca, marketing managers y agencias de publicidad: estad atentos a nuestras novedades de marketing tecnológico en los próximos meses 😉

Lo que seguramente vamos a probar rápidamente es esta joyita: xvfb disponible en npm… Buenísima pinta 🙂



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Javier Infante Porro

Linux, HTTP, JS, TS, PHP... Programo (entre otras cosas) en Irontec desde hace más de 12 ó 13 años... @jabiinfante

Queremos tu opinión :)