J’organise une fête pour le nouvel an et je voulais que les personnes invitées puissent ajouter simplement des chansons à la playlist sans pour autant avoir recours à spotify ou tout autre gestionnaire de playlist en ligne. Ayant un peu d’expérience en la matière j’ai décidé de partir sur un principe similaire à ce que j’avais fait par le passé.
La boite à outil sera
- yt-dlp pour télécharger les musiques
- mes scripts de téléchargement pour synchroniser les chansons avec la playlist
- sigtop pour télécharger des messages sur signal
- dash pour le shell
- bc pour les calculs
- exiftool pour les métadonnées
- date pour savoir quelle chanson passera quand
- un lecteur de musique (j’utilise mpv)
- toilet pour faire du “ascii art”
Le décompte pour minuit
Construisons un script pour un décompte de minuit. Pour l’affichage on souhaite
quelque chose d’un peu plus joli que juste ce qui sort si l’on fait un echo
.
Pour cela on peut utiliser toilet
1.
echo "Test" | toilet
mmmmmmm m
# mmm mmm mm#mm
# #" # # " #
# #"""" """m #
# "#mm" "mmm" "mm
On peut choisir des fonts et des styles :
echo "Test" | toilet -f ansi --gay
████████ ███████ ███████ ████████
██ ██ ██ ██
██ █████ ███████ ██
██ ██ ██ ██
██ ███████ ███████ ██
L’option --gay
ajoute des jolies couleurs arc-en-ciel (qu’on ne voit pas ici
forcément).
Evidemment dans notre cas on veut l’heure :
date +"%H:%M:sectionmd: " | toilet -f ansi
██ ██████ ██ ██████ ██████ ██████
███ ██ ██ ███ ██ ██ ██ ██
██ ███████ ██ █████ █████ █████
██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██████ ██ ███████ ██████ ███████
Maintenant il faut avancer dans le temps et donc relancer
cette commande toutes les secondes. Par exemple, pour
le faire sur trois secondes on itère sur la sortie de
seq 3
- c’est à dire ½/3 - avec une boucle for
.
for i in $(seq 3)
do
date +"%H:%M:sectionmd: " | toilet -f ansi --gay
done
Sauf que l’on aura trois fois la même seconde en instantané. Il faut dormir une seconde entre chaque affichage.
for i in $(seq 3)
do
date +"%H:%M:sectionmd: " | toilet -f ansi --gay
sleep 1
done
Cette fois-ci les secondes s’affichent les une après les autres or on voudrait
qu’elles s’affichent dans le même espace, la nouvelle seconde écrasant
l’ancienne. Il faut donc remettre le curseur d’écriture en haut de la fenêtre
avec tput cup 0 0
.
#! /bin/sh
datetime=”$@” unixtime=$(date +%s –date “$datetime”) nbsecondsuntilend=$(( $unixtime - $(date +%s) - 10 ))
trap “clear;tput cnorm;exit 0” INT EXIT clear tput civis for i in $(seq $nbsecondsuntilend) do tput cup 0 0 date +”%H:%M:sectionmd: “ | toilet -f ansi –gay sleep 1 done clear for i in $(seq 10 -1 0) do tput cup 0 0 echo “$i “ | toilet -f ansi –gay sleep 1 done sleep 100000
Construire une playlist
Recueillir les données
Évidemment elle sera un fichier texte, lisant des titres sous la forme “artiste - titre”, un titre par ligne. L’idéal serait que chaque personne prenant part à la soirée utilise git mais puisque ce n’est absolument pas le cas des personnes invitées j’ai eu pour idée de recueillir les contributions via une application de messagerie. Celle que j’utilise, signal, stocke ses messages dans une base de données sqlite chiffrée. Si vous avez une application signal desktop installée sur votre machine vous pouvez alors lire la base de donnée. Personnellement je n’ai pas voulu perdre de temps à apprendre comment faire, j’ai donc utilisé le projet sigtop qui le fait automatiquement.2 Avec sigtop il suffit de faire
sigtop msg data
Pour avoir vos conversations sous format texte dans le dossier data
. Admettons que notre
fichier soit nouvel-an.txt
, il me reste à faire un grep
sur les messages
que les invité·e·s ont envoyé. En l’occurrence j’avais demandé que les messages
commencent par playlist -
, j’ai donc fait grep -I "^playlist - "
nouvel-an.txt | sed 's/^playlist - //' > playlist.m3u
pour avoir la liste des titres à télécharger.
Dans la pratique cela m’a demandé un peu plus de travail puisqu’évidemment j’ai
mal communiqué le format et son importance mais ce n’est pas bien grave.
Télécharger les titres et les jouer
Rien de plus facile une fois la liste des titres extraite j’utilise mon script
syncmusicfolder
pour télécharger tous les morceaux. Et hop, c’est fini !
mkdir chansons
cp playlist.m3u chansons
cd chansons
syncmusicfolder < playlist.m3u
Pour jouer la playlist on lance mpv playlist.m3u
.
Savoir quand vont passer les chansons
Le gros du travail est fait ! Maintenant disons que l’on souhaite savoir quand est-ce que les chansons passerons. En effet, on imagine que l’on ne veuille pas la même ambiance à 19h ou à 4h, sans parler de minuit. Comment pouvons nous contrôler cela ?
Extraire les données
Chaque morceau a dans ses métadonnées sa durée. On peut consulter les
métadonnées avec exiftool
. La commande exiftool -Duration -t chanson.mp3
renverra quelque chose sous la forme Duration[tabulation]0:03:24
pour une
chanson d’une durée de 3 minutes et 24 secondes. Si on lui donne plusieurs
morceaux en argument on obtient une liste avec toutes les durées
cat playlist.m3u | xargs -d'\n' exiftool -t -Duration
======== brique argent - collé serré
Duration 0:03:15
======== ABBA - Gimme Gimme Gimme
Duration 0:03:30
======== Louise Attaque - J't'emmène au vent
Duration 0:03:04
Les ajouter à notre fichier
On peut choisir de les ajouter à notre fichier de playlist de façon à
contenir toutes les informations au même endroit. Il faudra évidemment changer
la façon de lancer la playlist (en faisant cut -f1 playlist.m3u | xargs mpv
par exemple).
Reprenons là où nous en étions et filtrons sur les durées uniquement à l’aide d’une regex :
cat playlist.m3u |
xargs -d'\n' exiftool -t -Duration |
grep -oE "[0-9]:[0-9]{2}:[0-9]{2}"
0:03:15
0:03:30
0:03:04
On peut ensuite l’ajouter au fichier de playlist avec paste :
cat playlist.m3u |
xargs -d'\n' exiftool -t -Duration |
grep -oE "[0-9]:[0-9]{2}:[0-9]{2}" |
paste playlist.m3u -
brique argent - collé serré 0:03:15
ABBA - Gimme Gimme Gimme 0:03:30
Louise Attaque - J't'emmène au vent 0:03:04
Manipuler le temps
Manipuler des durées c’est assez relou. J’ai fait un petit script un peu dégueu qui converti le format hh:mm:ss en secondes et inversement. Si l’on avait mis le résultat de la dernière commande dans `playlistwithduration, on l’utiliserait ainsi :
cut -f2 playlistwithduration | ./t2s2t
195
210
184
Avoir le temps sous cette forme permet très simplement de savoir combien de
temps dur la playlist. On fait la somme des secondes en pipant ça dans paste
-s -d+ | bc
et on reconverti en format hh:mm:ss
en le repipant dans ./t2s2t
-r
. En l’occurence sur nos trois chansons ça fait 589 secondes soit 9 minutes
et 49 secondes.
Et maintenant la prédiction
Il se trouve que date
permet des syntaxes où l’on ajoute une certaine
quantité de secondes, minutes, heures à une date donnée. C’est en parti sur ce
principe que repose kun. Par exemple la commande date --date
'2023-12-31T19:00:00+01:00+184seconds'
renvoie 2023-12-31T19:03:04+01:00
3.
On imagine alors pouvoir ajouter la durée des chansons à un horaire donnée
et savoir à partir de là quand chacune des chansons commencera.
Pour cela il va falloir faire la somme successive du temps passé depuis la première chansons jusqu’à celle en cours. Pour cela j’ai un petit script qui, si on lui donne une liste d’entier, fait exactement cela :
cut -f2 playlistwithduration | ./t2s2t | ./cumulduration
195
405
589
Si l’on a une colonne comme celle-ci on peut alors construire des formats de
date mangeables par date
qui correspondent tous au moment où se lancera
chacune des musiques à partir d’une date donnée. En le mettant dans un script
predict
:
cut -f2 playlistwithduration |
./t2s2t |
./cumulduration |
./predict "dec 31 19:00" |
paste playlist.m3u -
brique argent - collé serré 19:00:00
ABBA - Gimme Gimme Gimme 19:03:15
Louise Attaque - J't'emmène au vent 19:06:45
Hop là on peut savoir quand est-ce que passeront chacune des chansons.
Et si l’on souhaite changer l’ordre ?
Peut-être qu’avec ce nouveau pouvoir vous souhaitez pour éditer l’ordre de la playlist et voir comment cela affecte les horaires. C’est ici que l’on peut utiliser le pouvoir de vim pour créer des interfaces. Sachant que :
- il est possible d’activer l’écriture automatique d’un fichier lorsqu’on lance une commande
- il est possible d’activer la lecture automatique d’un fichier quand il change sur le disque
- il est possible de lancer des commandes shell à l’intérieur de vim
- il est possible de créer des raccourcis clavier personnalisés
on peut écrire un script qui modifie playlist.m3u
pour lui ajouter les
horaires, l’appeler à l’intérieur de vim et voir automatiquement les effets.
On configure vim ainsi :
:set ar aw
:nmap <C-s> :silent exec "!< playlist.m3u ../makepredictions 'dec 31 19:00'" \| redraw!<CR>
La première commande active l’écriture et la lecture automatique. La seconde map ctrl+s à l’éxecution
de la commande < playlist.m3u ../makepredictions 'dec 31 19:00'
(mais vous
pouvez y mettre ce que vous voulez) puis redessine l’écran. Ainsi on peut
manipuler la playlist comme bon nous semble à l’aide de nos connaissances de vim, appuyer
sur ctrl-s et hop avoir presque tout de suite les nouvelles horaires !
Pour aller plus loin
J’explique ici comment t2s2t
, cumulduration
et predict
fonctionnent.
-
sudo apt install toilet
sur debian ↩ -
Attention ! Si vous avez des messages sensibles sur signal il vaut peut-être mieux faire une revue du code de sigtop et/ou apprendre à extraire les messages vous même. D’autant plus que sigtop extrait toutes les conversations, il n’est pas possible de lui demander de n’en extraire qu’une seule. ↩
-
La date est au format ISO. Le +01:00 est le fuseau horaire. ↩