Streaming de Recalbox en Twitch con un Raspberry Pi 2

Soy un gran fan de Recalbox. Para aquellos que todavía no lo conocen, Recalbox es un sistema operativo libre dedicado a la emulación y a la preservación de juegos antiguos (retrogaming). Se puede instalar en los Raspberry Pi o en un USB para jugar desde el PC. Proporciona una interfaz basada en Emulation Station y más de 50 emuladores diferentes, algunos basados en RetroArch, pero no todos. También está integrado con la DolphinBar, que permite jugar a los juegos de pistola con un mando de la Wii. Además se puede jugar en modo "netplay" (online). Al instalar Recalbox sólo tienes a disposición unos cuantos juegos libres de derechos, pero no es difícil encontrar ROMs en internet y colecciones completas (gracias a los proyectos de preservación Redump, Tosec y NoIntro). Desgraciadamente, muchos juegos antiguos todavía tienen derechos de copyright y no pueden ser distribuidos.

Existen otros sistemas parecidos a Recalbox, como Batocera, en la que está basada la BOB, RetroPie, o Lakka, pero la idea detrás de Recalbox consiste en dar acceso al retrograming de la forma más sencilla posible, para que todo el mundo, incluso aquellos sin conocimientos en informática, puedan jugar y divertirse. No hace falta configurar nada, ni editar ficheros, lo único con lo que téneis que tener cuidado es en utilizar las ROMs correctas. En internet se encuentra de todo, y mucho de lo que se encuentra no funciona. Afortunadamente en la web de Recalbox téneis una documentación muy detallada (y en varios idiomas) sobre los requisitos de cada emulador y los conjuntos de juegos recomendados. Para algunos emuladores, como por ejemplo MAME, Recalbox propociona los ficheros DAT que permiten validar o corregir las ROMs.

Me paro aquí, porque la emulación es un mundo y podría estar hablando de Recalbox durante días enteros, pero el objetivo de este artículo es otro.

Me he comprado un USB que permite capturar la señal HDMI. Mi idea es poder hacer un streaming en Twitch de mi Recalbox cuando juego online con mis amigos, para que los demás puedan presenciar la partida. Hoy en día todo el mundo utiliza OBS para hacer streaming, pero yo quería algo sencillo que pueda colocar al lado de mi Raspberry Pi 4 que se encuentra en el mueble del salón. Como tengo una Pi 2 sin hacer nada, me he preguntado, ¿sería posible utilizarlo para hacer el streaming? La respuesta la tenéis a continuación.

Antes de entrar en los detalles os preguntaréis, ¿por qué no hacer el streaming directamente desde la Pi de Recalbox?. Sería estupendo, pero los emuladores necesitan bastante potencia y una Raspberry Pi no podría hacer las dos cosas al mismo tiempo.

¡Así que manos a la obra! Os voy a explicar cómo utilizar ffmpeg instalado en una Raspberry Pi 2 y utilizando el USB de captura que os he mostrado más arriba, para hacer un stream de Recalbox.

Primero accedemos a la configuración de los modos de vídeo soportados por el USB utilizando:

v4l2-ctl --list-formats-ext  

En mi caso, mi capturadora HDMI me permite obtener el vídeo en formato MJPEG, una resolución de 1280x720 a 30 fps, me permite más, pero esto es una calidad suficiente para mí.

El problema es que el decodificador de MJPEG de ffmpeg no utiliza la aceleración hardware de la GPU de la Pi, para ello necesitamos compilar una versión de ffmpeg que soporte el decodificador ffmpeg_mmal. De la misma forma, para el codificador h264, necesitamos usar la GPU, para lo cuál necesitamos el controlador h264_omx. Sin estos dos drivers, la CPU de la Pi no puede tratar el flujo de datos suficientemente rápido.

He encontrado este ticket de ffmpeg que permite compilar una versión antigua de ffmpeg con el driver ffmpeg_mmal. Antes de nada, creamos los directorios necesarios para compilar ffmpeg:

mkdir -p ~/ffmpeg_sources ~/ffmpeg_build ~/bin  

Antes de compilarlo, necesitamos tener unas cuantas librerías:

apt install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libsdl2-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libvpx-dev libmp3lame-dev pkg-config texinfo libpulse-dev libssh-dev wget zlib1g-dev nasm yasm libx264-dev libx265-dev libnuma-dev libsdl2-dev mesa-common-dev libopengl-dev libopengl libzvbi-dev libopus-dev libvorbis-dev libvpx-dev libx264-dev libx265-dev libsoxr-dev libvpx-dev libpulse-dev libssh-dev  

