Table des matières

Creer une Web Radio avec Icecast


Créer votre Web Radio sur votre rpi.

Installation

sudo apt-get install icecast2 ezstream

Paramétrage

Icecast

nano /etc/icecast2/icecast.xml 

configurer les sections <limit> </limit> et <authentication> </authentication>

<icecast>
    <!-- location and admin are two arbitrary strings that are e.g. visible
         on the server info page of the icecast web interface
         (server_version.xsl). -->
    <location>To the Moon</location>
    <admin>admin@mazinger.fr</admin>
 
    <!-- IMPORTANT!
         Especially for inexperienced users:
         Start out by ONLY changing all passwords and restarting Icecast.
         For detailed setup instructions please refer to the documentation.
         "It's also available here: http://icecast.org/docs/"
    -->
 
    <limits>
        <clients>100</clients>
        <sources>2</sources>
        <queue-size>524288</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <!-- If enabled, this will provide a burst of data when a client 
             first connects, thereby significantly reducing the startup 
             time for listeners that do substantial buffering. However,
             it also significantly increases latency between the source
             client and listening client.  For low-latency setups, you
             might want to disable this. -->
        <burst-on-connect>1</burst-on-connect>
        <!-- same as burst-on-connect, but this allows for being more
             specific on how much to burst. "Most people won't need to
             change from the default 64k. Applies to all mountpoints"  -->
        <burst-size>65535</burst-size>
    </limits>
 
    <authentication>
        <!-- Sources log in with username 'source' -->
        <source-password>hackme</source-password>
        <!-- Relays log in with username 'relay' -->
        <relay-password>hackme</relay-password>
 
        <!-- Admin logs in with the username given below -->
        <admin-user>admin</admin-user>
        <admin-password>hackme</admin-password>
    </authentication>

ezsetream

cp /usr/share/doc/ezstream/examples/ezstream_mp3.xml
 /usr/share/doc/ezstream/examples/ezstream_Funk.xml
<ezstream>
    <url>http://localhost:8000/stream</url>
    <!--
      If a different user name than "source" should be used, set it in
      <sourceuser/>:
     -->
    <!-- <sourceuser>mr_stream</sourceuser> -->
    <sourcepassword>hackme</sourcepassword>
    <format>MP3</format>
    <filename>/home/pi/Music/Funk.m3u</filename>
    <!-- Once done streaming playlist.m3u, exit: -->
    <stream_once>0</stream_once>
    <shuffle>1</shuffle>
     <!--
      The following settings are used to describe your stream to the server.
      It's up to you to make sure that the bitrate/samplerate/channels
      information matches up with your input stream files. Note that
      <svrinfoquality /> only applies to Ogg Vorbis streams.
     -->
    <svrinfoname>My Funk Stream</svrinfoname>
    <svrinfourl>http://stream.mazinger.fr</svrinfourl>
    <svrinfogenre>Funk Music 80's</svrinfogenre>
    <svrinfodescription>Le Meilleur de la Funk!!</svrinfodescription>
    <svrinfobitrate>128</svrinfobitrate>
    <svrinfochannels>2</svrinfochannels>
    <svrinfosamplerate>44100</svrinfosamplerate>
    <!--
      Prohibit the server to advertise the stream on a public YP directory:
     -->
    <svrinfopublic>0</svrinfopublic>
</ezstream>

LiquidSoap

Installer la source liquidsoap:

apt install liquidsoap

La Configuration est bien plus simple : 8-)
Editer un ficher.liq exemple 80.liq

#Pour executer le stream avec root
set("init.allow_root",true)
 
# FICHIER DE LOG
set("log.file.path","/tmp/ma-radio.log")
 
# Musique (Répertoire où se trouve les musiques)
myplaylist = playlist("/home/pi/Music/ma-zick.m3u", reload_mode="watch")  # Playlist principale
 
# Ajout des jingles (Répertoire où se trouve les jingles)
jingles = playlist("/home/pi/Music/jingles/")
 
# Si il y a un problème alors on lance la musique ci-dessous
security = single("/home/pi/Music/jingles/ERROR_MSG/Probleme-Radio.mp3")
 
# On créer une variable radio
radio = myplaylist
 
# On y ajoute les jingles 3 titres par defaut
radio = random(weights = [1, 2],[jingles, radio])
 
