Liquidsoap: Un paso más para Icecast

Pues aquí sigo trasteando con la emisión de audio vía web; recordar que recientemente os explique como montar un servidor con Icecast 2. La cuestión es que quiero ir un paso más allá, y conseguir poder hacer una parrilla de programación, para que así cada usuario sepa, en la medida de lo posible, los horarios de los programas.

Investigando un poco me he encontrado con Liquidsoap, una herramienta de software libre, que nos permite generar contenido complejo, tanto de audio como de vídeo. Se trata de un lenguaje de script simple, flexible y fácilmente extensible.

Según indica en la web del proyecto, su intención es que sea fácil de usar. Aunque, claro, cuanto más lo vayamos usando y más le pidamos, más complejo sera.

Logo oficial del proyecto Liquidsoap

Principales funcionalidades de Liquidsoap

Veamos un resumen de sus principales funcionalidades:

  • Permite reproducir ficheros, listas de reproducción o directorios.
  • Además permite programación de muchas fuentes, dependiendo del tiempo, prioridades, cuotas. (Esto es justo lo que buscaba)
  • Incorpora procesamiento de sonido: compresión, normalización, eco, toque de sonido, etcétera.
  • Síntesis de voz y de sonido.
  • Editar e insertar metadatos. Trasiciones arbritrarias: fundido cruzado, inserción de cuñas (jingles), personalizado, etcétera. El comportamiento de transición puede depender de los metadatos o del volumen promedio.
  • Entradas desde otras transmisiones: muy útil para acceder a emisiones en directo (shows en vivo)
  • Controladores de eventos.
  • Múltiples salidas en la misma instancia: puede tener varias configuraciones de calidad, usar varios medios o incluso transmitir varios contenidos desde la misma instancia.
  • Salida a Icecast, Peercast, Shoutcast (MP3 u Ogg) o un archivo local (WAV, MP3, Ogg, AAC)
  • Entrada y salida a través de Jack, ALSA, OSS y PortAudio

Tiene más funcionalidades, que os recomiendo descubrir consultando su documentación oficial.

¿Cómo funciona la emisión?

Liquidsoap es un generador de flujo de audio general, pero está destinado principalmente a radios de Internet. Veamos las partes que están involucradas en su funcionamiento:

  • El generador de flujo (Liquidsoap, ices, o por ejemplo, un software de DJ que se ejecuta en el PC local, por ejemplo Mixxx) que crea un flujo de audio (Ogg Vorbis o MP3)
  • El servidor de transmisión de medios (Icecast, Shoutcast, …) que transmite varias transmisiones desde sus fuentes a sus oyentes
  • El reproductor de medios (iTunes, Winamp, …) que obtiene el flujo de audio del servidor de medios de transmisión y lo reproduce en los altavoces del oyente

Una imagen vale más que mil palabras:

Esquema funcionamiento de una emisión con Liquidsoap. Imagen extraido de la doc oficial.


El flujo siempre se pasa del generador de flujo al servidor, haya o no oyentes. Luego es enviado por el servidor a cada oyente. Cuantos más oyentes tenga, más ancho de banda necesitará. Esto es lógico.

Si usamos Icecast (es nuestro caso) puede transmitir más de una fuente de audio usando el mismo servidor

Instalación de Liquidsoap en GNU/Linux

La herramienta se encuentra disponible en la mayoría de repositorios.

Por ejemplo, en Ubuntu 18.04, solo hemos de escribir:

  1. sudo apt update
  2. sudo apt install liquidsoap

Esto hará que se instale el paquete más una serie de complementos y librerías necesarias.

Para sistemas basados en RHEL o Centos, podemos utilizar este repositorio de Github.

Trabajando con Liquidsoap

Una vez ya lo tenemos disponible, nos hemos de asegurar de tener la libreria utils.liq, disponible, generalmente en la ubicación: /usr/lib/liquidsoap/1.1.1/utils.liq, esta es imprescindible para el funcionamiento de Liquidsoap.

Uso de fuentes

La herramienta utiliza para funcionar una serie de fuentes definidas por el usuario. Proporciona muchas funciones para crear fuentes desde cero (por ejemplo, una lista de reproducción) y también para crear fuentes complejas al agrupar fuentes más simples. Algunas de estas funciones crean una fuente activa, que extraerá continuamente la transmisión de sus hijos y la transmitirá a los altavoces, a un archivo, a un servidor de transmisión, etc. Estas fuentes activas son las raíces de una instancia de Liquidsoap.

Imagen extraida de la documentación oficial.

¡Por si las moscas!

Las cosas pueden ir mal durante la emisión. Utilizando el termino definido en ladocumentación oficial, puede que tengamos una fuente falible. Esto es, si consideramos una fuente infalible, significa que siempre está disponible. En cambio, con una fuente falible algo puede salir mal. Por defecto necesitamos una fuente infalible, de lo contrario se quejara.

Por ejemplo, una lista de reproducción normal es falible. En primer lugar, porque podría contener solo archivos no válidos, o al menos pasar demasiado tiempo en archivos no válidos para preparar uno válido a tiempo. Además, una lista de reproducción puede contener archivos remotos, que pueden no estar accesibles rápidamente en todo momento. Una cola de solicitudes de usuario es otro ejemplo de fuente falible.