Aunque podemos usar el codec aac que viene por defecto con ffmpeg, el fdk-aac es mejor, pero lo tenemos que compilar a mano:

git clone https://github.com/mstorsjo/fdk-aac  
cd fdk-aac  
autoreconf -fiv  
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make && sudo make install  

Una vez hecho esto, podemos descargar la versión de ffmpeg con el soporte de mjpeg_mmal:

cd ~/ffmpeg_sources && git clone https://github.com/lgeek/FFmpeg.git ffmpeg  

Nos metemos dentro del directorio ffmpeg de git, y aquí téneis la línea de compilación necesaria:

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib" --extra-libs="-lpthread -lm" --bindir="$HOME/bin" --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree --enable-libsoxr --enable-libvpx --enable-libpulse --enable-libssh --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --enable-opengl --enable-libzvbi --enable-omx --enable-omx-rpi --enable-mmal --enable-runtime-cpudetect --disable-x86asm && make -j4 && sudo make install  

Si todo va bien, en ~/bin tendréis la versión de ffmpeg que hace falta utilizar. Es posible que haya olvidado alguna librería, pero no deberían ser difíciles de encontrar. Mi Raspberry Pi 2
utiliza la versión stable de raspberry pi os llamada "bullseye".

Ya casi hemos terminado lo más duro, ahora viene lo más importante. Aquí os dejo la línea ffmpeg que hace el streaming de Twitch:

bin/ffmpeg -f video4linux2 -codec:v:0 mjpeg_mmal -s 1280x720 -input_format mjpeg -framerate 30 -thread_queue_size 16000 -i /dev/video0 -f alsa -ac 1 -channel_layout mono -sample_rate 44100 -thread_queue_size 16000 -i plughw:MS2109 -vcodec h264_omx -profile:v main -vsync 1 -pix_fmt yuv420p -b:v 3000k -minrate 3000k -maxrate 3000k -bufsize 6000k -g 60 -sc_threshold 0 -acodec libfdk_aac -ab 64k -ar 44100 -ac 1 -profile:a aac_low -map 0:0,0:0 -map 1:0,0:0 -r 30 -async 44100 -threads 0 -f flv rtmp://cdg10.contribute.live-video.net/app/<twitch-private-key>  

Notaréis en la línea ffmpeg la utilizacion de "mjpeg_mmal" y "h264_omx". Gracias a estos dos drivers que utilizan la GPU de la Pi, somos capaces de hacer un streaming en calidad HD, donde el porcentaje de uso de la CPU no pasa de 70%, que corresponde principalmente al esfuerzo software para codificar el audio.

Para que ffmpeg pueda acceder a la GPU, hay que utilizar el comando "raspi-config" para dedicar 256 MB de memoria RAM a la GPU, no he probado, pero quizás con 128 MB sea suficiente. También con esta herramienta, en "Opciones avanzadas", he activado el driver GL (G3 GL (Full KMS) OpenGL desktop driver with full KMS), aunque no sé si esto es necesario.

Finalemente, para que todo esto funcione automáticamente, me he creado un script en bash que se lanza desde /etc/rc.local y que lanza ffmpeg automáticamente, pero atención, he tenido que utilizar un sleep 60 antes de lanzarlo porque si no, la CPU de la Pi se encuentra saturada nada más encenderse y se producen desincronizaciones entre el audio y el vídeo a causa de esta sobrecarga. Esperando un minuto la carga de la CPU baja y cuando lanzo ffmpeg ya no hay problemas. La idea es que cuando quiero hacer el streaming, sólo tengo que enchufar la Pi 2 y el Recalbox y nada más, cuando quiero parar, desenchufo la Pi 2.

Espero no haberme olvidado nada, y esperando que os pueda servir de algo este artículo, os comparto mi cuenta de Twitch y os invito a abonaros para recibir las notificaciones cuando juegue y poder verme en directo: YonailoGaming en Twitch. Y por supuesto, si tenéis ganas de volver a jugar a vuestros juegos de infancia, a los juegos de las máquinas recreativas, a la DreamCast, la Play 1, y la 2, así como otras muchas consolas y ordenadores antiguos, spectrum, amstrand, commodore, ¡no dudéis en probar Recalbox!.