# Et la sécurité si pas de stream (playlist impossible à charger)
radio = fallback(track_sensitive = false, [radio, security])
 
# On crée une écoute d'un live, si il y a du son il sera diffuse sinon la playlist reste en lecture
#live = fallback(track_sensitive=false,
#[input.http("http://localhost:8000/live"),
#radio])
 
# On lance une écoute pour voir si il y a un blanc pendant le live, si c'est le cas la playlist se relance
#stream = fallback(track_sensitive=false,
#[ strip_blank(max_blank=5.,live) , radio ])
 
 
# Envoie du flux vers Icecast
output.icecast(%mp3,
  host="127.0.0.1",
  port=8000,
  password="hackme",
  mount="/stream",
  name="Best Funk Radio",
  description="Le meilleur de la Funk",
  genre="Funk Music 80's",
  url="http://stream.mazinger.fr",
  public=false,
  radio)

Préparer votre Playlist

cd $HOME/Music

Si il n'existe pas créer le

mkdir /home/pi/Music

dans mon exemple je fait une recherche depuis un point de montage correspondant à mon NAS

find /mnt/BigHeroMp3/Funk\ Music/ALL\ FUNK/ -iname "*.mp3" >Funk.m3u

-iname permet d'être insensible à la casse (.mp3 et .MP3) seront valide !!
Extrait du fichier généré:

/mnt/BigHeroMp3/Funk Music/ALL FUNK/Bettye Lavette - I Can't Stop.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/Central Line - Walking Into Sunshine.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/COOL NOTES - LOOK WHAT YOU  DONE TO ME.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/David Joseph - You Can't Hide.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/ D Train-Keep Giving Me Love.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/A.W.B pick up the pieces.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/Fat Eddy Band - Let your body move it.mp3
/mnt/BigHeroMp3/Funk Music/ALL FUNK/Cameo - Talking out.mp3

Donc mon fichier de playlist sera situé dans /home/pi/Music/ et sera nommé Funk.m3u

Tester

EZSTREAM

Voici la commande à saisir pour lancer votre Web Radio:

ezstream -c /usr/share/doc/ezstream/examples/ezstream_Funk.xml

Vous pouvez choisir un autre emplacement lors de la copie du fichier exemple. (ezstream_mp3.xml)
Faire la copie dans un autre répertoire, /home/pi/EZconf
La commande sera donc “ezstream -c /home/pi/EZconf/ezstream_Funk.xml

Si tout se passe bien vous devriez voir ceci dans votre terminal:

ezstream: Connected to http://localhost:8000/stream
ezstream: Streaming ``Lionel Richie - Lionel Richie-Say You Say Me''

Cela indique que ezstream est bien en fonctionnement et est en train de lire le titre ``Lionel Richie - Lionel Richie-Say You Say Me''


LIQUIDSOAP

Tester 60s de stream pour voir si tout est ok !!

timeout 60s liquidsoap /media/USB/80.liq

URL de stream

http://localhost:8000/stream  ou http://ipDuServeur:8000/stream

URL de Gestion

http://localhost:8000  ou http://ipDuServeur:8000


Script

Démarrage

Afin d'automatiser le lancement vous pouvez créer un script qui exécutera ezstream.
Ex: Funk.sh

#!/bin/sh
 
ezstream -c /usr/share/doc/ezstream/examples/ezstream_Funk.xml

Afin de pouvoir le faire executer en tâche de fond:

./Funk.sh &

Auto Script ezstream

#!/bin/sh
#Lancement de la playlist via ezstream
ezstream -c /home/pi/Music/ezstream_Best-Funk.xml &  
#Récuperation du PID du process de ezstream dans une variable (varPID)
varPID=$(ps -aux | grep ezstream | awk {'print $2'} |sed '2d')
#Timer réglé sur 4h de diffusion
sleep 14400
#Arrêt de la diffusion du stream
kill $varPID
 
exit;

Auto Script liquidsoap

#!/bin/bash
#Lancement de la playlist via ezstream
liquidsoap /home/pi/Music/Funk.liq &
#Récuperation du PID du process de liquidsoap dans une variable (varPID)
varPID=$(ps -aux | grep liquidsoap | awk {'print $2'} |sed '2d')
#Timer réglé sur 4h de diffusion
sleep 14400
#Arrêt de la diffusion du stream
kill $varPID
 
