Instalación de Icecast: Servidor de Streaming de Audio

Icecast es el servidor de streaming de audio open-source más utilizado para radio por internet, compatible con MP3, OGG Vorbis, AAC y otros formatos. Con soporte para múltiples puntos de montaje (mount points), configuración de relay entre servidores, autenticación de fuentes y estadísticas de oyentes, Icecast es la base de miles de emisoras de radio en internet. Esta guía cubre la instalación y configuración completa de Icecast en Linux.

Requisitos Previos

  • Ubuntu 20.04+, Debian 11+, CentOS 8+ o Rocky Linux 8+
  • Mínimo 256 MB de RAM (más según el número de oyentes)
  • Ancho de banda: calcular como bitrate × oyentes simultáneos (ej: 128 kbps × 100 = 12.8 Mbps)
  • Puerto 8000 disponible (puerto por defecto de Icecast)

Instalación de Icecast

Ubuntu/Debian

# Instalar Icecast2 desde los repositorios
sudo apt update
sudo apt install -y icecast2

# Durante la instalación se pedirá configuración básica:
# - Hostname del servidor
# - Contraseñas para source, relay y admin
# Puedes configurarlo manualmente después

# Habilitar e iniciar el servicio
sudo systemctl enable --now icecast2

# Verificar el estado
sudo systemctl status icecast2

CentOS/Rocky Linux

# Instalar desde repositorios EPEL
sudo dnf install -y epel-release
sudo dnf install -y icecast

# Habilitar e iniciar
sudo systemctl enable --now icecast

# Verificar
sudo systemctl status icecast

Configuración de Icecast

El archivo de configuración principal está en /etc/icecast2/icecast.xml:

sudo cp /etc/icecast2/icecast.xml /etc/icecast2/icecast.xml.bak
sudo nano /etc/icecast2/icecast.xml

Configuración completa de ejemplo:

<icecast>
    <!-- Límites del servidor -->
    <limits>
        <!-- Máximo de clientes conectados -->
        <clients>250</clients>
        <!-- Máximo de fuentes (streams) -->
        <sources>10</sources>
        <!-- Máximo de conexiones en cola -->
        <queue-size>524288</queue-size>
        <!-- Timeout de cliente en segundos -->
        <client-timeout>30</client-timeout>
        <!-- Timeout de conexión de fuente -->
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <!-- Tiempo de espera burst para nuevos oyentes -->
        <burst-on-connect>1</burst-on-connect>
        <burst-size>65535</burst-size>
    </limits>

    <!-- Contraseñas de autenticación -->
    <authentication>
        <!-- Contraseña para las fuentes (streamers) -->
        <source-password>contrasena-fuente-segura</source-password>
        <!-- Contraseña para servidores relay -->
        <relay-password>contrasena-relay-segura</relay-password>
        <!-- Contraseña del panel de administración -->
        <admin-user>admin</admin-user>
        <admin-password>contrasena-admin-segura</admin-password>
    </authentication>

    <!-- Hostname público del servidor -->
    <hostname>radio.tu-dominio.com</hostname>

    <!-- Configuración de red -->
    <listen-socket>
        <port>8000</port>
        <!-- Descomentar para escuchar solo en localhost (detrás de proxy) -->
        <!-- <bind-address>127.0.0.1</bind-address> -->
    </listen-socket>

    <!-- Punto de montaje por defecto -->
    <mount type="normal">
        <mount-name>/stream</mount-name>
        <!-- Nombre del stream para los metadatos -->
        <stream-name>Mi Radio Online</stream-name>
        <stream-description>La mejor música 24/7</stream-description>
        <stream-url>http://radio.tu-dominio.com</stream-url>
        <genre>Various</genre>
        <!-- Máximo de oyentes para este mount -->
        <max-listeners>100</max-listeners>
        <!-- Activar en los directorios Icecast públicos -->
        <public>0</public>
    </mount>

    <!-- Configuración de archivos del servidor -->
    <fileserve>1</fileserve>

    <!-- Rutas del servidor web integrado -->
    <paths>
        <basedir>/usr/share/icecast2</basedir>
        <logdir>/var/log/icecast2</logdir>
        <webroot>/usr/share/icecast2/web</webroot>
        <adminroot>/usr/share/icecast2/admin</adminroot>
        <pidfile>/run/icecast2/icecast.pid</pidfile>
    </paths>

    <!-- Configuración de logs -->
    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
        <loglevel>3</loglevel> <!-- 1=error, 2=warn, 3=info, 4=debug -->
        <logsize>10000</logsize>
    </logging>

    <!-- Configuración de seguridad -->
    <security>
        <chroot>0</chroot>
    </security>
