
Radio Menthe à l'eau

J’apprécie beaucoup les webradios et à chaque fois que j’en écoute je me dis que potentiellement une autre personne quelque part vibe sur la même musique que moi. Il va sans dire que j’ai toujours été curieux de faire ma propre webradio. Mais pour ça il faut du contenu musical à diffuser… C’est là qu’arrive « Menthe à l’eau ».
Un peu plus de contexte
Menthe à l’eau c’est une playlist youtube soigneusement séléctionnée par une amie, à l’heure ou j’écris ces lignes il y a 3 379 vidéos et lorsque j’ai découvert l’existence de cette playlist il y a 6 ans elle en comportait ~ 550. À mes yeux c’est une bizarrerie de par le spectre de genres qu’elle couvre mais surtout à cause du volume disponible. Youtube étant ce qu’il est, on ne peut chercher ni trier les vidéos, ce qui fait que pour l’écouter obligé·e de la mettre en aléatoire et se laisser porter… La sensation est donc déjà presque celle d’une webradio, sauf que l’expérience est plus individuelle puisque on est seul·e avec son ordre « aléatoire ».
L’idée de diffuser cette playlist en continu 24h/24h a donc plusieurs fois été évoquée, et ce jusqu’à ce que je termine mes études et je me retrouve en flottement chez mes parents. Tout ce temps disponible me permet de m’attaquer un peu à la pile de projets jamais terminés que j’accumule depuis quelques années.
Création du logiciel de webradio
Pour cette webradio mon « cahier des charges » était assez simple :
- Pouvoir diffuser la playlist Menthe à l’eau
- Tous·tes les utilisateur·rices doivent en être à peu près au même moment du stream
- Les informations basiques (titre, miniature, lien) doivent s’afficher pour la musique en cours
- Garder une consommation de ressources relativement faible sur mon serveur
Je me suis dit que diffuser directement de Youtube ça serait un véritable casse tête, et puisque j’ai du stockage en masse que je n’utilise pas je pouvais tout à fait télécharger l’entièreté de la playlist et juste diffuser un dossier de mp3.
Il a donc fallu se battre avec l’outil yt-dlp pour télécharger uniquement le son de toutes les vidéos de la playlist et si possible ne pas avoir à retélécharger l’entièreté de la playlist à chaque fois que je veux la mettre à jour.
yt-dlp --download-archive archive.txt --sleep-requests 1.5 --min-sleep-interval 60 --max-sleep-interval 90 -x -f bestaudio --audio-format mp3 --audio-quality 160K --embed-metadata --parse-metadata "playlist_index:%(track_number)s" --embed-thumbnail -o "%(title)s.%(ext)s" https://www.youtube.com/playlist?list=PLiMXFqXq5gIo7hLOtbgOiQPAVTk2kSjCE
La partie --sleep-requests 1.5 --min-sleep-interval 60 --max-sleep-interval 90
me permet de mettre un peu d’aléatoire et de ne pas me faire bloquer par Youtube.
Maintenant que j’avais mon contenu à diffuser il fallait faire le logiciel qui diffuse. Après quelques recherches je me suis arrêté sur une infrastructure en Go et une interface faite avec Vite + Svelte. Je vous passe les détails mais le fonctionnement est le suivant, le logiciel vient récupérer morceaux par morceaux les mp3 dans un buffer et si des personnes sont connectées les morceaux sont envoyés. Vous pouvez trouver la source sur mon git ici : mentalaradio
La partie reloue a été de faire en sorte que l’interface web récupère le son et le joue plus ou moins synchro avec tout le monde, sauf que la je me suis heurté aux différents fonctionnements des navigateurs pour la gestion des flux audio… Finalement j’ai fait de la bricole et ça a l’air de fonctionner.
Pour la partie metadonnées (titre, miniature, lien) je les envoi à chaque changement de musique via des Server-Sent Events. Heureusement que yt-dlp
me permet de mettre directement dans le mp3 généré l’URL de la vidéo et la miniature.
La bonne surprise a été de voir la consommation de ressources du logiciel :
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ec562f5ce619 mentalaradio 0.18% 88.18MiB / 15.28GiB 0.56% 2.08MB / 84.8MB 83.4MB / 0B 10
Je ne l’ai pas testé en charge mais de toute façon je ne cherche pas à avoir des centaines d’auditeur·rices, si mes ami·es et moi on peut l’écouter c’est bien suffisant. Donc ~88Mo de RAM, 0.18% de CPU et une image docker qui fait 8.2Mo ! La consommation est frugale ! Je pense que je pourrais fortement optimiser la partie serveur en Go mais pour une première fois c’est déjà pas mal.
Retours après… Une journée d’utilisation
Bon on a pas vraiment eu le temps de poncer de fond en comble la radio mais déjà c’est fonctionnel ! Il manque peut être juste une fonctionnalité…
Donc la prochaine étape sera de mettre un petit compteur de personne en ligne actuellement, stay tuned 📻 !