- Le problème
- Mon usage de spotify
- shell + ytcli + yt-dlp + mpv + git
- Migration depuis spotify
- L’existant
Le code qui résulte de toute cette exploration est accesible dans le dépôt
downloadmusic
en ce qui concerne la synchronisation playlist <-> fichiers
audio
git clone git://katzele.netlib.re/downloadmusic
et dans
git clone git://katzele.netlib.re/zenu-arthur
en ce qui concerne les commandes que j’utilise fréquemment pour lire,
filtrer, synchroniser le tout. Elles sont dans les fichiers de menu zenu
(article sur le sujet à venir) playlist
et filtrer
.
Il vous est possible de directement utiliser ce code là1, mais je vous recommande de lire l’article pour savoir d’où il vient et construire votre système selon vos besoins. J’ai peut-être fait des choses plus compliquées et nécessitant plus de dépendances que ce dont vous avez réellement besoin.
Le problème
Depuis que je m’organise pour pouvoir faire la (quasi) totalité de mes activités numériques sur un raspberry ou équivalent je sais qu’inévitablement il va falloir que je m’occupe de spotify. Il y a deux façons traditionnelles de consommer de la musique sur ce service :
- accéder au contenu via spotify.com
- accéder au contenu via l’application desktop
Il est préférable de ne pas passer par un navigateur web pour écouter de la musique. En effet, de très nombreuses applications savent déjà le faire et de façon bien plus efficace. À l’inverse les navigateurs webs ne sont originellement pas conçus pour. De manière générale il serait opportun, pour réduire les coûts (de quelques natures qu’ils soient), de ne pas utiliser le web pour autre chose que de s’échanger des documents html. Je ne redéveloppe pas tout l’argumentaire expliquant pourquoi et comment, cela a déjà été fait maintes fois. Si vous peinez à trouver des ressources dessus contactez moi !
L’application desktop rencontre le même souci puisqu’elle est basée sur la technologie electron qui fait usage de la stack technique des navigateurs web. Cet état de fait condamne une personne utilisant un ordinateur peu puissant à ne pas pouvoir utiliser spotify. J’imagine que c’est au moins en partie pour cette raison qu’un ensemble de clients tiers est apparu. Pour en lister deux :
- spotify-tui, une interface textuelle dans la console, écrite en rust
- Psst, une interface graphique, écrite en rust
Ces deux logiciels sont bien des interfaces, elles ne remplacent pas le backend de spotify. Pour pouvoir les utiliser et écouter de la musique avec il vous faudra utiliser spotifyd qui s’occupera d’aller streamer la musique depuis spotify. Les interfaces contrôleront spotifyd pour lui dire de passer la chanson, monter le volume etc. Pour avoir testé ces deux solutions il y a un an environ elles fonctionnent et sont effectivement beaucoup plus légères mais rencontrent d’assez nombreux problèmes/bug. Je ne vais pas prendre le temps de les lister, j’ai simplement le souvenir qu’à force de frustration j’ai décidé de réutiliser l’appli desktop sur mes terminaux relativement puissants.
J’étais donc rendu au point de départ. Il se trouve qu’il y a d’autres raisons de vouloir se débarrasser de spotify, notamment le DRM ou Gestion des Droits Numériques. Le DRM, c’est pas bien. Les alternatives sont :
- Écouter la musique sur youtube ou une autre plateforme “ouverte” (quoi qu’avec un bloqueur de pub c’est kifkif ?)
- Acheter la musique
- Le piratage
Le piratage c’est pas bien, vous ne voleriez pas une voiture n’est-ce pas ? Cependant, si l’on veut rester sur quelque chose d’aussi simple que Spotify j’ai le sentiment que le piratage, notamment télécharger de la musique que l’on trouve sur youtube, est la meilleure solution. Je dois préciser que cette réflexion de ma part est certainement regrettable. Je pense que je me suis fait à la relative simplicité de l’usage de spotify ce qui m’incite à ne pas chercher à acheter la musique. Ces achats devraient se faire dans des lieux différents, auraient des formats différents etc. J’ai consenti à faire des efforts supplémentaire dans d’autres domaines de ma vie quand je sais que cela réduit considérablement les coûts sociaux et environnementaux mais je me voyais mal le faire dans celui-ci. Du moins pas tout de suite.
Mon usage de spotify
D’abord je décris l’usage que j’en fais. Si votre usage est très différent peut-être que ce que j’ai pensé ne vous conviendra pas du tout. J’utilise spotify de trois façons différentes.
- Playlist “Liked Songs” (en anglais)
Je découvre de la musique à travers des ami·e·s, en écoutant la radio, en allant en soirée, festival, concert ou beaucoup plus rarement en utilisant les recommandations spotify. Je fais une recherche sur spotify, j’écoute et je “like” ce que j’apprécie. J’écoute la playlist “Liked Songs” produite dans l’ordre antéchronologique ou en aléatoire.
- Ecoute plus spécifique
J’ai une envie très particulière d’écouter un ou une artiste, je fais une recherche spécifique et j’écoute, généralement des albums en entier.
- Ecoute en soirée
J’ouvre l’interface spotify sur mon pc et je laisse les personnes mettre la musique qu’elles souhaitent.
J’ai un usage assez restreint des playlists en dehors de celle générée par les titres que je like. Au vu de ces usages je me suis construit un petit système pour répliquer une partie de mon usage de spotify.
shell + ytcli + yt-dlp + mpv + git
Pour économiser de la bande passante et pouvoir écouter de la musique sans avoir besoin d’internet, comme lorsque l’on télécharge la musique en local sur spotify, il faut pouvoir télécharger les morceaux. Je choisis de le faire depuis youtube du fait de la taille du catalogue disponible sur cette plateforme. Si vous avez déjà lu l’article sur ma façon de lire des vidéos youtube vous savez que l’on peut télécharger des vidéos youtube avec yt-dlp. Puisque yt-dlp permet d’accéder à tous les formats disponibles, il est possible de télécharger uniquement l’audio d’une vidéo.
Pour faire simple on peut utiliser les formats “dynamiques” de yt-dlp. Le
format worstaudio
sélectionnera toujours le format audio de moins bonne
qualité2. Le format bestaudio
fera l’inverse. Puisque que l’on
souhaite écouter de la musique et que par ailleurs youtube n’héberge pas des
formats audio de très grande taille, le format bestaudio
me semble adapté à
notre besoin. Ainsi, si l’on souhaite télécharger la musique
https://www.youtube.com/embed/WBsIKQEGQ_A
on peut lancer la commande
yt-dlp -f bestaudio https://www.youtube.com/embed/WBsIKQEGQ_A
et obtenir un fichier de 3,96Mo nommé “Mop Mop - Jamajumba [WBsIKQEGQ_A].webm”.
Si votre morale ou vos contraintes techniques vous imposent de télécharger des
formats plus petits regardez le manuel de yt-dlp pour choisir un format
différent. Pour changer le nom du fichier on peut utiliser l’option -o
qui
prendra en argument une chaine de caractère. Si l’on récupère quelques liens de
la sorte et que l’on télécharge quelques musiques, construire une playlist
revient à créer un fichier avec la liste des chemins vers les fichiers audios.
Par exemple, vous pouvez avoir l’arborescence suivante :
/home/vous/playlist
├── Inüit - Hush
├── Iron Maiden - Phantom Of The Opera - 1998 Remastered Version
├── King Gizzard & The Lizard Wizard - Inner Cell
├── Marc Rebillet - VACCINATED ATTITUDE
├── playlist.m3u
├── Souad Massi - Mirage (feat. Piers Faccini)
├── The Notorious B - Big Poppa - 2007 Remaster
├── Weval - Half Age
├── Yom - Longing for the Beat
└── Yuksek, Her - Sweet Addiction - Live Edit
Avec le contenu de playlist.m3u
étant :
Inüit - Hush
Iron Maiden - Phantom Of The Opera - 1998 Remastered Version
King Gizzard & The Lizard Wizard - Inner Cell
Marc Rebillet - VACCINATED ATTITUDE
Souad Massi - Mirage (feat. Piers Faccini)
The Notorious B - Big Poppa - 2007 Remaster
Weval - Half Age
Yom - Longing for the Beat
Yuksek, Her - Sweet Addiction - Live Edit
Et il suffira de faire
mpv playlist.m3u
ou
vlc playlist.m3u
pour lire toute la playlist dans l’ordre du fichier. Pour la suite je prendrai mpv pour exemple parce que c’est ce que j’utilise. On peut lancer la playlist avec :
mpv –no-audio-display –volume=50 chemin/vers/la/playlist.m3u
--no-audio-display
permet de garantir qu’mpv n’ouvrira pas d’interface
graphique, --volume=50
de ne pas péter mes oreilles par défaut.
Si l’on veut jouer la playlist de façon aléatoire, deux solutions. Soit on
utilise l’option --shuffle
d’mpv soit on mélange le contenu du fichier avec
shuf
:
shuf playlist.m3u | xargs -d'\n' mpv
J’aurais tendance à favoriser l’utilisation de shuf
. C’est un outil
agnostique que l’on pourra réutiliser à chaque fois qu’il faut mélanger un
fichier. A l’inverse --shuffle
ne fait sens que dans le cadre d’mpv.
Philo Unix, acquisition de savoirs génériques, etc.
J’utilise beaucoup
xargs
, c’est une commande vraiment puissante. Un jour je ferai un court article pour expliquer comment elle fonctionne (ou du moins l’usage que j’en fais). En attendant sachez qu’ici cela exprime l’idée “prend chaque élément rendu parshuf playslist.m3u
séparé par une retour à la ligne (chaque ligne donc) et fais-en un argument à la commande mpv. Cela revient donc à lancer la commandempv titre1 titre2 titre3 titre4
.
Tout cela est bien sympa mais comment fait-on si l’on a des playlists de plusieurs centaines chansons, on va quand même pas chercher les liens sur youtube à la main et lancer les commandes yt-dlp une par une ?
Non effectivement, on peut l’automatiser. Ce ne sera pas sans erreurs mais le
gain de temps sera tout de même considérable. Pour automatiser les recherches
youtube nous allons utiliser un outil disponible dans le dépôt frontends de
codemadness. On y retrouve, dans le dossier youtube, le nécessaire pour
compiler un binaire nommé cli
qui permet de faire des recherches youtube et
de récupérer les résultats dans la console sous format texte. Dans le reste de
cet article je nommerai cli
ytcli
pour plus de clarté.
il est possible que vous ayez des difficultés à compiler ytcli et il est préférable de légèrement le modifier pour notre besoin. Je ferai un petit tuto à l’avenir pour les personnes que ça intéresse TODO
ytcli
s’utilise simplement en lui donnant en argument le sujet de notre
recherche, comme si c’était la boite de recherche sur youtube.com. Par exemple,
si l’on veut chercher le morceau Highway of Endless Dreams d’M83 on pourrait
faire :
ytcli "M83 - Highway of Endless Dreams"
et cela imprime
M83 - Highway of Endless Dreams (audio)
URL: https://www.youtube.com/embed/iqNohjW_kWc
Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UC8WbdD3m5dP9giOU9XtAGWQ
Channel title: M83
Channelid: UC8WbdD3m5dP9giOU9XtAGWQ
Published: 7 years ago
Viewcount: 138,424 views
Duration: 4:37
===
M83 Highway Of Endless Dreams
URL: https://www.youtube.com/embed/HXUKHZ9wwNw
Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCynAa3zrpJlU4WjxiBe4qrg
Channel title: inner silence
Channelid: UCynAa3zrpJlU4WjxiBe4qrg
Published: 8 years ago
Viewcount: 29,162 views
Duration: 4:36
===
M83 "Highway of Endless Dreams, Skin of the Night,+" live on 6.6.2008 in Philadelphia, PA.
URL: https://www.youtube.com/embed/6SQkmxjUpzc
Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCv8I0sTv7aaelMbd3OQEdAw
Channel title: Not All Punk & Games
Channelid: UCv8I0sTv7aaelMbd3OQEdAw
Published: 6 years ago
Viewcount: 4,547 views
Duration: 18:35
...
Ces résultats ne sont pas inventés par ytcli, ce sont très exactement les mêmes
que ceux que vous auriez obtenu si vous aviez fait la recherche sur youtube.com
dans un navigateur. ytcli
ne fait que remanier les données pour les imprimer
sous forme textuelle. Dans la grande majorité des cas le premier résultat est
celui que l’on veut. Pour rappel notre but est d’automatiser le fait de lancer
des commandes de téléchargement telle que celle que l’on a vu précédemment.
yt-dlp -f bestaudio https://www.youtube.com/embed/WBsIKQEGQ_A
Il nous faut donc récupérer le premier lien du premier résultat. A priori, tant
que l’on ne modifie pas ytcli
cette donnée se trouvera toujours sur la première
ligne commençant par URL:
ligne. On peut donc récupérer le nécessaire avec ce
coup de grep et de sed :
ytcli "M83 - Highway of Endless Dreams" | grep -m1 URL: | sed 's/URL: \+//'
Maintenant que l’on a un moyen de récupérer le lien du premier résultat d’une recherche youtube on peut les enchaîner. Notre donnée d’entrée sera la liste des chansons :
cat playlist.m3u
Inüit - Hush
Iron Maiden - Phantom Of The Opera - 1998 Remastered Version
King Gizzard & The Lizard Wizard - Inner Cell
Marc Rebillet - VACCINATED ATTITUDE
Souad Massi - Mirage (feat. Piers Faccini)
The Notorious B - Big Poppa - 2007 Remaster
Weval - Half Age
Yom - Longing for the Beat
Yuksek, Her - Sweet Addiction - Live Edit
On automatise les recherches :
cat playlist.m3u | xargs -d'\n' -n1 ytcli
Pour xargs ici le
-n1
permet d’indiquer que l’on ne veut qu’un argument par commande. Au lieu de lancerytcli titre1 titre2 titre3
ce sont les commandesytcli titre1
puisytcli titre2
puisytcli titre3
qui seront exécutées.
Comme fait précedemment on voudrait récupérer le premier lien de chaque recherche sauf que nous obtenons tous les résultats d’un coup dans l’ordre :
Nous ne pouvons donc plus simplement retenir le premier lien puisque le premier de la seconde chanson sera quelque part bien plus bas dans le flux. Les données ressemblent à ça :
recherche 1 - résultat 1
recherche 1 - résultat 2
recherche 1 - résultat 3
recherche 2 - résultat 1
recherche 2 - résultat 2
recherche 2 - résultat 3
recherche 3 - résultat 1
recherche 3 - résultat 2
recherche 3 - résultat 3
etc.
notre grep -m1 URL:
omettrait toutes les chansons venant après la première
recherche. Il nous faut opérer le grep
et le sed
sur chaque “bloc” de
résultats. Pour cela la commande exécutée par xargs doit contenir elle même les
filtres.
cat playlist.m3u | xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' --
Pour faire en sorte que la commande exécutée par xargs puisse enchaîner des pipes sans que ce soit la sortie d’xargs elle même qui soit pipée on lance un subshell avec la commande
sh -c
. L’option-c
permet de dire au subshell de lire ses commandes non pas depuisstdin
mais depuis la chaîne de caractère qui suivra dans les arguments. On écrit donc la commande qui nous intéresse entre simple cotte en positionnant l’argument$1
au bon endroit. Une fois la commande finie on ferme la simple cotte. Viennent ensuite les arguments de cette commande. Par convention le permier argument sera$0
qui contient tradtionnellement le chemin du script exécuté. Puisque qu’ici il n’y a pas fichier de script il faut choisir$0
“à la main”. Viennent ensuite les arguments$1
,$2
etc. C’est pour “sauter”$0
que l’on met les “–”. Ainsi on s’assure que l’argument passé parxargs
ne terminera pas dans$0
(puisqu’il aura déjà pour valeur –) mais bien dans$1
.
On récupère la liste :
https://www.youtube.com/embed/NZHUCu8ggpY
https://www.youtube.com/embed/VnDNXbDjPis
https://www.youtube.com/embed/G3JeZDps7O8
https://www.youtube.com/embed/qeCwwYjf8gw
https://www.youtube.com/embed/1qnKfnGFuSU
https://www.youtube.com/embed/QceVTChhlJM
https://www.youtube.com/embed/wDRp0KjJ9ds
https://www.youtube.com/embed/ptJ2fIzksIc
https://www.youtube.com/embed/qWMP-UxSEss
Il ne reste plus qu’à les télécharger :
cat playlist.m3u |
xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- |
xargs -n1 yt-dlp -f bestaudio
pas besoin de préciser le délimiteur
-d'\n'
ici puisque le démiliteur par défaut d’xargs est l’espace et que les liens n’en contiennent pas.
Il existe dorénavant, dans le dossier ou nous nous trouvons, les fichiers
./Big Poppa (2007 Remaster) [QceVTChhlJM].webm
./Phantom of the Opera (1998 Remaster) [VnDNXbDjPis].webm
./VACCINATED ATTITUDE [qeCwwYjf8gw].webm
./Longing for the Beat [ptJ2fIzksIc].webm
./Inner Cell [G3JeZDps7O8].webm
./Souad Massi - Mirage feat. Piers Faccini (Carte Blanche Culturebox) [1qnKfnGFuSU].webm
./Weval - Half Age [wDRp0KjJ9ds].webm
./INÜIT - HUSH [LIVE] [NZHUCu8ggpY].webm
./Sweet Addiction - live edit [qWMP-UxSEss].webm
Problème ! Si l’on lance la commande mpv playlist.m3u
aucune chanson ne se
lancera. Pourquoi ? En lisant le fichier playlist.m3u mpv va chercher à ouvrir le
fichier Inuit - Hush
mais celui-ci a été nommé INÜIT - HUSH [LIVE]
[NZHUCu8ggpY].webm
par yt-dlp, c’est à dire titre de la vidéo youtube
[identifiant de la vidéo].[format du fichier audio]
. Comme précisé plus tôt on
peut y remédier avec l’option `-o
cat playlist.m3u |
xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- |
paste playlist.m3u - |
sed 's/ /\n/' |
xargs -d'\n' -n2 sh -c 'yt-dlp -f bestaudio -o "$1" "$2"' --
On aura utilisé paste
pour pouvoir donner en entrée à xargs à la fois le nom
du fichier voulu et l’url de la vidéo à télécharger ainsi qu’une substitution
pour simplifier leur ingestion par xargs.
Nous avons dorénavant un format de fichier pour déclarer une playlist, un moyen de télécharger toutes les musiques s’y trouvant et un moyen pour lire la dite playlist. L’essentiel est là. Evidemment vous pourriez vouloir appeler les fichiers différèmment, sélectionner la second résultat youtube, choisir une autre qualité si vous êtes sur une mauvaise connexion par exemple, parraléliser les téléchargements. Notre commande est suffisament flexible et courte pour pouvoir faire tout cela.
Astuces d’usage :
- Si vous voulez que
yt-dlp
n’écrive pas un roman à chaque téléchargement
Utilisez l’option --quiet
. Si vous voulez tout de même avoir un retour sur ce
qu’il se passe vous pouvez modifier la commande de la sorte :
- Si vous voulez télécharger l’audio en moins bonne qualité
Vous pouvez opter pour le format worstaudio
.
Il existe pleins d’options différentes pour choisir très précisèment le format que l’on veut. On peut jouer sur la taille du fichier, le codec, le conteneur, le bitrate etc. Pour plus de détails voir la documentation de yt-dlp.
- Si vous voulez n’écouter qu’une sous partie de la playlist
Vous pouvez filtrer sur le nom d’un artiste et passer tous les fichiers en réultant à mpv à la chaîne.
grep M83 playlist.m3u | xargs -d'\n' mpv
Lira toutes les chansons d’M83 de la playlist.
J’utilise plus récemment fzy
pour ce genre de besoins. fzy
est une commande
prenant dans stdin du texte, présentant chaque ligne dans un petit menu
interactif et écrivant dans stdout le contenu de la ligne que l’on a selectionné.
On peut y écrire une recherche qui s’effectuera sur la liste d’éléments.
L’algorithme de recherche est dit “fuzzy”. On peut le voir comme une sorte de
grep fuzzy interactif. J’utilise ce fork qui a l’avantage de permettre la
multi-sélection. Un exemple d’usage simple de fzy
dans notre cas pour faire
une recherche dans notre playlist serait :
cut -f1 playlist.m3u |
fzy -m |
sed 's,^,/chemin/vers/le/dossier/avec/les/fichiers/audio' |
xargs -d'\n' mpv
- Si vous utilisez mpv, quelques raccourcis utiles
>
pour passer à la chanson suivante
<
pour passer à la chanson précédente
0
pour augmenter le volume
9
pour baisser le volume
- Si vous constatez des erreurs
Si vous utilisez beaucoup ce système vous verrez que le script ne télécharge pas toujours la chanson que vous voulez. Sur ma playlist le taux d’erreur est d’environ 5%. Elles sont majoritairement dues au fait que le premier résultat de la recherche youtube n’est pas toujours la version spécifique que vous cherchez de cette chanson. J’estime que les erreurs sont suffisament rares pour être corrigées “à la main”. Je fais une recherche youtube, récupère l’url de la version que je cherche et exécute le téléchargement moi-même. Il est assez fréquent que si le premier résultat youtube n’est pas celui que vous cherchez, le second sera le bon. Pour automatiser un peu cette affaire on peut donc imaginer noter les titres des chansons qui posent problème dans un fichier et les télécharger mais en choisissant la seconde option à chaque fois. Le filtre ne sera donc plus
ytcli "M83 - Highway of Endless Dreams" | grep -m1 URL: | sed 's/URL: \+//'
mais
ytcli "M83 - Highway of Endless Dreams" | grep -m2 URL: | tail -n1 | sed 's/URL: \+//'
On peut facilement imaginer la première version être présente dans un script ou un alias et la seconde dans un autre script ou un autre alias nommé “correction”.
- Si vous voulez ajouter une ou plusieurs musiques
Ajouter un morceau revient simplement à écrire une nouvelle ligne dans notre fichier de playlist. L’emplacement dans le fichier determinera quand il sera lu. Ajouté tout en haut du fichier il sera lu en premier, tout en bas il sera lu en dernier etc. Ensuite si vous relancez le téléchargement avec la commande vue précédemment vous retéléchargerez toutes les chansons. Trois façon de se prémunir de cela :
- Vous filtrez le fichier de playlist pour n’inclure que les chansons que vous venez d’ajouter.
Par exemple si vous avez ajouté deux chansons au début du fichier, commencez
par un head -n2
plutôt qu’un cat
. Il faudra ajouter un tee quelque part
pour écrire un fichier temporaire ne contenant que les fichiers filtrés sinon
le paste sera bancale. Exemple :
head -n2 playlist.m3u |
tee temp |
xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- |
paste temp - |
sed 's/ /\n/' |
xargs -d'\n' -n2 sh -c 'yt-dlp -f worstaudio -o "$1" "$2"' --
rm temp
- Ajoutez l’option
--no-overwrites
à yt-dlp.
Avec cete option yt-dlp vérifiera si un fichier au nom que vous voulez donner
au nouveau téléchargement existe déjà. Si oui alors yt-dlp sautera le
téléchargement. Cependant il téléchargera quand même la page web de la vidéo.
Ma théorie est que cela est nécessaire quand on ne donne pas le nom du fichier
nous même. En effet, dans ce cas yt-dlp doit d’abord récupérer quelques infos
(le titre de la vidéo sur youtube notamment) pour savoir si le nom de fichier
qu’il génèrera pour le nouveau téléchargement sera le même qu’un fichier déjà
existant. Puisque l’on force le nom du fichier avec -o
ce comportement n’a
pas vraiment de sens, il suffirait pour yt-dlp de vérifier que l’argument donné
à -o
n’est pas le nom d’un fichier déjà existant et ce sans jamais avoir
besoin d’obtenir quoi que ce soit comme information sur la vidéo.
- Pour remédier au souci de 2. on peut nous même filtrer le fichier playlist pour ne retenir que les titres non téléchargés - c’est à dire ceux qui n’ont pas de fichier à leur nom.
Pour cela nous allons utiliser une commande nommée comm
:
sort playlist.m3u > temp
find * |
comm -23 temp -
rm temp
En shell POSIX il n’est, je crois, pas possible de rediriger deux entrées dans une commande. Il nous faut donc créer un fichier intermédiaire
temp
pour contenir les titres des chansons de la playlist triées par ordre alphabétique. On compare ensuite ce contenu avec les chemins des fichiers du dossier local et on n’affiche que ce qui est unique au fichier playlist.m3u.comm
construit des données sous la forme de trois colonnes. La première est tout ce qui est unique au premier fichier, la seconde au second et la troisième ce qui est commun au deux fichiers. Ici on passetemp
- c’est à dire le contenu du fichierplaylist.m3u
- en premier. C’est bien ce qui existe dans ce fichier et pas dans le dossier que l’on veut récupérer. On utilise donc les options-2
et-3
que l’on peut concatener en-23
pour dire à comm de supprimer la deuxième et la troisième colonne du résultat. Finalement on supprime le fichier temporaire.
En réalité ce filtre pourrait être celui par défaut. Si c’est la première fois que vous déclarez la playlist il permettra de tout télécharger. Si jamais vous ajoutez quoi que ce soit il permettra de télécharger les nouveautés. Attention si vous modifiez le nom d’une chanson dans le fichier sans modifier le nom du fichier audio correspondant vous retéléchargerez la chanson. Si vous supprimez un fichier ce filtre ne permettra rien. En somme cela ne permet une synchronisation qu’en ajout.
- Si vous voulez supprimer une ou des musiques
Même approche que pour l’ajout mais avec des options différentes pour comm
sort playlist.m3u > temp
find * |
comm -13 temp - |
grep -v "playlist.m3u" |
xargs -d'\n' rm
Cette fois-ci c’est ce qui se trouve uniquement dans le dossier et plus dans le fichier que l’on souhaite. On utilise donc les options
-13
. On ajoute également un grep pour éviter d’inclure les fichiers playlist.m3u dans le lot. En effet ce fichier existe bien dans le dossier sans pour autant être dans la playlist mais nous ne voudrions pas le supprimer. On pipe le tout dans un xargs pour supprimer les fichiers correspondants.
- Si vous voulez faire des recherches
J’utilise fzy, voir ce que j’ai écrit plus haut, sous le point “Si vous voulez n’écouter qu’une sous partie de la playlist”.
- Si vous voulez avoir un système de tag
J’ai récemment eu l’envie de classifier les chansons d’une playlist en fonction
de certains thèmes. Pour cela on pourrait créer autant de playlist différentes,
c’est tout à fait naturel. Cela ferait autant de fichiers. Alternativement si
vous souhaitez classer les chansons au sein d’une même playlist nous pouvons
ajouter des tags avec la syntaxe artiste - titre[tabulation]tag1 tag2 tag3...
.
Cela donne par exemple :
Fistaille - 13h12 acab
Maya Dunietz - The wine of love (feat. David Lemoine)
AURORA, Pomme - Everything Matters sadgirl
Edouard Ferlet - Reflex
Emile Londonien - Missing Arrow jazz
Emile Londonien - Covered Bridges jazz
Sampa the great - Never Forget hiphop
Fred again... - Marea dance electro
Sampa the Great - Shadows hiphop
Sébastien Tellier - L'amour et la violence
DOMi & JD BECK - SMiLE jazz
Brutalist - Movements dance electro
Shubh Saran - Enculture
Gala - Freed From Desire dance
Mara, Sleazy Stereo - Foufoune dance hiphop
On peut ensuite faire un grep
pour filtrer sur un tag
grep -i " .*dance.*" playlist.m3u
ce qui renvoie
Fred again... - Marea dance electro
Brutalist - Movements dance electro
Gala - Freed From Desire dance
Mara, Sleazy Stereo - Foufoune dance hiphop
et pourra être lu dans mpv en pipant tout ça
grep -i " .*dance.*" playlist.m3u | cut -f1 | shuf | xargs -d'\n' mpv
Le petit shuf
pour désordonner le résultat.
Attention, avec ce système faire mpv playlist.m3u
ne fonctionnera plus pour
les chansons sur lesquelles vous avez mis un tag puisqu’il n’existera pas de
fichier avec un nom correspondant (“Fistaille - 13h12 acab” n’est pas le
fichier que l’on souhaite lire). Il faut donc adapter vos alias et le script de
synchro de façon à omettre les tags. Ça tombe bien, cela revient à piper le
fichier dans cut -f1
.
L’ajout de ce système de tag et cette courte documentation m’a pris quelques
dizaines de minutes et a résulté en la modification et l’écriture de quatre
lignes de codes (ajout de trois cut -f1
et écriture d’un nouvel alias pour
filtrer sur les tags).
- Si vous voulez télécharger ce que vous avez entendu sur fip avec l’outil fip
Pour télécharger cet outil :
git clone git://katzele.netlib.re/fip
Les instructions d’usage sont dans le README.
Si votre alias pour lancer la lecture est fip
vous pouvez faire ceci
fip | tee session
pour enregistrer les informations de toutes les chansons diffusées dans le fichier session. Vous pouvez ensuie télécharger les chansons comme nous l’avons vu précédemment. Si vous kiffez ce que vous êtes en train d’écouter à l’instant vous pouvez aussi ouvrir votre fichier de playlist dans vim, taper
tail -n1 chemin/vers/session
et l’exécuter avec :.!sh
pour directement récupérer les infos.
Alternativement vous pouvez aliaser cette commande :
sed -i "1 s/^/$(tail -n1 /chemin/vers/session)\n/" /chemin/vers/playlist.m3u
- Savoir si l’un ou l’une des artistes de votre playlist passe en concert à Strasbourg
L’outil concerts est disponible avec la commande suivante :
git clone git://katzele.netlib.re/concerts-light
Avec on peut faire le croisement des données et savoir quand et où passe un artiste de votre playlist :
cut -f1 playlist.m3u |
cut -f1 -d- |
sed 's/ *$//' |
sort -u |
sed 's/, /\n/g' |
xargs -n1 -d'\n' sh -c 'grep "$1" emplacement_des_données_des_concerts' --
Ou un peu plus performant sur des gros fichiers
concerts=$(cut -f2 emplacement_données_concerts | sed 's/, /\n/g' | sort -u)
artists=$(cut -f1 emplacement_fichier_playlist | cut -f1 -d- | sed 's/ *$//' | sed 's/, /\n/g' | sort -u)
echo $concerts $artists |
sort |
uniq -d
Côté performance quand il s’agit de croiser des données entre deux sources il est souvent préférable de jouer sur le tri et la détéction de doublons plutôt que de faire des recherches à répétition.
Synchronisation
Une fonctionnalité pratique de spotify est la synchronisation des playlists sur
plusieurs terminaux. J’estime que cette fonctionnalité est suffisamment utile
pour être répliquée. L’information de la playlist est entièrement détenue dans
le fichier playlist.m3u. J’ai donc opté pour un dépôt git, hébergé sur un
serveur distant, avec pour .gitignore
*
!.gitignore
!playlist.m3u
de façon à ne tracker que la playlist et le .gitignore. Quand j’arrive sur un
nouveau terminal je fais un git pull
et je lance mon script de synchro. Pour
économiser de la bande passante il reste préférable de transférer les fichiers
audios par clef usb.
Migration depuis spotify
Si vous avez de très grandes playlists spotify j’ai écrit quelques scripts pour récupérer les infos des titres. Pour les télécharger :
git clone git://katzele.netlib.re/downloadmusic
Les instructions d’usage sont dans le README. A noter, cela fait un moment que je n’ai pas testé les scripts de migration, ils peuvent ne plus fonctionner.
L’existant
Il existe déjà des outils permettant de télécharger des musiques depuis youtube en fonction d’une playlist spotify, notamment spotdl. J’ai tout de même voulu en faire ma propre version parce que spotdl
- nécessite python or je veux vouloir gérer mes playlist sur des systèmes n’ayant pas ce langage
- est relativement peu performant, à tester plus en détail
- est un logiciel assez conséquent, je n’ai ni le temps ni l’envie de le comprendre pour pouvoir le modifier
- contient bien plus de fonctionnalités que ce dont j’ai besoin or l’abus de fonctionnalités est l’un des facteurs qui participent à l’obsolescence logicielle
Parmi les fonctionnalités supplémentaires qui pourraient vous intéresser, spotdl peut :
- récupérer tout un tas de métadonnées (artiste, titre, date de parution, nom de l’album, n° de la chanson dans l’album, pochette)
- sauter les pubs avec sponsorblock
- télécharger un album depuis un lien spotify (devrait pas être très difficile)
- afficher une interface web
- télécharger les paroles
- …