Cuando una salida se queja de su fuente, debemos convertirla en una infalible. Dependiendo de la situación, hay muchas soluciones disponibles. La cuestión al final es evitar esos silencios incómodos. Por lo que podemos recurrir a una fuente infalible de seguridad, esto es, a un fichero de audios, considerado infalible.

Nuestro primer guión de prueba

La mejora manera de aprender es hacer, así que veamos un ejemplo de un guión:

  1. #!/usr/bin/liquidsoap
  2. # Fichero de registro
  3. set("log.file.path","/var/log/liquidsoap/basic-radio.log")
  4.  
  5. # Musica
  6. myplaylist = playlist("/home/davidochobits/liquidsoap-playlist.m3u")
  7. # Algunas cuñas (jingles(
  8. jingles = playlist("/home/davidochobits/jingles.m3u")
  9. # Si algo sale mal:
  10. security = single("/home/davidochobits/A-Forest-Human_Error.ogg")
  11.  
  12. # Indicamos el nombre la "playlist", el intervalo de las cuñas o el mensaje de fallo
  13. radio = myplaylist
  14. # Añadimos algunas cuñas
  15. radio = random(weights = [1, 4],[jingles, radio])
  16. # Volvemos con la seguridad
  17. radio = fallback(track_sensitive = false, [radio, security])
  18.  
  19.  # Los datos del stream
  20. output.icecast(%vorbis,
  21.   host = "localhost", port = 8000,
  22.   password = "hackme", mount = "bitsandlinux-radio.ogg",
  23.   name="BitsaAndLinux Station", description="Estación en pruebas de Davidochobits",
  24.   radio)

(Si queremos también podemos consultar el fichero de ejemplo ubicado en: /etc/liquidsoap/radio.liq.example)

¿Qué hemos hecho en el guión?

Vayamos por partes. Primero de todo declaramos el lenguaje del script. A continuación la ubicación del fichero de registro.

  1. #!/usr/bin/liquidsoap
  2. # Fichero de registro
  3. set("log.file.path","/var/log/liquidsoap/basic-radio.log")

A partir de aquí declaramos varias cosas; la primera de todo es la variable «myplaylist» (pueda llamarse como tu quieras), que es donde tenemos ubicada la lista de los ficheros a reproducir. En lo que respecta a «jingles», aquí declaramos todas las cuñas (anuncios) que queramos utilizar.

Respecto a las «playlist» o «jingles», pueden apuntar a un fichero con un listado de ficheros de sonidos a reproducir, o bien que apunte a la carpeta donde están los ficheros de audio en cuestión.

Por último, que no menos importante, en esta parte indicamos un fichero de audio. Esto está pensando para radiar mensajes tipo: «Estamos teniendo problemas con la emisión» junto con alguna sintonía pegadiza.

  1. # Musica
  2. myplaylist = playlist("/home/davidochobits/liquidsoap-playlist.m3u")
  3. # Algunas cuñas (jingles(
  4. jingles = playlist("/home/davidochobits/jingles.m3u")
  5. # Si algo sale mal:
  6. security = single("/home/davidochobits/A-Forest-Human_Error.ogg")

Yo tengo los audios de música, en la carpeta /home/davidochobits/temas, el contenido en mi caso del fichero: /home/davidochobits/liquidsoap-playlist.m3u, es:

En el caso de el fichero de cuñas, me he bajado algunas versiones de la canción que RMS ha popularizado tantas veces sobre el software libre:

El uso de las cuñas es bastante sencillo. En el código le indicamos que tras un fichero de cuña habrán cuatro canciones seguidas, para que después venga otra cuña.

  1. # Indicamos el nombre la "playlist", el intervalo de las cuñas o el mensaje de fallo
  2. radio = myplaylist
  3. # Añadimos algunas cuñas
  4. radio = random(weights = [1, 4],[jingles, radio])
  5. # Volvemos con la seguridad
  6. radio = fallback(track_sensitive = false, [radio, security])

Al final indicamos el nombre del host, el puerto, y la contraseña que tengamos definida en el servidor. Además el punto de montaje. Aquí cada uno lo que le convenga.

Creo que también es interesante comentar, respecto a esta parte, que podemos definir varias puntos de montaje en el mismo script, por ejemplo, una que emita en formato OGG y otro en formato MP3.

  1.  # Los datos del stream
  2. output.icecast(%vorbis,
  3.   host = "localhost", port = 8000,
  4.   password = "hackme", mount = "bitsandlinux-radio.ogg",
  5.   name="BitsaAndLinux Station", description="Estación en pruebas de Davidochobits",
  6.   radio)

En este apartado también podemos realizar la transmisión desde una emisión ubicada en otro servidor o desde una tarjeta de sonido.

Para ejecutar el guión debemos escribir:

  1. /home/davidochobits/scripts/guion-sencillo-liquidsoap.liq &

Podemos ver el punto de montaje, junto todos los datos de la emisión:

Muestra de datos de la emisión


Y esto es todo. La verdad es que cada vez me está gustando más el tema de la emisión de contenidos en directo con software libre. Un tema realmente interesante.

Fuentes consultadas

Página oficial de Liquidsoap
Linux Journal – Creating an Internet Radio Station with Icecast and Liquidsoap