</icecast>
# Aplicar la configuración
sudo systemctl restart icecast2

# Acceder al panel de administración
# http://TU-SERVIDOR:8000/admin/ (admin / contrasena-admin)

Configuración de Clientes Fuente

Los clientes fuente envían el audio al servidor Icecast. Ejemplo con BUTT (Broadcast Using This Tool):

Configuración de BUTT:

  • Host: TU-SERVIDOR
  • Puerto: 8000
  • Contraseña: contrasena-fuente-segura
  • Mount point: /stream

Con Mixxx (software de DJ):

  • Configuración > Difusión en vivo
  • Tipo: Icecast2
  • Host: TU-SERVIDOR, Puerto: 8000
  • Mount: /stream, Contraseña: contrasena-fuente-segura

Enviar audio desde la línea de comandos con FFmpeg:

# Streaming de un archivo MP3 a Icecast
ffmpeg -re -i /ruta/a/musica.mp3 \
  -c:a libmp3lame -b:a 128k \
  -content_type audio/mpeg \
  -f mp3 \
  icecast://source:contrasena-fuente-segura@localhost:8000/stream

# Streaming de audio del sistema con ALSA
ffmpeg -f alsa -i hw:0 \
  -c:a libmp3lame -b:a 128k \
  -f mp3 \
  icecast://source:contrasena-fuente-segura@localhost:8000/stream

# Streaming OGG Vorbis (mejor calidad a mismo bitrate)
ffmpeg -re -i /ruta/a/musica.flac \
  -c:a libvorbis -b:a 192k \
  -f ogg \
  icecast://source:contrasena-fuente-segura@localhost:8000/stream.ogg

Integración con Liquidsoap

Liquidsoap es un generador de streams automático que puede gestionar listas de reproducción, fallbacks y efectos de audio:

# Instalar Liquidsoap
sudo apt install -y liquidsoap  # Ubuntu/Debian
# sudo dnf install -y liquidsoap  # CentOS/Rocky

# Verificar la instalación
liquidsoap --version

Script de Liquidsoap para radio automática con fallback:

# Crear script de Liquidsoap
sudo tee /opt/radio/radio.liq << 'EOF'
# radio.liq - Configuración de radio automática con Liquidsoap

# Configuración del servidor de salida
set("server.telnet", true)
set("server.telnet.port", 1234)

# Playlist principal (reproducción aleatoria de la carpeta de música)
playlist_principal = playlist(
  mode="randomize",
  reload=3600,
  "/mnt/musica/"
)

# Fuente de emergencia (archivo de silencio o jingle de cierre)
emergencia = single("/opt/radio/emergencia.mp3")

# Silenciar si no hay audio
output_safe = fallback(
  track_sensitive=false,
  [playlist_principal, emergencia]
)

# Activar cruce de fundido entre canciones
output_fundido = crossfade(output_safe)

# Salida a Icecast
output.icecast(
  %mp3(bitrate=128),
  host="localhost",
  port=8000,
  password="contrasena-fuente-segura",
  mount="/stream",
  name="Mi Radio Online",
  description="Música automática 24/7",
  genre="Various",
  output_fundido
)
EOF

