Código y componentes para un dashboard que controla tu radio
Cómo Crear un Dashboard Web para Controlar tu Radio surgió mientras intentábamos visualizar el estado de Icecast en tiempo real.
Teníamos que revisar la audiencia, los mounts y el bitrate sin entrar en la consola de administración.
El reto de monitorear una radio 24/7
Si el dashboard no está disponible, nos vemos obligados a abrir el panel de Icecast en cada servidor. Eso consume tiempo y genera errores humanos.
Además, sin una vista centralizada, no detectamos picos de tráfico ni caídas de streams.
El problema se vuelve crítico cuando la audiencia reporta cortes y no sabemos quién los causó.
Qué necesitas antes de empezar
- Una VM con Ubuntu 22.04 y acceso root.
- Python 3.11, pip y virtualenv instalados.
- Icecast corriendo en /etc/icecast2/icecast.xml.
- Nginx como proxy inverso.
- Acceso a /home/lamix/ para guardar el código.
Cómo Crear un Dashboard Web para Controlar tu Radio:
arquitectura básica
Primero creamos un entorno virtual dentro de /home/lamix/dashboard.
mkdir -p /home/lamix/dashboard
cd /home/lamix/dashboard
python3 -m venv venv
source venv/bin/activate
pip install flask requests
Luego escribimos la aplicación Flask que consumirá el endpoint JSON de Icecast.
from flask import Flask, jsonify, render_template
import requests
app = Flask(__name__)
ICECAST_STATUS = 'http://127.0.0.1:8000/status-json.xsl'
def get_icecast_stats():
try:
resp = requests.get(ICECAST_STATUS, timeout=3)
resp.raise_for_status()
return resp.json()
except Exception:
return {'error': 'No se pudo obtener el estado'}
@app.route('/api/stats')
def api_stats():
return jsonify(get_icecast_stats())
@app.route('/')
def dashboard():
return render_template('dashboard.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Guardamos este archivo como app.py.
Ahora creamos la plantilla HTML que hará peticiones AJAX cada 5 segundos.
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Estado de la Radio</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Dashboard de La MIX Radio</h1>
<pre id="stats">Cargando...</pre>
<script>
function loadStats() {$.getJSON('/api/stats') .done(data => { $('#stats').text(JSON.stringify(data, null, 2));})
.fail(() => {$('#stats').text('Error al leer Icecast');});
}
setInterval(loadStats, 5000);
$(document).ready(loadStats);
</script>
</body>
</html>
Guardamos la plantilla en /home/lamix/dashboard/templates/dashboard.html.
Con esto la API ya responde en http://localhost:5000/api/stats.
El siguiente paso es exponer Flask detrás de Nginx para usar HTTPS y evitar puertos extraños.
server {listen 80; server_name dashboard.lamixradio.com; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
location /api/ {proxy_pass http://127.0.0.1:5000/api/; proxy_set_header Host $host;}
}
Copiamos ese bloque en /etc/nginx/sites-available/dashboard y habilitamos el sitio.
ln -s /etc/nginx/sites-available/dashboard /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Para que Flask arranque automáticamente, creamos un unit file de systemd.
[Unit]
Description=Dashboard Flask for La MIX Radio
After=network.target
[Service]
User=lamix
WorkingDirectory=/home/lamix/dashboard
Environment="PATH=/home/lamix/dashboard/venv/bin"
ExecStart=/home/lamix/dashboard/venv/bin/python app.py
Restart=always
[Install]
WantedBy=multi-user.target
Guardamos como /etc/systemd/system/dashboard.service, habilitamos y arrancamos.
systemctl daemon-reload
systemctl enable dashboard.service
systemctl start dashboard.service
Con estos pasos, el dashboard está disponible en http://dashboard.lamixradio.com.
Podemos observar en tiempo real la audiencia, los listeners y el bitrate de cada mount.
Errores que nos costaron tiempo
- Síntoma: La página mostraba “Error al leer Icecast”. Causa: Icecast solo escuchaba en
localhosty la petición venía de Nginx conproxy_passa127.0.0.1. Solución: Cambiamos la URL ahttp://127.0.0.1:8000/status-json.xsly habilitamoslisten=127.0.0.1enicecast.xml. - Síntoma: Nginx devolvía “502 Bad Gateway”. Causa: El servicio Flask no estaba corriendo porque la variable
PATHapuntaba a un virtualenv inexistente. Solución: Verificamos la ruta completa/home/lamix/dashboard/venv/biny reparamos el unit file. - Síntoma: Los cambios en
dashboard.confno tenían efecto. Causa: Olvidamos recargar Nginx después de crear el enlace simbólico. Solución: Ejecutamosnginx -t && systemctl reload nginxy comprobamos el log.
Cómo saber que funciona
Abre el dominio del dashboard y verifica que el panel Muestre JSON con campos como source y listeners.
Si la información se actualiza cada 5 segundos, el proceso está OK.
Revisa systemctl status dashboard para confirmar que el servicio está activo.
Qué sigue después de montar el dashboard
Podemos añadir botones que envíen peticiones a la API de Icecast para detener o iniciar mounts.
También es útil integrar alertas por Telegram usando n8n cuando el número de listeners cae bajo un umbral.
En nuestro caso, Cómo Crear un Dashboard Web para Controlar tu Radio nos permitió detectar problemas antes de que impactaran a la audiencia.