exit;

Best Script

Voici une version plus propre pour une mise en prod plus sure avec log !!

#!/bin/bash
 
# === CONFIG ===
LIQ_SCRIPT="/home/pi/Music/Funk.liq"
LOG_FILE="/home/pi/Music/stream.log"
RUNTIME=14400  # Durée en secondes (4h)
 
# === ENVIRONNEMENT ===
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 
# === START LOG ===
echo "=== $(date '+%Y-%m-%d %H:%M:%S') - DÉBUT DU STREAM ===" >> "$LOG_FILE"
 
# === LANCEMENT DU STREAM ===
liquidsoap "$LIQ_SCRIPT" &
PID=$!
echo "Liquidsoap lancé avec le PID $PID" >> "$LOG_FILE"
 
# === VÉRIFICATION ===
sleep 5
if ! ps -p "$PID" > /dev/null; then
    echo "ERREUR : Liquidsoap ne s'est pas lancé correctement." >> "$LOG_FILE"
    exit 1
fi
 
# === TEMPS DE DIFFUSION ===
echo "Streaming pendant $((RUNTIME/3600))h..." >> "$LOG_FILE"
sleep "$RUNTIME"
 
# === ARRÊT DU STREAM ===
if ps -p "$PID" > /dev/null; then
    kill "$PID"
    echo "Liquidsoap (PID $PID) stoppé proprement." >> "$LOG_FILE"
else
    echo "Avertissement : le processus Liquidsoap n'était plus actif à l'arrêt." >> "$LOG_FILE"
fi
 
echo "=== $(date '+%Y-%m-%d %H:%M:%S') - FIN DU STREAM ===" >> "$LOG_FILE"

Dans Crontab FIXME

Crontab -e
 
15 20 * * * /home/pi/Music/Best-Funk.sh >/dev/null 2>&1

Reload du cron, pour prendre les modif en compte.

/etc/init.d/cron reload

Chaque soir à partir de 20h15 le script sera éxecuté par cron, et s’arrêtera 4h plus tard.
Pour changer l'heure d’arrêt modifier le script dans la partie #Timer (sleep xxxx en sec).

Arrêt

ezstream

ps -aux | grep ezstream
root     28529  0.2  0.7  50704  7412 pts/2    S+   20:04   0:24 ezstream -c /usr/share/doc/ezstream/examples/ezstream_Funk.xml
 
kill 28529

liquidsoap

ps -aux | grep liquidsoap
root     28729  0.2  0.7  50704  7412 pts/2    S+   20:24   0:36 liquidsoap /home/pi/Music/Funk.liq
kill 28729

Icecast

systemctl stop icecast2.service 

Lecture

Consommation

Niveau consommation de ressources cette solutions est peu gourmande:

Après reste à voir la charge en fonction du nombre de Client(s)


🧰 Maintenance

Ajout de titres et regénérer la playlist 8-)

Démontage

Si je travaille avec un support USB !!

umount -f /media/USB

Si bloqué par un processus fantôme et même un “kill -9” n'y fait rien !

fuser -k /media/USB/

Montage

Pour m'affranchir des ACL sur le point de montage d'origine pour www-data, je remonte mon volume ailleurs.

mount UUID=52D5-74A4 /mnt/USB

Commande pour avoir le “UUID”

lsblk -f

Ajout de MP3

cp -R /source_MP3/*.* /mnt/USB/Destination/ 

Playlist

Je renomme l'ancienne playlist !!

mv /mnt/USB/myplaylist.m3u /mnt/USB/myplaylist.m3u.old

Je génère la nouvelle playlist.

find /mnt/USB/Destination/ -iname "*.mp3" >/mnt/USB/myplaylist.m3u

Contrôle

Le nombre de fichiers

ll /mnt/USB/Destination/ | wc -l

Le nombre de lignes dans le fichier playlist.

cat /mnt/USB/myplaylist.m3u | wc -l 

Les nombres devraient être identiques
Penser à démonter le point de montage de travail

umount /mnt/USB

Montage

Réappliquer le montage issu du fichier fstab

mount -a

Conf possible fstab :

#USB Disk Stream
UUID=52D5-74A4	/media/USB    vfat    ro,suid,dev,auto,async,uid=33,umask=007    0      2