# Crear servicio systemd para Liquidsoap
sudo tee /etc/systemd/system/liquidsoap.service << 'EOF'
[Unit]
Description=Liquidsoap Radio Automation
After=icecast2.service

[Service]
Type=simple
User=www-data
ExecStart=/usr/bin/liquidsoap /opt/radio/radio.liq
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now liquidsoap

Configuración de Relay

Icecast soporta relay entre servidores para distribuir la carga:

# Configuración de relay en icecast.xml del servidor secundario
# (agrega dentro de <icecast>)
<!-- Relay desde el servidor principal -->
<relay>
    <!-- Servidor Icecast origen -->
    <server>radio-principal.tu-dominio.com</server>
    <port>8000</port>
    <!-- Mount point en el servidor origen -->
    <mount>/stream</mount>
    <!-- Contraseña de relay del servidor origen -->
    <password>contrasena-relay-segura</password>
    <!-- Mount point local (en este servidor) -->
    <local-mount>/stream</local-mount>
    <!-- Relay en vivo (0=solo a demanda, 1=siempre activo) -->
    <on-demand>0</on-demand>
</relay>

Estadísticas de Oyentes

# Ver estadísticas via API XML
curl http://localhost:8000/admin/stats.xml \
  -u admin:contrasena-admin

# Estadísticas en formato JSON (Icecast 2.4+)
curl http://localhost:8000/status-json.xsl

# Ver el estado de un mount point específico
curl "http://localhost:8000/admin/listmounts.xml" \
  -u admin:contrasena-admin

# Ver oyentes activos de un mount
curl "http://localhost:8000/admin/listclients.xml?mount=/stream" \
  -u admin:contrasena-admin

# Monitoring simple con watch
watch -n 5 'curl -s http://localhost:8000/status-json.xsl | python3 -m json.tool | grep -E "listeners|source"'

Proxy Inverso con Nginx

# Configurar Nginx para proxy con SSL
sudo tee /etc/nginx/sites-available/icecast << 'EOF'
server {
    listen 80;
    server_name radio.tu-dominio.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name radio.tu-dominio.com;

    ssl_certificate /etc/letsencrypt/live/radio.tu-dominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/radio.tu-dominio.com/privkey.pem;

    # Proxy principal al servidor Icecast
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # Streaming de audio - sin buffer
        proxy_buffering off;
        proxy_read_timeout 3600s;
        # Importante para streaming continuo
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/icecast /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Solución de Problemas

Icecast no inicia:

# Ver logs de error
sudo journalctl -u icecast2 -f
cat /var/log/icecast2/error.log

# Verificar el archivo de configuración XML
xmllint --noout /etc/icecast2/icecast.xml

# Verificar permisos
ls -la /etc/icecast2/
ls -la /var/log/icecast2/
sudo chown -R icecast2:icecast /var/log/icecast2/

El cliente fuente no puede conectar:

# Verificar que Icecast está escuchando
sudo ss -tlnp | grep 8000

# Probar la conexión de fuente manualmente con FFmpeg
ffmpeg -re -i /ruta/musica.mp3 \
  -c:a libmp3lame -b:a 128k -f mp3 \
  icecast://source:CONTRASENA@localhost:8000/test \
  2>&1 | head -20

Los oyentes se desconectan frecuentemente:

# Aumentar el tamaño del burst en icecast.xml
# <burst-size>65535</burst-size>  -> aumentar a 131072 o 262144

# Verificar el uso de ancho de banda
vnstat -l  # Monitoreo en tiempo real

Conclusión

Icecast, combinado con Liquidsoap para la automatización, proporciona una infraestructura completa de radio por internet sin coste de licencias. Su capacidad de relay permite distribuir la carga a múltiples servidores, y la API XML facilita la integración con paneles de control personalizados para monitorizar oyentes y gestionar el contenido en tiempo real.