Añade capacidad de digitalización de fuentes externas y visualización de fuentes analógicas en Kodi
Tabla de contenidos
Introducción
Seguro que en alguna ocasión has querido conectar una videoconsola, una cámara, un decodificador de televisión o un reproductor de VHS al ordenador y distribuir esa señal de vídeo por toda la red de tu casa.
La solución habitual suele consistir en instalar un programa de captura, dejarlo funcionando continuamente y acceder a él desde otro equipo. El problema es que este método consume recursos de forma permanente, obliga a mantener un programa abierto las 24 horas y, en muchos casos, requiere un ordenador relativamente potente.
En este artículo vamos a construir una solución completamente distinta.
Nuestro objetivo será transformar una sencilla capturadora HDMI USB, de las que pueden encontrarse por muy poco dinero, en un servidor RTSP profesional que solo consuma recursos cuando alguien solicite el vídeo.
Cuando nadie esté viendo la señal, el sistema permanecerá prácticamente en reposo.
Cuando un cliente solicite el flujo RTSP:
- el sistema arrancará automáticamente la captura;
- comenzará a codificar el vídeo utilizando la GPU del equipo;
- publicará el flujo RTSP;
- y, cuando el último cliente se desconecte, todo el proceso volverá a detenerse automáticamente.
Todo ello sin intervención del usuario.
De esta forma, a través de cualquier plugin de reproducción de iptv o grabación de iptv podemos integrar en Kodi esta fuente como una parte más de nuestro reproductor y realizar grabaciones de fuentes externas de vídeo.
¿Qué vamos a conseguir?
Al finalizar este tutorial dispondremos de un sistema capaz de:
- Capturar vídeo y audio HDMI.
- Publicar un flujo RTSP compatible con VLC, Kodi, FFplay, OBS Studio y cualquier cliente RTSP estándar.
- Codificar el vídeo utilizando la GPU Intel mediante VAAPI, reduciendo enormemente el consumo de CPU.
- Arrancar automáticamente únicamente cuando exista una petición de vídeo.
- Detener completamente la captura cuando no haya clientes conectados.
- Recuperarse automáticamente después de reiniciar el equipo, sin necesidad de volver a ejecutar ningún comando.
En otras palabras, convertiremos un pequeño equipo con LibreELEC en un auténtico servidor de vídeo bajo demanda.
¿Por qué LibreELEC?
A primera vista puede parecer extraño utilizar LibreELEC para este proyecto.
LibreELEC nació como un sistema operativo orientado exclusivamente a Kodi y la reproducción multimedia, pero precisamente por eso ofrece varias ventajas muy interesantes:
- ocupa muy poco espacio;
- arranca en pocos segundos;
- apenas consume recursos;
- incluye un kernel optimizado para multimedia;
- incorpora un excelente soporte para dispositivos de vídeo y audio;
- resulta extremadamente estable.
Además, como el sistema permanecerá encendido de forma permanente, nos interesa una distribución ligera y con el menor mantenimiento posible.
Hardware utilizado
Aunque esta guía puede adaptarse a otros equipos, durante el desarrollo se ha utilizado el siguiente hardware:
| Componente | Modelo |
|---|---|
| Mini PC | Intel NUC |
| Sistema operativo | LibreELEC 12.2 |
| Capturadora HDMI | MacroSilicon MS2109 |
| Conversor analógico → HDMI | Panasonic DMR-EX77 |
| Fuente de vídeo | VHS, LaserDisc y DVD |
El Panasonic DMR-EX77 merece una mención especial.
En lugar de conectar directamente un reproductor VHS a una capturadora analógica, utilizamos el Panasonic como conversor.
De esta forma obtenemos:
- una sincronización mucho más estable;
- un excelente escalado;
- salida HDMI;
- una calidad de imagen muy superior.
Durante nuestras pruebas el resultado fue sorprendentemente bueno.
Arquitectura del sistema
Antes de comenzar conviene comprender cómo funcionará todo el conjunto.
VHS
LaserDisc
DVD
│
▼
Panasonic DMR-EX77
│
HDMI
│
▼
Capturadora USB HDMI
│
▼
Contenedor Docker
│
FFmpeg
│
H.264 + Audio AAC
│
▼
MediaMTX
│
┌────────┴─────────┐
│ │
Kodi VLC
Como puede verse, la capturadora nunca será utilizada directamente por Kodi.
Kodi únicamente verá un flujo RTSP estándar.
Eso significa que cualquier otro dispositivo de la red podrá utilizar exactamente la misma señal.
La clave del proyecto
Hasta aquí no hay nada especialmente novedoso.
Lo realmente interesante aparece en este punto.
No queremos que FFmpeg permanezca ejecutándose continuamente.
Si nadie está viendo la señal…
FFmpeg apagado
Docker detenido
Consumo prácticamente nulo
Cuando alguien abre:
rtsp://IP_DEL_SERVIDOR:8554/vhs
MediaMTX detectará automáticamente esa petición y ejecutará el contenedor Docker.
En ese momento comenzará la captura.
Cuando el último cliente abandone la reproducción…
MediaMTX volverá a detener Docker automáticamente.
Es decir, el sistema consume recursos únicamente cuando realmente son necesarios.
Este comportamiento será uno de los aspectos más interesantes de todo el proyecto y uno de los motivos por los que elegimos MediaMTX como servidor RTSP.
¿Por qué Docker?
Una pregunta que suele aparecer rápidamente es:
¿Por qué ejecutar FFmpeg dentro de Docker y no directamente sobre LibreELEC?
La respuesta es sencilla.
Docker nos aporta varias ventajas importantes:
- mantiene LibreELEC completamente limpio;
- facilita las actualizaciones de FFmpeg;
- permite reconstruir el sistema en pocos minutos;
- evita dependencias innecesarias;
- simplifica las copias de seguridad.
Además, durante el desarrollo realizamos numerosas pruebas cambiando parámetros de codificación, resoluciones y formatos de audio.
Gracias a Docker nunca modificamos el sistema operativo.
Todo el trabajo queda encapsulado dentro del contenedor.
Lo que veremos en la siguiente parte
En el siguiente capítulo comenzaremos la instalación real del sistema.
Aprenderemos a:
- preparar LibreELEC;
- instalar Docker;
- instalar MediaMTX;
- identificar correctamente la capturadora HDMI;
- comprobar los dispositivos de vídeo y audio;
- y dejar el sistema preparado para comenzar a publicar el primer flujo RTSP.
Fin del Capítulo 1
Nota del autor
Durante el desarrollo de este proyecto se realizaron numerosas pruebas hasta conseguir un sistema completamente estable. En esta guía se muestran únicamente los pasos definitivos, ya verificados, para que el lector pueda reproducir el resultado sin pasar por todos los ensayos y errores del proceso de desarrollo.
Preparando LibreELEC para convertirlo en un servidor RTSP
En el capítulo anterior vimos qué íbamos a construir y cómo sería la arquitectura general del sistema.
Ahora llega el momento de preparar nuestro equipo.
Aunque LibreELEC está pensado principalmente para ejecutar Kodi, bajo esa interfaz encontramos una distribución Linux muy ligera que incorpora un kernel optimizado para multimedia y un excelente soporte para dispositivos USB.
Precisamente eso es lo que vamos a aprovechar.
Antes de empezar
Durante este tutorial asumiremos que LibreELEC ya está instalado y funcionando correctamente.
No importa si está instalado sobre un Intel NUC, un mini PC o cualquier otro equipo compatible.
Lo importante es que:
- Kodi funciona correctamente.
- Podemos acceder mediante SSH.
- La capturadora HDMI ya está conectada.
Activar SSH
Toda la configuración se realizará desde la consola.
Para ello necesitaremos activar el servidor SSH integrado en LibreELEC.
Desde Kodi:
Ajustes
↓
Servicios
↓
SSH
↓
Activar SSH
Una vez activado podremos conectarnos desde otro ordenador.
En macOS o Linux simplemente abrimos un Terminal y escribimos:
ssh root@IP_DE_LIBREELEC
Por ejemplo:
ssh root@192.168.1.50
La contraseña por defecto de LibreELEC es:
libreelec
Si todo ha ido correctamente veremos algo parecido a esto:
LibreELEC (official): 12.x.x
LibreELEC:~ #
Ya estamos dentro del sistema.
Comprobando la capturadora
Antes de instalar absolutamente nada debemos asegurarnos de que Linux detecta correctamente la capturadora.
Ejecutamos:
lsusb
En nuestro caso apareció:
Bus 001 Device 005
534d:2109 MacroSilicon USB Video
Si aparece un dispositivo similar, ya tenemos la primera parte resuelta.
Comprobando el vídeo
Ahora comprobaremos que el kernel ha creado el dispositivo de captura.
Ejecutamos:
v4l2-ctl --list-devices
La salida debería ser similar a:
USB Video
/dev/video0
/dev/video1
Generalmente:
- /dev/video0 será el dispositivo de captura.
- /dev/video1 suele corresponder a metadatos o funciones auxiliares.
Nos interesa únicamente el primero.
Resoluciones soportadas
Ahora veremos qué resoluciones admite realmente la capturadora.
Ejecutamos:
v4l2-ctl --list-formats-ext -d /dev/video0
En nuestro caso obtuvimos:
MJPEG
1920x1080
1600x1200
1360x768
1280x720
1024x768
800x600
720x576
720x480
y también:
YUYV
720x576
720x480
640x480
Aquí aparece una diferencia importante.
¿MJPEG o YUYV?
Nuestra capturadora permite dos modos distintos.
MJPEG
La propia capturadora comprime la imagen.
Ventajas:
- menor tráfico USB
- mayor resolución
- mayor fluidez
Inconvenientes:
- ligera compresión previa
YUYV
Entrega la imagen completamente sin comprimir.
Ventajas:
- máxima calidad
Inconvenientes:
- enorme ancho de banda USB
- resolución práctica mucho menor
Después de numerosas pruebas comprobamos que MJPEG ofrecía un equilibrio excelente entre calidad y rendimiento.
Por ello será el modo utilizado durante todo este proyecto.
Comprobando el audio HDMI
Muchas capturadoras USB incorporan también una tarjeta de sonido.
Para comprobarlo ejecutamos:
cat /proc/asound/cards
En nuestro caso aparecía:
2 [MS2109]
USB Audio
Eso significa que Linux reconoce correctamente el audio HDMI procedente de la capturadora.
También podemos comprobar los dispositivos ALSA disponibles:
cat /proc/asound/devices
y los dispositivos creados:
ls /dev/snd
Todo ello confirma que disponemos tanto de vídeo como de audio.
¿Por qué hacemos todas estas comprobaciones?
Es muy habitual comenzar a instalar programas antes de comprobar que el hardware funciona correctamente.
Eso suele terminar en horas intentando depurar un problema que en realidad era un simple cable HDMI defectuoso o una capturadora mal detectada.
Por ese motivo dedicamos este capítulo únicamente a verificar que:
- LibreELEC reconoce la capturadora.
- Existe el dispositivo
/dev/video0. - Existe un dispositivo ALSA para el audio.
- La capturadora soporta las resoluciones esperadas.
Hasta que estas cuatro comprobaciones sean correctas no tiene sentido continuar.
Instalando Docker
Una de las ventajas de LibreELEC es que dispone de un complemento oficial para Docker.
Desde Kodi abrimos:
Complementos
↓
Descargar
↓
Servicios
↓
Docker
Lo instalamos normalmente.
Una vez terminado podremos comprobar su funcionamiento desde la consola.
docker version
Si aparece información similar a esta:
Client:
Version:
Server:
Engine:
Docker ya está listo para utilizarse.
¿Por qué utilizaremos Docker?
Aunque podríamos instalar FFmpeg directamente sobre LibreELEC, preferimos encapsular todo el proceso de captura dentro de un contenedor.
Esto presenta varias ventajas:
- LibreELEC permanece completamente limpio.
- Las actualizaciones son mucho más sencillas.
- Podemos reconstruir todo el sistema en pocos minutos.
- Resulta muy fácil realizar copias de seguridad.
- Si algo falla basta con eliminar el contenedor y volver a crearlo.
Además, toda la configuración queda perfectamente aislada del sistema operativo.
Comprobaciones finales
Antes de continuar asegúrate de que puedes responder afirmativamente a todas estas preguntas.
✔ LibreELEC detecta la capturadora.
✔ Existe /dev/video0.
✔ Existe un dispositivo ALSA correspondiente a la capturadora.
✔ Docker está instalado y funcionando.
Si todo es correcto ya estamos preparados para comenzar a construir nuestro servidor RTSP.
Instalando MediaMTX: el corazón de nuestro servidor RTSP
Hasta ahora únicamente hemos preparado el entorno de trabajo.
Nuestro equipo reconoce la capturadora, Docker está funcionando y disponemos tanto de vídeo como de audio HDMI.
Ahora necesitamos un componente fundamental.
Necesitamos un servidor capaz de publicar el flujo RTSP que generará FFmpeg.
Existen varias alternativas:
- GStreamer
- Live555
- VLC
- FFserver (ya desaparecido)
- RTSP Simple Server
Sin embargo, durante los últimos años ha aparecido un proyecto que ha terminado convirtiéndose prácticamente en el estándar para este tipo de aplicaciones.
Su nombre es MediaMTX.
¿Qué es MediaMTX?
MediaMTX es un servidor multimedia extremadamente ligero diseñado específicamente para distribuir flujos de vídeo en tiempo real.
Aunque inicialmente nació como un simple servidor RTSP, con el paso del tiempo ha evolucionado hasta convertirse en una plataforma muy completa capaz de trabajar con distintos protocolos:
- RTSP
- RTMP
- HLS
- WebRTC
- SRT
- MPEG-TS
- HTTP
En nuestro caso únicamente utilizaremos RTSP, pero resulta interesante conocer todo su potencial.
¿Por qué hemos elegido MediaMTX?
Durante el desarrollo de este proyecto probamos distintas soluciones.
La razón por la que finalmente nos decidimos por MediaMTX fue muy sencilla.
Necesitábamos que la capturadora permaneciera completamente apagada cuando nadie estuviera utilizando el vídeo.
Y MediaMTX incorpora precisamente una característica que resulta perfecta para ello.
Se llama:
runOnDemand
Gracias a esta opción, MediaMTX puede ejecutar un programa automáticamente cuando el primer cliente solicita un flujo RTSP.
Y detener dicho programa cuando desaparece el último cliente.
Eso significa que no necesitamos mantener FFmpeg funcionando permanentemente.
Funcionamiento
Sin clientes:
FFmpeg
DETENIDO
Docker
DETENIDO
Consumo prácticamente nulo.
Cuando alguien abre:
rtsp://IP_DEL_SERVIDOR:8554/vhs
MediaMTX hace automáticamente:
Ejecutar FFmpeg
El flujo comienza a publicarse.
Cuando el último cliente se desconecta:
Detener FFmpeg
Todo vuelve al estado inicial.
Esta característica será una de las claves de todo el proyecto.
Descargando MediaMTX
La última versión puede descargarse directamente desde GitHub.
En nuestro caso utilizamos la versión:
1.19.2
Descargamos el paquete:
wget https://github.com/bluenviron/mediamtx/releases/download/v1.19.2/mediamtx_v1.19.2_linux_amd64.tar.gz
Descomprimimos:
tar xzf mediamtx_v1.19.2_linux_amd64.tar.gz
A continuación crearemos un directorio específico dentro de LibreELEC.
mkdir -p /storage/mediamtx
Copiamos los archivos descargados.
Nuestro árbol de directorios quedará aproximadamente así:
/storage
└── mediamtx
├── mediamtx
├── mediamtx.yml
└── LICENSE
Primer arranque
Antes de modificar ninguna configuración comprobaremos que el servidor funciona.
Entramos en el directorio:
cd /storage/mediamtx
Y ejecutamos:
./mediamtx
Si todo ha ido correctamente veremos una salida similar a esta:
MediaMTX
RTSP started
RTMP started
HLS started
WebRTC started
Eso significa que el servidor está funcionando correctamente.
En este momento todavía no publica ningún flujo.
Simplemente permanece esperando conexiones.
Podemos detenerlo pulsando:
CTRL + C
Organización de los directorios
Aunque MediaMTX puede ejecutarse desde cualquier ubicación, es recomendable mantener una estructura organizada.
Durante este proyecto utilizaremos la siguiente:
/storage
├── mediamtx
├── capturadora
└── recordings
Cada directorio tendrá una misión concreta.
mediamtx
Contendrá exclusivamente el servidor RTSP y su configuración.
capturadora
Aquí almacenaremos los scripts relacionados con Docker y FFmpeg.
recordings
Más adelante será el lugar donde se almacenarán las digitalizaciones.
Mantener esta separación facilita enormemente el mantenimiento del sistema.
Configuración por defecto
Antes de modificar el fichero principal conviene abrirlo y echar un vistazo.
nano mediamtx.yml
Veremos un fichero bastante largo.
No debemos asustarnos.
MediaMTX soporta multitud de protocolos y opciones.
En realidad únicamente modificaremos una pequeña parte.
Todo lo demás permanecerá exactamente igual.
Lo importante: los Paths
La sección que realmente nos interesa es:
paths:
Podemos imaginarla como una lista de canales.
Por ejemplo:
/camara
/vhs
/dvd
/consola
Cada uno de esos nombres correspondería a un flujo RTSP diferente.
En nuestro caso únicamente utilizaremos uno:
vhs
Ese será el nombre del flujo que utilizaremos durante todo el proyecto.
El siguiente paso
Hasta ahora MediaMTX simplemente espera clientes.
En el próximo capítulo configuraremos nuestro primer flujo RTSP.
Y será precisamente ahí donde aparecerá la característica que hace tan especial a MediaMTX:
runOnDemand
Gracias a ella conseguiremos que la capturadora permanezca completamente apagada cuando nadie esté viendo el vídeo y que todo el sistema se active automáticamente cuando aparezca el primer cliente RTSP.
Ese comportamiento será, probablemente, la característica más interesante de todo el proyecto y uno de los motivos por los que elegimos esta arquitectura frente a otras alternativas.
Configurando MediaMTX para capturar únicamente bajo demanda
En el capítulo anterior dejamos MediaMTX instalado y funcionando.
Si intentáramos acceder ahora al flujo RTSP, comprobaríamos que el servidor responde correctamente, pero no existe ninguna fuente de vídeo asociada.
Es el momento de decirle qué debe hacer cuando alguien solicite el flujo.
Y aquí aparece una de las características más interesantes de MediaMTX.
El concepto de «captura bajo demanda»
La mayoría de sistemas de captura funcionan de una forma muy simple.
Nada más arrancar el ordenador:
- FFmpeg comienza a capturar.
- La capturadora permanece funcionando.
- La CPU y la GPU están trabajando continuamente.
- Aunque nadie esté viendo el vídeo.
Es un sistema sencillo, pero poco eficiente.
Nosotros vamos a hacer exactamente lo contrario.
Mientras no exista ningún cliente conectado:
Capturadora apagada
FFmpeg detenido
Docker detenido
Consumo prácticamente nulo
Cuando alguien abra el flujo RTSP:
VLC
Kodi
OBS
FFplay
MediaMTX detectará automáticamente esa petición y lanzará el proceso de captura.
Cuando el último cliente abandone la reproducción, MediaMTX volverá a detener todo el sistema.
Este comportamiento hace que el equipo permanezca prácticamente inactivo durante la mayor parte del tiempo.
¿Cómo consigue MediaMTX hacer esto?
Todo ocurre gracias a una opción llamada:
runOnDemand
Esta opción permite ejecutar cualquier programa cuando aparece el primer cliente.
No tiene por qué ser FFmpeg.
Podría ser:
- un script Bash;
- un programa en Python;
- Docker;
- cualquier aplicación instalada en el sistema.
Nosotros utilizaremos un pequeño script que será el encargado de arrancar el contenedor Docker donde se ejecutará FFmpeg.
Organizando nuestro proyecto
Antes de continuar crearemos un directorio específico para todos los scripts relacionados con la capturadora.
mkdir -p /storage/capturadora
La estructura quedará así:
/storage
├── capturadora
├── mediamtx
└── recordings
Dentro de este directorio iremos almacenando todos los elementos relacionados con la captura.
El script de arranque
Creamos un nuevo archivo.
nano /storage/capturadora/run_ondemand.sh
Introducimos el siguiente contenido.
#!/bin/sh
docker stop capturadora-ms2109 >/dev/null 2>&1
trap 'docker stop capturadora-ms2109 >/dev/null 2>&1' EXIT INT TERM
docker start -a capturadora-ms2109
Guardamos el archivo.
Y ahora es muy importante convertirlo en ejecutable.
chmod +x /storage/capturadora/run_ondemand.sh
¿Qué hace realmente este script?
Aunque únicamente contiene tres instrucciones, merece la pena analizarlas.
La primera línea:
docker stop capturadora-ms2109
garantiza que el contenedor no se encuentre ya en ejecución.
Es una medida de seguridad.
En caso de que hubiera quedado arrancado por cualquier motivo, se detendrá antes de volver a iniciarlo.
La segunda línea:
trap ...
es probablemente la más interesante.
Le indica al sistema:
Cuando este script termine, detén automáticamente el contenedor.
Es decir, cuando MediaMTX decida que ya no quedan clientes conectados, el propio script apagará la captura.
No tendremos que preocuparnos de ello.
Finalmente:
docker start -a capturadora-ms2109
arranca el contenedor Docker y permanece esperando hasta que finalice.
Mientras tanto, FFmpeg estará capturando vídeo y publicándolo mediante RTSP.
Configurando MediaMTX
Abrimos nuevamente el archivo de configuración.
nano /storage/mediamtx/mediamtx.yml
Buscamos la sección:
paths:
Y añadimos:
paths:
vhs:
source: publisher
runOnDemand: /storage/capturadora/run_ondemand.sh
runOnDemandRestart: no
runOnDemandStartTimeout: 30s
runOnDemandCloseAfter: 10s
Vamos a explicar qué significa cada parámetro.
source: publisher
Le indica a MediaMTX que el flujo será publicado por un proceso externo.
En nuestro caso será FFmpeg.
runOnDemand
Es el corazón de todo el sistema.
Cuando llegue el primer cliente RTSP, MediaMTX ejecutará automáticamente el script indicado.
runOnDemandRestart
Al establecer:
runOnDemandRestart: no
evitamos que MediaMTX intente reiniciar continuamente el proceso en caso de error.
Esto facilita enormemente la depuración.
runOnDemandStartTimeout
30s
MediaMTX esperará hasta treinta segundos para que FFmpeg comience a publicar el flujo.
Normalmente el proceso tarda apenas unos segundos, pero disponer de un margen amplio evita falsos errores.
runOnDemandCloseAfter
10s
Cuando desaparezca el último cliente conectado, MediaMTX esperará diez segundos antes de detener FFmpeg.
¿Por qué?
Porque resulta muy habitual que un reproductor cierre y vuelva a abrir el flujo inmediatamente al cambiar de resolución o al reconectar.
Con esos diez segundos evitamos arrancar y detener continuamente el contenedor.
Reiniciando MediaMTX
Una vez guardados los cambios reiniciamos el servidor.
pkill mediamtx
cd /storage/mediamtx
./mediamtx
Si todo ha ido correctamente veremos un mensaje similar a:
MediaMTX started
Path "vhs" ready
Todavía no habrá comenzado la captura.
Simplemente estará esperando.
¿Cómo comprobar que funciona?
En este momento todavía no existe ningún flujo de vídeo.
Podemos comprobarlo fácilmente.
Mientras MediaMTX está esperando ejecutamos:
docker ps
No debería aparecer ningún contenedor relacionado con la capturadora.
Ahora, desde otro ordenador de la red, abrimos:
rtsp://IP_DEL_SERVIDOR:8554/vhs
En ese mismo instante ocurrirá toda la secuencia automáticamente.
Cliente RTSP
↓
MediaMTX detecta la petición
↓
Ejecuta run_ondemand.sh
↓
Docker inicia FFmpeg
↓
FFmpeg comienza la captura
↓
MediaMTX publica el flujo
Cuando cerremos VLC o Kodi:
El último cliente abandona el flujo
↓
MediaMTX espera diez segundos
↓
Finaliza el script
↓
Docker detiene FFmpeg
↓
Sistema nuevamente en reposo
Y todo ello sin necesidad de intervención del usuario.
Una solución elegante y eficiente
Este mecanismo presenta una enorme ventaja frente a los sistemas tradicionales.
Mientras nadie utiliza la capturadora:
- la CPU permanece prácticamente inactiva;
- la GPU no realiza ninguna codificación;
- la capturadora permanece en reposo;
- el consumo eléctrico es mínimo.
Solo cuando realmente alguien necesita acceder al vídeo se ponen en marcha todos los componentes.
Desde el punto de vista energético y de rendimiento es una solución muy elegante.
Construyendo el contenedor Docker con FFmpeg
Ya tenemos preparado MediaMTX y sabemos que es capaz de arrancar automáticamente cualquier proceso cuando aparece el primer cliente RTSP.
Ahora necesitamos crear ese proceso.
Ese proceso será FFmpeg.
Sin embargo, en lugar de instalarlo directamente sobre LibreELEC, lo ejecutaremos dentro de un contenedor Docker.
¿Por qué Docker?
Aunque instalar FFmpeg directamente podría parecer más sencillo, utilizar Docker aporta varias ventajas muy importantes.
La primera de ellas es el aislamiento.
Todo el software relacionado con la captura quedará completamente separado del sistema operativo.
Si mañana queremos actualizar FFmpeg, probar otra versión o modificar parámetros de codificación, simplemente reconstruiremos el contenedor.
LibreELEC permanecerá completamente intacto.
Además, este enfoque facilita enormemente las copias de seguridad y hace posible reconstruir todo el sistema en apenas unos minutos.
Creando el directorio de trabajo
Dentro del directorio de la capturadora crearemos un pequeño espacio para nuestro proyecto Docker.
mkdir -p /storage/capturadora
cd /storage/capturadora
A partir de este momento todos los archivos relacionados con la captura quedarán almacenados aquí.
Nuestro primer Dockerfile
Creamos un archivo llamado:
Dockerfile
nano Dockerfile
Su contenido será el siguiente.
FROM debian:bookworm-slim
RUN apt update && \
apt install -y \
ffmpeg \
alsa-utils && \
apt clean && \
rm -rf /var/lib/apt/lists/*
COPY capture.sh /capture.sh
RUN chmod +x /capture.sh
ENTRYPOINT ["/capture.sh"]
CMD ["preview"]
Aunque apenas ocupa unas pocas líneas, este fichero realiza todo el trabajo necesario para construir nuestro contenedor.
Analizando el Dockerfile
La primera línea indica la imagen base que utilizaremos.
FROM debian:bookworm-slim
Elegimos Debian porque ofrece un excelente soporte para FFmpeg y dispone de paquetes muy actualizados.
Además, la versión slim reduce considerablemente el tamaño de la imagen.
A continuación instalamos únicamente dos paquetes.
ffmpeg
alsa-utils
No necesitamos nada más.
El objetivo es mantener la imagen lo más pequeña posible.
Posteriormente copiamos nuestro script de captura.
COPY capture.sh /capture.sh
Ese script será el encargado de ejecutar FFmpeg con todos los parámetros adecuados.
Finalmente indicamos cuál será el programa principal del contenedor.
ENTRYPOINT ["/capture.sh"]
Cada vez que Docker arranque este contenedor ejecutará automáticamente dicho script.
¿Por qué un script?
Podríamos haber escrito directamente el comando FFmpeg dentro del Dockerfile.
Sin embargo, utilizar un pequeño script Bash presenta numerosas ventajas.
Permite:
- modificar parámetros sin reconstruir toda la imagen;
- reutilizar el mismo contenedor para distintos modos de funcionamiento;
- mantener la configuración mucho más ordenada.
Además, facilita enormemente la lectura del proyecto.
Creando capture.sh
Creamos ahora el archivo principal.
nano capture.sh
Aquí será donde realmente construiremos nuestro flujo RTSP.
La capturadora
Antes de escribir una sola línea de FFmpeg debemos recordar una característica importante.
Nuestra capturadora entrega vídeo mediante MJPEG.
Durante las pruebas comprobamos que este modo ofrecía el mejor equilibrio entre calidad y rendimiento.
Aunque también soporta YUYV sin compresión, la enorme cantidad de datos que genera hace que no resulte práctico para un funcionamiento continuo.
Por ese motivo utilizaremos MJPEG como formato de entrada.
Capturando vídeo
La primera parte del comando indica a FFmpeg cómo acceder al dispositivo.
-f v4l2
-input_format mjpeg
-video_size 1280x720
-framerate 30
-i /dev/video0
Cada uno de estos parámetros tiene una función concreta.
El primero indica que utilizaremos Video4Linux.
Después especificamos el formato de entrada.
A continuación fijamos la resolución y la frecuencia de imágenes.
Finalmente indicamos el dispositivo de captura.
Capturando el audio HDMI
La mayoría de capturadoras HDMI también incorporan una tarjeta de sonido USB.
En nuestro caso la entrada se encontraba en:
hw:0,0
Por ello añadimos:
-f alsa
-i hw:0,0
Con estas dos líneas FFmpeg comenzará a capturar simultáneamente el vídeo y el audio procedentes de la misma entrada HDMI.
¿Por qué utilizamos VAAPI?
Hasta ahora únicamente estamos leyendo la señal.
Sin embargo, antes de publicarla por RTSP debemos comprimirla.
Podríamos utilizar el codificador software x264.
Funcionaría perfectamente.
Pero supondría mantener varios núcleos del procesador trabajando continuamente.
En nuestro caso disponemos de una GPU Intel compatible con VAAPI.
Eso significa que será la propia tarjeta gráfica quien realizará toda la compresión H.264.
El resultado es espectacular.
Durante nuestras pruebas el consumo de CPU descendió desde valores superiores al 100 % hasta apenas un 10–15 %, manteniendo además una calidad de imagen excelente.
Configurando VAAPI
El dispositivo gráfico utilizado será:
/dev/dri/renderD128
Lo indicamos mediante:
-vaapi_device /dev/dri/renderD128
A continuación adaptamos el formato de imagen para que pueda ser procesado por el codificador hardware.
-vf "setsar=1,setdar=16/9,format=nv12,hwupload"
Esta línea realiza varias tareas al mismo tiempo.
Corrige el aspecto de la imagen, la convierte al formato NV12 requerido por VAAPI y la transfiere directamente a la GPU.
Configurando el codificador
Finalmente configuramos H.264.
-c:v h264_vaapi
-qp 18
-g 60
Durante las pruebas encontramos que un valor de QP igual a 18 ofrecía un equilibrio excelente entre calidad y tamaño del flujo.
No se trata de un valor obligatorio.
Cada usuario puede modificarlo posteriormente según sus necesidades.
Configurando el audio
Para el audio utilizaremos AAC.
-c:a aac
-b:a 192k
-ar 48000
-ac 2
AAC garantiza una excelente compatibilidad con prácticamente cualquier cliente RTSP moderno.
Además mantiene un tamaño muy reducido.
El resultado
En este punto ya disponemos de un contenedor Docker capaz de:
- capturar vídeo HDMI;
- capturar audio HDMI;
- utilizar la GPU Intel para codificar H.264;
- generar audio AAC;
- mantener un consumo muy reducido.
Sin embargo, todavía falta el paso más importante.
Todavía no estamos enviando esa señal a ningún sitio.
Publicando el flujo RTSP y consiguiendo una captura completamente automática
Hasta este momento ya tenemos prácticamente todas las piezas preparadas.
Disponemos de:
- LibreELEC funcionando.
- Docker instalado.
- MediaMTX configurado.
- Un contenedor capaz de capturar vídeo y audio HDMI utilizando la GPU Intel.
Sin embargo, todavía falta unir todas esas piezas.
Nuestro objetivo es que cualquier dispositivo de la red pueda abrir simplemente esta dirección:
rtsp://IP_DEL_SERVIDOR:8554/vhs
Y que, automáticamente:
- arranque el contenedor Docker,
- comience la captura,
- se publique el flujo RTSP,
- y todo vuelva a apagarse cuando el último cliente cierre la reproducción.
Ese comportamiento será completamente transparente para el usuario.
¿Por qué no utilizar FFmpeg como servidor RTSP?
Es una pregunta muy habitual.
FFmpeg puede actuar como servidor RTSP.
Entonces…
¿Por qué complicarnos utilizando MediaMTX?
La respuesta es sencilla.
Porque FFmpeg únicamente sabe capturar y codificar.
MediaMTX, en cambio, está pensado para gestionar clientes.
Gracias a MediaMTX obtenemos automáticamente:
- múltiples clientes simultáneos;
- desconexiones automáticas;
- reconexiones;
- publicación mediante distintos protocolos;
- y, sobre todo, la captura bajo demanda.
Por tanto, FFmpeg se dedicará únicamente a hacer aquello para lo que fue diseñado:
capturar vídeo.
Y MediaMTX hará aquello para lo que también fue diseñado:
distribuirlo.
Separar ambas funciones simplifica muchísimo el sistema.
El flujo de trabajo
A partir de este momento el funcionamiento será el siguiente.
Cliente
↓
Solicita
rtsp://SERVIDOR:8554/vhs
↓
MediaMTX
↓
Ejecuta run_ondemand.sh
↓
Docker
↓
FFmpeg
↓
Captura HDMI
↓
Publicación RTSP
↓
Cliente recibe el vídeo
Cuando el último cliente desaparezca:
Cliente desconectado
↓
MediaMTX espera unos segundos
↓
Finaliza run_ondemand.sh
↓
Docker se detiene
↓
FFmpeg finaliza
↓
Sistema nuevamente en reposo
Todo ocurre de forma completamente automática.
El script de captura
Nuestro contenedor ejecutará un único programa.
Ese programa será:
capture.sh
La misión de este script será muy sencilla.
- Capturar vídeo HDMI.
- Capturar audio HDMI.
- Codificar mediante VAAPI.
- Publicar el flujo RTSP.
Nada más.
Cuanto más sencillo sea este script, más fácil resultará mantenerlo en el futuro.
Publicando el flujo
La parte final del comando FFmpeg será la encargada de enviar el flujo a MediaMTX.
-f rtsp \
-rtsp_transport tcp \
rtsp://127.0.0.1:8554/vhs
Aquí aparecen dos decisiones importantes.
¿Por qué utilizamos 127.0.0.1?
Puede sorprender que publiquemos el flujo hacia la propia máquina.
Sin embargo, tiene todo el sentido.
FFmpeg y MediaMTX se ejecutan en el mismo equipo.
Por tanto, no existe ninguna razón para enviar ese tráfico a través de la red física.
Utilizar:
127.0.0.1
reduce ligeramente la latencia y evita depender de la configuración de red del equipo.
MediaMTX será quien posteriormente entregue el flujo a los clientes externos.
¿Por qué TCP?
RTSP permite trabajar mediante UDP o TCP.
Aunque UDP suele ofrecer una latencia ligeramente inferior, durante nuestras pruebas comprobamos que TCP resultaba mucho más estable.
Especialmente cuando los clientes eran:
- Kodi
- VLC
- FFprobe
Por ese motivo decidimos forzar el transporte TCP.
-rtsp_transport tcp
El aumento de latencia es prácticamente inapreciable y, a cambio, obtenemos un flujo mucho más robusto.
¿Qué ocurre cuando Kodi solicita el vídeo?
Veamos todo el proceso paso a paso.
El usuario selecciona:
Ver fuente analógica
Kodi intenta abrir:
rtsp://SERVIDOR:8554/vhs
En ese instante todavía no existe ningún flujo.
MediaMTX detecta esa petición.
Ejecuta automáticamente:
run_ondemand.sh
Ese script arranca Docker.
Docker inicia FFmpeg.
FFmpeg comienza a capturar.
Apenas unos segundos después, MediaMTX recibe el flujo publicado por FFmpeg.
Y finalmente Kodi comienza a reproducir el vídeo.
Todo este proceso suele completarse en muy pocos segundos.
Desde el punto de vista del usuario simplemente parece que la fuente tarda un instante en conectarse.
¿Qué ocurre cuando cerramos Kodi?
El proceso es exactamente el inverso.
Kodi deja de solicitar el flujo.
MediaMTX detecta que ya no existen clientes.
Espera el tiempo configurado mediante:
runOnDemandCloseAfter
Y finalmente finaliza el script.
El propio script se encarga de detener Docker.
Docker detiene FFmpeg.
La capturadora deja de trabajar.
Y el sistema vuelve nuevamente al estado de reposo.
Comprobando que realmente funciona
La mejor forma de comprobar que todo está correctamente configurado consiste en observar el comportamiento del sistema.
Antes de abrir el flujo ejecutamos:
docker ps
No debería aparecer ningún contenedor relacionado con la captura.
Ahora abrimos el flujo RTSP desde VLC.
Inmediatamente volvemos a ejecutar:
docker ps
Esta vez aparecerá nuestro contenedor.
Al cerrar VLC…
Volvemos a ejecutar el mismo comando.
Unos segundos después el contenedor habrá desaparecido nuevamente.
Eso confirma que la captura bajo demanda está funcionando correctamente.
Verificando el flujo
Otra herramienta extremadamente útil es:
ffprobe
Podemos comprobar exactamente qué está publicando MediaMTX.
ffprobe -rtsp_transport tcp rtsp://127.0.0.1:8554/vhs
Una salida correcta será similar a esta.
Video:
H.264
1280x720
30 fps
Audio:
AAC
48000 Hz
Stereo
Esta comprobación resulta especialmente útil cuando estamos depurando problemas relacionados con el audio o con la codificación del vídeo.
Una solución sorprendentemente eficiente
Uno de los aspectos que más nos sorprendió durante el desarrollo fue el reducido consumo del sistema.
Cuando ningún cliente solicita el flujo:
- Docker permanece detenido.
- FFmpeg no consume CPU.
- La GPU Intel permanece inactiva.
- La capturadora prácticamente no trabaja.
Es decir…
Nuestro servidor RTSP consume prácticamente lo mismo que un LibreELEC funcionando únicamente con Kodi.
Y solo cuando realmente alguien necesita acceder al vídeo se ponen en marcha todos los componentes.
Ese comportamiento convierte este sistema en una solución extremadamente eficiente para un funcionamiento continuo.
Haciendo que todo funcione automáticamente después de un reinicio
Hasta este momento ya tenemos un servidor RTSP completamente funcional.
Podemos abrir el flujo desde:
- Kodi
- VLC
- FFplay
- OBS Studio
La capturadora únicamente comienza a trabajar cuando aparece el primer cliente y vuelve a detenerse cuando desaparece el último.
Sin embargo, todavía existe un pequeño inconveniente.
¿Qué ocurre si apagamos el equipo?
O, peor todavía…
¿Qué sucede si se produce un corte eléctrico?
Si al volver a encender el ordenador tenemos que ejecutar manualmente MediaMTX, realmente todavía no hemos terminado el proyecto.
Nuestro objetivo es mucho más ambicioso.
Queremos que el sistema se comporte exactamente igual que un NAS o un router.
Es decir:
Encender.
Esperar unos segundos.
Y olvidarnos de él.
Cómo arranca LibreELEC
Antes de automatizar nada conviene comprender cómo funciona LibreELEC.
A diferencia de otras distribuciones Linux, LibreELEC está pensado para arrancar directamente en Kodi.
Todo el proceso de inicio es extremadamente rápido.
Cuando el sistema termina de cargar:
- inicia los servicios internos;
- monta el almacenamiento;
- prepara la red;
- y finalmente lanza Kodi.
Precisamente por esa simplicidad resulta tan estable.
¿Dónde debemos colocar nuestros scripts?
Una de las ventajas de LibreELEC es que dispone de un directorio específico para personalizaciones del usuario.
Ese directorio es:
/storage/.config
Todo lo que coloquemos aquí permanecerá intacto incluso después de actualizar LibreELEC.
Es el lugar recomendado para añadir scripts propios.
El archivo autostart.sh
LibreELEC incorpora un mecanismo muy sencillo para ejecutar acciones al arrancar el sistema.
Simplemente debemos crear el archivo:
/storage/.config/autostart.sh
Si no existe, lo creamos.
nano /storage/.config/autostart.sh
¿Qué vamos a hacer aquí?
Nuestro objetivo es muy simple.
Cada vez que LibreELEC termine de arrancar:
- MediaMTX deberá iniciarse automáticamente.
- Quedará esperando clientes RTSP.
- No arrancará todavía la capturadora.
- No iniciará Docker.
- Simplemente permanecerá preparado.
Eso significa que, aunque reiniciemos el equipo, el comportamiento seguirá siendo exactamente el mismo.
Contenido del script
Nuestro script será muy sencillo.
#!/bin/sh
sleep 15
/storage/mediamtx/mediamtx \
>/storage/mediamtx/mediamtx.log 2>&1 &
Y, por supuesto, debemos convertirlo en ejecutable.
chmod +x /storage/.config/autostart.sh
¿Por qué esperamos quince segundos?
Puede parecer extraño.
¿Por qué no iniciar MediaMTX inmediatamente?
Durante nuestras pruebas comprobamos que LibreELEC todavía continúa inicializando distintos servicios durante los primeros segundos del arranque.
Esperar unos instantes garantiza que:
- Docker ya está disponible.
- La red está completamente operativa.
- Los dispositivos USB ya han sido detectados.
- Kodi ha terminado de iniciar.
No existe ninguna prisa.
MediaMTX únicamente comenzará a esperar conexiones.
¿Por qué redirigimos la salida?
Observa esta parte.
>/storage/mediamtx/mediamtx.log 2>&1
Con ella conseguimos que todos los mensajes de MediaMTX se almacenen en un único archivo.
Esto presenta dos ventajas.
La primera.
El sistema permanece completamente limpio.
No aparecen mensajes innecesarios por pantalla.
La segunda.
Si algún día algo deja de funcionar podremos consultar inmediatamente el registro.
cat /storage/mediamtx/mediamtx.log
O, más útil todavía.
tail -50 /storage/mediamtx/mediamtx.log
Durante el desarrollo esta información nos permitió localizar prácticamente todos los problemas encontrados.
Comprobando el funcionamiento
Llegados a este punto ya podemos reiniciar el equipo con tranquilidad.
reboot
Esperamos aproximadamente un minuto.
Volvemos a conectarnos mediante SSH.
Y comprobamos que MediaMTX está ejecutándose.
pidof mediamtx
Si obtenemos un número similar a este:
2145
significa que el servidor ya está funcionando.
También podemos comprobarlo revisando el registro.
tail -20 /storage/mediamtx/mediamtx.log
Deberíamos encontrar mensajes parecidos a:
MediaMTX started
RTSP started
Path vhs ready
Eso confirma que todo ha arrancado correctamente.
Probando la captura automática
La última comprobación consiste en abrir el flujo desde cualquier cliente RTSP.
Por ejemplo, desde VLC.
rtsp://IP_DEL_SERVIDOR:8554/vhs
En ese momento debería producirse automáticamente toda la secuencia.
MediaMTX
↓
runOnDemand
↓
Docker
↓
FFmpeg
↓
Captura HDMI
↓
Vídeo en VLC
Y, al cerrar VLC.
Docker detenido
↓
FFmpeg detenido
↓
MediaMTX continúa esperando
Todo ello sin intervención del usuario.
Un servidor que podemos olvidar
Llegados a este punto hemos conseguido exactamente el comportamiento que buscábamos al comenzar el proyecto.
Podemos apagar el equipo.
Podemos reiniciarlo.
Incluso puede producirse un corte eléctrico.
En cuanto LibreELEC vuelva a arrancar:
- MediaMTX se iniciará automáticamente.
- El servidor RTSP volverá a quedar disponible.
- La capturadora permanecerá completamente inactiva.
- El consumo seguirá siendo prácticamente nulo.
Y únicamente cuando alguien solicite el flujo comenzará realmente la captura.
Desde ese momento el sistema puede permanecer funcionando durante meses sin necesidad de realizar ninguna intervención manual.
Diagnóstico, resolución de problemas y optimización
Si has llegado hasta aquí, probablemente ya tengas un servidor RTSP completamente funcional.
Sin embargo, durante el desarrollo de este proyecto aparecieron numerosos problemas que no suelen documentarse y que pueden hacer perder muchas horas de depuración.
En este capítulo reuniremos todos ellos.
La mayoría proceden de situaciones reales encontradas durante el desarrollo de Analog Center.
Comprobación rápida del sistema
Antes de empezar a buscar errores conviene responder a una pregunta muy sencilla.
¿En qué punto del proceso está fallando el sistema?
Para ello podemos seguir este pequeño esquema.
¿MediaMTX está funcionando?
│
▼
¿Docker arranca?
│
▼
¿FFmpeg detecta la capturadora?
│
▼
¿Se publica el flujo RTSP?
│
▼
¿El cliente reproduce correctamente?
Responder a esas cinco preguntas suele permitir localizar el problema en muy pocos minutos.
Problema 1
MediaMTX no arranca
El síntoma suele ser:
Connection refused
o
404 Not Found
Lo primero es comprobar que realmente está ejecutándose.
pidof mediamtx
Si no devuelve ningún proceso:
tail -50 /storage/mediamtx/mediamtx.log
En la mayoría de ocasiones el problema aparecerá claramente indicado en el registro.
Problema 2
MediaMTX no encuentra el flujo
El cliente muestra:
No stream available
Normalmente significa que FFmpeg todavía no ha comenzado a publicar.
Podemos comprobarlo mediante:
docker ps
Si el contenedor no aparece, probablemente exista un problema en:
runOnDemand
o en el propio script:
run_ondemand.sh
Problema 3
Docker no arranca
Comprobaremos:
docker ps -a
Y posteriormente:
docker logs capturadora-ms2109
Prácticamente todos los errores relacionados con FFmpeg aparecerán aquí.
Problema 4
No aparece /dev/video0
La capturadora no ha sido detectada correctamente.
Comprobaremos:
lsusb
y
v4l2-ctl --list-devices
Si no aparece, el problema no está en Docker.
Está en el propio hardware.
Puede tratarse de:
- cable USB defectuoso;
- alimentación insuficiente;
- capturadora incompatible;
- puerto USB dañado.
Problema 5
No existe audio HDMI
La imagen funciona.
El sonido no.
Primero comprobaremos que Linux detecta realmente la tarjeta de sonido.
cat /proc/asound/cards
Después:
ls /dev/snd
Y finalmente:
ffprobe rtsp://127.0.0.1:8554/vhs
Si aparece:
Audio:
AAC
48000 Hz
Stereo
El problema ya no se encuentra en FFmpeg.
Debemos revisar el reproductor utilizado.
Problema 6
El vídeo consume demasiada CPU
Probablemente VAAPI no esté funcionando.
Comprobaremos que existe:
ls /dev/dri
Debe aparecer:
renderD128
También podemos observar el consumo mediante:
top
Si FFmpeg ocupa más de un núcleo completo probablemente esté utilizando codificación software.
Problema 7
El vídeo aparece estirado
Las capturadoras HDMI suelen entregar una resolución fija.
Para corregir el aspecto utilizamos:
setsar=1
setdar=16/9
Estas dos opciones indican al reproductor cuál es el aspecto correcto de la imagen.
Problema 8
El flujo RTSP no se reproduce
La primera comprobación siempre debe realizarse con:
ffprobe rtsp://127.0.0.1:8554/vhs
Si FFprobe recibe correctamente:
- vídeo
- audio
el problema no está en el servidor.
Se encuentra en el cliente.
Problema 9
Docker permanece funcionando siempre
Normalmente significa que:
runOnDemandCloseAfter
no está configurado correctamente.
O bien existe algún cliente que continúa conectado.
Podemos comprobar los registros de MediaMTX.
tail -50 /storage/mediamtx/mediamtx.log
Problema 10
Después de reiniciar el equipo no funciona
Lo primero es comprobar:
pidof mediamtx
Si no aparece ningún proceso:
revisaremos:
/storage/.config/autostart.sh
Y comprobaremos que dispone de permisos de ejecución.
chmod +x /storage/.config/autostart.sh
Herramientas imprescindibles
Durante todo el desarrollo prácticamente siempre utilizamos las mismas herramientas.
FFprobe
ffprobe
Permite comprobar inmediatamente qué está publicando realmente el servidor.
Docker
docker ps
docker logs
Es la forma más rápida de localizar errores de FFmpeg.
MediaMTX
tail -50 mediamtx.log
Indica exactamente cuándo llegan clientes y cuándo desaparecen.
Top
top
Nos permite comprobar si realmente la GPU está realizando la codificación.
Un sistema sorprendentemente estable
Después de numerosas pruebas, reinicios y modificaciones, el resultado final fue sorprendentemente satisfactorio.
Una vez configurado:
- el sistema arranca automáticamente;
- MediaMTX permanece esperando clientes;
- Docker únicamente se ejecuta cuando realmente es necesario;
- la GPU Intel realiza toda la codificación H.264;
- el consumo eléctrico permanece muy reducido;
- el funcionamiento resulta completamente transparente para el usuario.
En el día a día, la experiencia es muy similar a la de un equipo profesional dedicado exclusivamente a distribuir vídeo por la red.
Conclusiones
Cuando comenzamos este proyecto el objetivo parecía bastante sencillo: compartir por la red la señal procedente de una capturadora HDMI USB.
Sin embargo, conforme avanzaba el desarrollo aparecieron nuevos retos.
No solo queríamos capturar vídeo.
Queríamos construir un sistema eficiente, estable y completamente automático.
La combinación de LibreELEC, Docker, FFmpeg, VAAPI y MediaMTX nos permitió conseguir exactamente eso.
El resultado es un servidor RTSP que:
- solo consume recursos cuando realmente alguien solicita el vídeo;
- aprovecha la aceleración hardware de la GPU Intel;
- mantiene un consumo energético muy reducido;
- y continúa funcionando correctamente incluso después de apagar o reiniciar el equipo.
Lo más interesante de todo es que esta arquitectura no está limitada a un reproductor VHS.
Puede utilizarse exactamente igual para:
- cámaras HDMI;
- videoconsolas;
- decodificadores de televisión;
- receptores de satélite;
- cámaras réflex con salida HDMI;
- reproductores Blu-ray;
- o cualquier otro dispositivo capaz de generar una señal HDMI.
En nuestro caso este proyecto terminó convirtiéndose en la base de un sistema mucho más ambicioso: Analog Center, una aplicación integrada en Kodi para visualizar y digitalizar automáticamente cualquier fuente analógica.
Integrando la capturadora HDMI en Kodi: visualización y grabación mediante IPTV
En la primera parte de este tutorial construimos un servidor RTSP bajo demanda utilizando LibreELEC, Docker, FFmpeg y MediaMTX.
El resultado era un servidor completamente autónomo capaz de publicar un flujo RTSP únicamente cuando existía algún cliente conectado.
Sin embargo, todavía faltaba una pieza importante.
Nuestro objetivo no era simplemente disponer de un flujo RTSP.
Queríamos que la experiencia de uso fuera similar a la de un reproductor multimedia convencional.
Es decir, sentarnos frente al televisor, coger el mando a distancia y poder seleccionar:
📼 Analógico
▶ Ver fuente
⏺ Grabar
📁 Grabaciones
Para conseguirlo decidimos aprovechar una de las funciones más potentes de Kodi.
El soporte IPTV.
¿Por qué IPTV?
A primera vista puede parecer extraño.
No estamos viendo canales de televisión.
Estamos viendo una entrada HDMI.
Sin embargo, Kodi no hace ninguna distinción.
Para Kodi un canal IPTV no deja de ser una dirección de vídeo.
Y nuestro servidor RTSP es exactamente eso.
Ventajas
Utilizar IPTV aporta varias ventajas muy interesantes.
No necesitamos desarrollar ningún addon.
No modificamos Kodi.
Seguimos utilizando el reproductor nativo.
Podemos cambiar de canal con el mando.
La integración resulta prácticamente perfecta.
Instalando IPTV Simple Client
Kodi incorpora un complemento oficial denominado:
PVR IPTV Simple Client
Es uno de los complementos oficiales más utilizados de toda la plataforma.
Para instalarlo:
Ajustes
↓
Complementos
↓
Instalar desde repositorio
↓
Clientes PVR
↓
PVR IPTV Simple Client
Lo instalamos normalmente.
Todavía no debemos activarlo.
Primero prepararemos nuestra lista IPTV.
Creando la lista M3U
Kodi obtiene la información de los canales desde un sencillo fichero de texto.
Creamos:
analogico.m3u
Su contenido será:
#EXTM3U
#EXTINF:-1 tvg-id="analogico" tvg-name="Fuente Analógica" group-title="Capturas",Fuente Analógica
rtsp://192.168.1.50:8554/vhs
Naturalmente deberemos sustituir la dirección IP por la correspondiente a nuestro servidor.
Eso es todo.
Ya tenemos nuestro primer canal IPTV.
Cargando la lista
Abrimos la configuración del complemento.
Indicamos:
Ruta local
↓
analogico.m3u
Aceptamos.
Kodi solicitará reiniciar el cliente IPTV.
Tras unos segundos aparecerá un nuevo grupo de canales.
Nuestro primer canal
En el apartado:
Televisión
↓
Canales
Encontraremos:
Fuente Analógica
Al seleccionarlo ocurrirá toda la secuencia automáticamente.
Kodi
↓
MediaMTX
↓
runOnDemand
↓
Docker
↓
FFmpeg
↓
RTSP
↓
Imagen en pantalla
El usuario únicamente percibe un pequeño retraso de dos o tres segundos mientras el servidor inicia la captura.
Una experiencia muy similar a un televisor
A partir de este momento la experiencia cambia completamente.
Ya no estamos reproduciendo una dirección RTSP.
Estamos cambiando de canal.
Podemos asignarlo a favoritos.
Crear accesos directos.
Integrarlo en cualquier skin.
Utilizar el mando a distancia.
Desde el punto de vista del usuario se comporta exactamente igual que cualquier otro canal IPTV.
¿Y la grabación?
Aquí aparece otra ventaja importante.
Kodi dispone desde hace años de un sistema muy completo de grabación de televisión.
Si el flujo se presenta como un canal IPTV…
También puede grabarse.
No necesitamos desarrollar ninguna aplicación adicional.
Utilizando el sistema PVR
Kodi incorpora soporte para:
- grabaciones manuales;
- temporizadores;
- programación;
- biblioteca de grabaciones.
Todo ello puede aprovecharse también con nuestra fuente HDMI.
En nuestro caso instalamos un complemento específico de grabación IPTV que permite guardar el flujo recibido en disco sin necesidad de modificar nuestro servidor RTSP.
La ventaja de este enfoque es que la captura y la grabación quedan completamente desacopladas.
Nuestro servidor únicamente publica vídeo.
Kodi decide cuándo quiere visualizarlo o almacenarlo.
¿Dónde se guardan las grabaciones?
El complemento permite elegir cualquier ubicación.
En nuestro caso utilizamos un recurso compartido del NAS.
De esta forma:
Capturadora
↓
RTSP
↓
Kodi
↓
NAS
Las grabaciones quedan inmediatamente disponibles para cualquier otro dispositivo de la red.
Ventajas de esta solución
Comparada con una grabación directa desde FFmpeg presenta varias ventajas.
No es necesario modificar el servidor.
Podemos cambiar el sistema de grabación cuando queramos.
Las grabaciones quedan integradas dentro de Kodi.
Podemos programarlas.
Y el servidor RTSP continúa siendo completamente independiente.
Conclusiones
La combinación de MediaMTX y el cliente IPTV de Kodi permite integrar una fuente HDMI dentro del centro multimedia como si se tratara de un canal de televisión convencional.
La experiencia de uso resulta extremadamente cómoda.
Basta con seleccionar un canal desde el mando a distancia para que todo el sistema se active automáticamente y comience a mostrar la imagen.
Además, gracias al soporte PVR de Kodi, también es posible almacenar ese mismo flujo en un NAS o en cualquier otra ubicación sin modificar en absoluto el servidor RTSP.
