Le site arthur.bebou.netlib.re - retour accueil
git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |
index.sh (33234B)
1 #! page 2 3 title: Gestion simpliste de playlist et migration depuis Spotify 4 author: Arthur Pons 5 description: Comment gérer une playlist musicale avec des outils numériques possiblement sobres et conviviaux ? 6 publication: 2022-12-11 7 sectionmd: main 8 9 10 Le code qui résulte de toute cette exploration est accesible dans le dépôt 11 `downloadmusic` en ce qui concerne la synchronisation playlist <-> fichiers 12 audio 13 14 git clone git://katzele.netlib.re/downloadmusic 15 16 et dans 17 18 git clone git://katzele.netlib.re/zenu-arthur 19 20 en ce qui concerne les commandes que j'utilise fréquemment pour lire, 21 filtrer, synchroniser le tout. Elles sont dans les fichiers de menu `zenu` 22 (article sur le sujet à venir) `playlist` et `filtrer`. 23 24 Il vous est possible de directement utiliser ce code là[^2], mais je vous 25 recommande de lire l'article pour savoir d'où il vient et construire votre 26 système selon vos besoins. J'ai peut-être fait des choses plus compliquées 27 et nécessitant plus de dépendances que ce dont vous avez réellement besoin. 28 29 ## Le problème 30 31 Depuis que je m'organise pour pouvoir faire la (quasi) totalité de mes 32 activités numériques sur un raspberry ou équivalent je sais qu'inévitablement 33 il va falloir que je m'occupe de spotify. Il y a deux façons traditionnelles de 34 consommer de la musique sur ce service : 35 36 1. accéder au contenu via spotify.com 37 2. accéder au contenu via l'application desktop 38 39 Il est préférable de ne pas passer par un navigateur web pour écouter de la 40 musique. En effet, de très nombreuses applications savent déjà le faire et de 41 façon bien plus efficace. À l'inverse les navigateurs webs ne sont 42 originellement pas conçus pour. De manière générale il serait opportun, pour 43 réduire les coûts (de quelques natures qu'ils soient), de ne pas utiliser le 44 web pour autre chose que de s'échanger des documents html. Je ne redéveloppe 45 pas tout l'argumentaire expliquant pourquoi et comment, cela a déjà été fait 46 maintes fois. Si vous peinez à trouver des ressources dessus contactez moi ! 47 48 L'application desktop rencontre le même souci puisqu'elle est basée sur la 49 technologie [electron] qui fait usage de la stack technique des navigateurs 50 web. Cet état de fait condamne une personne utilisant un ordinateur peu 51 puissant à ne pas pouvoir utiliser spotify. J'imagine que c'est au moins en 52 partie pour cette raison qu'un ensemble de clients tiers est apparu. Pour en 53 lister deux : 54 55 * [spotify-tui], une interface textuelle dans la console, écrite en rust 56 * [Psst], une interface graphique, écrite en rust 57 58 Ces deux logiciels sont bien des interfaces, elles ne remplacent pas le backend 59 de spotify. Pour pouvoir les utiliser et écouter de la musique avec il vous 60 faudra utiliser [spotifyd] qui s'occupera d'aller streamer la musique depuis 61 spotify. Les interfaces contrôleront spotifyd pour lui dire de passer la 62 chanson, monter le volume etc. Pour avoir testé ces deux solutions il y a un an 63 environ elles fonctionnent et sont effectivement beaucoup plus légères mais 64 rencontrent d'assez nombreux problèmes/bug. Je ne vais pas prendre le temps de 65 les lister, j'ai simplement le souvenir qu'à force de frustration j'ai décidé 66 de réutiliser l'appli desktop sur mes terminaux relativement puissants. 67 68 J'étais donc rendu au point de départ. Il se trouve qu'il y a d'autres raisons 69 de vouloir se débarrasser de spotify, notamment le [DRM ou Gestion des Droits 70 Numériques]. Le DRM, c'est pas bien. Les alternatives sont : 71 72 * Écouter la musique sur youtube ou une autre plateforme "ouverte" (quoi 73 qu'avec un bloqueur de pub c'est kifkif ?) 74 * Acheter la musique 75 * Le piratage 76 77 Le piratage c'est pas bien, [vous ne voleriez pas une voiture n'est-ce pas] ? 78 Cependant, si l'on veut rester sur quelque chose d'aussi simple que Spotify 79 j'ai le sentiment que le piratage, notamment télécharger de la musique que l'on 80 trouve sur youtube, est la meilleure solution. Je dois préciser que cette 81 réflexion de ma part est certainement regrettable. Je pense que je me suis fait 82 à la relative simplicité de l'usage de spotify ce qui m'incite à ne pas 83 chercher à acheter la musique. Ces achats devraient se faire dans des lieux 84 différents, auraient des formats différents etc. J'ai consenti à faire des 85 efforts supplémentaire dans d'autres domaines de ma vie quand je sais que cela 86 réduit considérablement les coûts sociaux et environnementaux mais je me voyais 87 mal le faire dans celui-ci. Du moins pas tout de suite. 88 89 ## Mon usage de spotify 90 91 D'abord je décris l'usage que j'en fais. Si votre usage est très différent 92 peut-être que ce que j'ai pensé ne vous conviendra pas du tout. J'utilise 93 spotify de trois façons différentes. 94 95 * Playlist "Liked Songs" (en anglais) 96 97 Je découvre de la musique à travers des ami·e·s, en écoutant la radio, en 98 allant en soirée, festival, concert ou beaucoup plus rarement en utilisant les 99 recommandations spotify. Je fais une recherche sur spotify, j'écoute et je 100 "like" ce que j'apprécie. J'écoute la playlist "Liked Songs" produite dans 101 l'ordre antéchronologique ou en aléatoire. 102 103 * Ecoute plus spécifique 104 105 J'ai une envie très particulière d'écouter un ou une artiste, je fais une 106 recherche spécifique et j'écoute, généralement des albums en entier. 107 108 * Ecoute en soirée 109 110 J'ouvre l'interface spotify sur mon pc et je laisse les personnes mettre la 111 musique qu'elles souhaitent. 112 113 J'ai un usage assez restreint des playlists en dehors de celle générée par les 114 titres que je like. Au vu de ces usages je me suis construit un petit système 115 pour répliquer une partie de mon usage de spotify. 116 117 ## shell + ytcli + yt-dlp + mpv + git 118 119 Pour économiser de la bande passante et pouvoir écouter de la musique sans 120 avoir besoin d'internet, comme lorsque l'on télécharge la musique en local sur 121 spotify, il faut pouvoir télécharger les morceaux. Je choisis de le faire 122 depuis youtube du fait de la taille du catalogue disponible sur cette 123 plateforme. Si vous avez déjà lu [l'article sur ma façon de lire des vidéos 124 youtube] vous savez que l'on peut télécharger des vidéos youtube avec [yt-dlp]. 125 Puisque yt-dlp permet d'accéder à tous les formats disponibles, il est possible 126 de télécharger uniquement l'audio d'une vidéo. 127 128 Pour faire simple on peut utiliser les formats "dynamiques" de yt-dlp. Le 129 format `worstaudio` sélectionnera toujours le format audio de moins bonne 130 qualité[^1]. Le format `bestaudio` fera l'inverse. Puisque que l'on 131 souhaite écouter de la musique et que par ailleurs youtube n'héberge pas des 132 formats audio de très grande taille, le format `bestaudio` me semble adapté à 133 notre besoin. Ainsi, si l'on souhaite télécharger la musique 134 `https://www.youtube.com/embed/WBsIKQEGQ_A` on peut lancer la commande 135 136 yt-dlp -f bestaudio https://www.youtube.com/embed/WBsIKQEGQ_A 137 138 et obtenir un fichier de 3,96Mo nommé "Mop Mop - Jamajumba [WBsIKQEGQ_A].webm". 139 Si votre morale ou vos contraintes techniques vous imposent de télécharger des 140 formats plus petits regardez le manuel de yt-dlp pour choisir un format 141 différent. Pour changer le nom du fichier on peut utiliser l'option `-o` qui 142 prendra en argument une chaine de caractère. Si l'on récupère quelques liens de 143 la sorte et que l'on télécharge quelques musiques, construire une playlist 144 revient à créer un fichier avec la liste des chemins vers les fichiers audios. 145 146 Par exemple, vous pouvez avoir l'arborescence suivante : 147 148 /home/vous/playlist 149 ├── Inüit - Hush 150 ├── Iron Maiden - Phantom Of The Opera - 1998 Remastered Version 151 ├── King Gizzard & The Lizard Wizard - Inner Cell 152 ├── Marc Rebillet - VACCINATED ATTITUDE 153 ├── playlist.m3u 154 ├── Souad Massi - Mirage (feat. Piers Faccini) 155 ├── The Notorious B - Big Poppa - 2007 Remaster 156 ├── Weval - Half Age 157 ├── Yom - Longing for the Beat 158 └── Yuksek, Her - Sweet Addiction - Live Edit 159 160 Avec le contenu de `playlist.m3u` étant : 161 162 Inüit - Hush 163 Iron Maiden - Phantom Of The Opera - 1998 Remastered Version 164 King Gizzard & The Lizard Wizard - Inner Cell 165 Marc Rebillet - VACCINATED ATTITUDE 166 Souad Massi - Mirage (feat. Piers Faccini) 167 The Notorious B - Big Poppa - 2007 Remaster 168 Weval - Half Age 169 Yom - Longing for the Beat 170 Yuksek, Her - Sweet Addiction - Live Edit 171 172 Et il suffira de faire 173 174 mpv playlist.m3u 175 176 ou 177 178 vlc playlist.m3u 179 180 pour lire toute la playlist dans l'ordre du fichier. Pour la suite je prendrai 181 mpv pour exemple parce que c'est ce que j'utilise. On peut lancer la playlist 182 avec : 183 184 mpv --no-audio-display --volume=50 chemin/vers/la/playlist.m3u 185 186 `--no-audio-display` permet de garantir qu'mpv n'ouvrira pas d'interface 187 graphique, `--volume=50` de ne pas péter mes oreilles par défaut. 188 189 Si l'on veut jouer la playlist de façon aléatoire, deux solutions. Soit on 190 utilise l'option `--shuffle` d'mpv soit on mélange le contenu du fichier avec 191 `shuf` : 192 193 shuf playlist.m3u | xargs -d'\n' mpv 194 195 J'aurais tendance à favoriser l'utilisation de `shuf`. C'est un outil 196 agnostique que l'on pourra réutiliser à chaque fois qu'il faut mélanger un 197 fichier. A l'inverse `--shuffle` ne fait sens que dans le cadre d'mpv. 198 Philo Unix, acquisition de savoirs génériques, etc. 199 200 > J'utilise beaucoup `xargs`, c'est une commande vraiment puissante. Un jour je 201 > ferai un court article pour expliquer comment elle fonctionne (ou du moins 202 > l'usage que j'en fais). En attendant sachez qu'ici cela exprime l'idée "prend 203 > chaque élément rendu par `shuf playslist.m3u` séparé par une retour à la ligne 204 > (chaque ligne donc) et fais-en un argument à la commande mpv. Cela revient donc 205 > à lancer la commande `mpv titre1 titre2 titre3 titre4`. 206 207 Tout cela est bien sympa mais comment fait-on si l'on a des playlists de 208 plusieurs centaines chansons, on va quand même pas chercher les liens sur 209 youtube à la main et lancer les commandes yt-dlp une par une ? 210 211 Non effectivement, on peut l'automatiser. Ce ne sera pas sans erreurs mais le 212 gain de temps sera tout de même considérable. Pour automatiser les recherches 213 youtube nous allons utiliser un outil disponible dans le dépôt [frontends] de 214 codemadness. On y retrouve, dans le dossier youtube, le nécessaire pour 215 compiler un binaire nommé `cli` qui permet de faire des recherches youtube et 216 de récupérer les résultats dans la console sous format texte. Dans le reste de 217 cet article je nommerai `cli` `ytcli` pour plus de clarté. 218 219 > il est possible que vous ayez des difficultés à compiler ytcli et il est 220 > préférable de légèrement le modifier pour notre besoin. Je ferai un petit tuto 221 > à l'avenir pour les personnes que ça intéresse TODO 222 223 `ytcli` s'utilise simplement en lui donnant en argument le sujet de notre 224 recherche, comme si c'était la boite de recherche sur youtube.com. Par exemple, 225 si l'on veut chercher le morceau Highway of Endless Dreams d'M83 on pourrait 226 faire : 227 228 ytcli "M83 - Highway of Endless Dreams" 229 230 et cela imprime 231 232 M83 - Highway of Endless Dreams (audio) 233 URL: https://www.youtube.com/embed/iqNohjW_kWc 234 Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UC8WbdD3m5dP9giOU9XtAGWQ 235 Channel title: M83 236 Channelid: UC8WbdD3m5dP9giOU9XtAGWQ 237 Published: 7 years ago 238 Viewcount: 138,424 views 239 Duration: 4:37 240 === 241 M83 Highway Of Endless Dreams 242 URL: https://www.youtube.com/embed/HXUKHZ9wwNw 243 Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCynAa3zrpJlU4WjxiBe4qrg 244 Channel title: inner silence 245 Channelid: UCynAa3zrpJlU4WjxiBe4qrg 246 Published: 8 years ago 247 Viewcount: 29,162 views 248 Duration: 4:36 249 === 250 M83 "Highway of Endless Dreams, Skin of the Night,+" live on 6.6.2008 in Philadelphia, PA. 251 URL: https://www.youtube.com/embed/6SQkmxjUpzc 252 Atom feed: https://www.youtube.com/feeds/videos.xml?channel_id=UCv8I0sTv7aaelMbd3OQEdAw 253 Channel title: Not All Punk & Games 254 Channelid: UCv8I0sTv7aaelMbd3OQEdAw 255 Published: 6 years ago 256 Viewcount: 4,547 views 257 Duration: 18:35 258 ... 259 260 Ces résultats ne sont pas inventés par ytcli, ce sont très exactement les mêmes 261 que ceux que vous auriez obtenu si vous aviez fait la recherche sur youtube.com 262 dans un navigateur. `ytcli` ne fait que remanier les données pour les imprimer 263 sous forme textuelle. Dans la grande majorité des cas le premier résultat est 264 celui que l'on veut. Pour rappel notre but est d'automatiser le fait de lancer 265 des commandes de téléchargement telle que celle que l'on a vu précédemment. 266 267 yt-dlp -f bestaudio https://www.youtube.com/embed/WBsIKQEGQ_A 268 269 Il nous faut donc récupérer le premier lien du premier résultat. A priori, tant 270 que l'on ne modifie pas `ytcli` cette donnée se trouvera toujours sur la première 271 ligne commençant par `URL:` ligne. On peut donc récupérer le nécessaire avec ce 272 coup de grep et de sed : 273 274 ytcli "M83 - Highway of Endless Dreams" | grep -m1 URL: | sed 's/URL: \+//' 275 276 Maintenant que l'on a un moyen de récupérer le lien du premier résultat d'une 277 recherche youtube on peut les enchaîner. Notre donnée d'entrée sera la liste 278 des chansons : 279 280 cat playlist.m3u 281 Inüit - Hush 282 Iron Maiden - Phantom Of The Opera - 1998 Remastered Version 283 King Gizzard & The Lizard Wizard - Inner Cell 284 Marc Rebillet - VACCINATED ATTITUDE 285 Souad Massi - Mirage (feat. Piers Faccini) 286 The Notorious B - Big Poppa - 2007 Remaster 287 Weval - Half Age 288 Yom - Longing for the Beat 289 Yuksek, Her - Sweet Addiction - Live Edit 290 291 On automatise les recherches : 292 293 cat playlist.m3u | xargs -d'\n' -n1 ytcli 294 295 > Pour xargs ici le `-n1` permet d'indiquer que l'on ne veut qu'un argument par 296 > commande. Au lieu de lancer `ytcli titre1 titre2 titre3` ce sont les commandes 297 > `ytcli titre1` puis `ytcli titre2` puis `ytcli titre3` qui seront exécutées. 298 299 Comme fait précedemment on voudrait récupérer le premier lien de chaque 300 recherche sauf que nous obtenons tous les résultats d'un coup dans l'ordre : 301 302 303 Nous ne pouvons donc plus simplement retenir le premier lien puisque le premier 304 de la seconde chanson sera quelque part bien plus bas dans le flux. Les données 305 ressemblent à ça : 306 307 recherche 1 - résultat 1 308 recherche 1 - résultat 2 309 recherche 1 - résultat 3 310 recherche 2 - résultat 1 311 recherche 2 - résultat 2 312 recherche 2 - résultat 3 313 recherche 3 - résultat 1 314 recherche 3 - résultat 2 315 recherche 3 - résultat 3 316 etc. 317 318 notre `grep -m1 URL:` omettrait toutes les chansons venant après la première 319 recherche. Il nous faut opérer le `grep` et le `sed` sur chaque "bloc" de 320 résultats. Pour cela la commande exécutée par xargs doit contenir elle même les 321 filtres. 322 323 cat playlist.m3u | xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- 324 325 > Pour faire en sorte que la commande exécutée par xargs puisse enchaîner des 326 > pipes sans que ce soit la sortie d'xargs elle même qui soit pipée on lance un 327 > subshell avec la commande `sh -c`. L'option `-c` permet de dire au subshell 328 > de lire ses commandes non pas depuis `stdin` mais depuis la chaîne de 329 > caractère qui suivra dans les arguments. On écrit donc la commande qui nous 330 > intéresse entre simple cotte en positionnant l'argument `$1` au bon endroit. 331 > Une fois la commande finie on ferme la simple cotte. Viennent ensuite les 332 > arguments de cette commande. Par convention le permier argument sera `$0` qui 333 > contient tradtionnellement le chemin du script exécuté. Puisque qu'ici il n'y 334 > a pas fichier de script il faut choisir `$0` "à la main". Viennent ensuite 335 > les arguments `$1`, `$2` etc. C'est pour "sauter" `$0` que l'on met les "--". 336 > Ainsi on s'assure que l'argument passé par `xargs` ne terminera pas dans `$0` 337 > (puisqu'il aura déjà pour valeur --) mais bien dans `$1`. 338 339 On récupère la liste : 340 341 https://www.youtube.com/embed/NZHUCu8ggpY 342 https://www.youtube.com/embed/VnDNXbDjPis 343 https://www.youtube.com/embed/G3JeZDps7O8 344 https://www.youtube.com/embed/qeCwwYjf8gw 345 https://www.youtube.com/embed/1qnKfnGFuSU 346 https://www.youtube.com/embed/QceVTChhlJM 347 https://www.youtube.com/embed/wDRp0KjJ9ds 348 https://www.youtube.com/embed/ptJ2fIzksIc 349 https://www.youtube.com/embed/qWMP-UxSEss 350 351 Il ne reste plus qu'à les télécharger : 352 353 cat playlist.m3u | 354 xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- | 355 xargs -n1 yt-dlp -f bestaudio 356 357 > pas besoin de préciser le délimiteur `-d'\n'` ici puisque le démiliteur par 358 > défaut d'xargs est l'espace et que les liens n'en contiennent pas. 359 360 Il existe dorénavant, dans le dossier ou nous nous trouvons, les fichiers 361 362 ./Big Poppa (2007 Remaster) [QceVTChhlJM].webm 363 ./Phantom of the Opera (1998 Remaster) [VnDNXbDjPis].webm 364 ./VACCINATED ATTITUDE [qeCwwYjf8gw].webm 365 ./Longing for the Beat [ptJ2fIzksIc].webm 366 ./Inner Cell [G3JeZDps7O8].webm 367 ./Souad Massi - Mirage feat. Piers Faccini (Carte Blanche Culturebox) [1qnKfnGFuSU].webm 368 ./Weval - Half Age [wDRp0KjJ9ds].webm 369 ./INÜIT - HUSH [LIVE] [NZHUCu8ggpY].webm 370 ./Sweet Addiction - live edit [qWMP-UxSEss].webm 371 372 Problème ! Si l'on lance la commande `mpv playlist.m3u` aucune chanson ne se 373 lancera. Pourquoi ? En lisant le fichier playlist.m3u mpv va chercher à ouvrir le 374 fichier `Inuit - Hush` mais celui-ci a été nommé `INÜIT - HUSH [LIVE] 375 [NZHUCu8ggpY].webm` par yt-dlp, c'est à dire `titre de la vidéo youtube 376 [identifiant de la vidéo].[format du fichier audio]`. Comme précisé plus tôt on 377 peut y remédier avec l'option `-o 378 379 cat playlist.m3u | 380 xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- | 381 paste playlist.m3u - | 382 sed 's/ /\n/' | 383 xargs -d'\n' -n2 sh -c 'yt-dlp -f bestaudio -o "$1" "$2"' -- 384 385 On aura utilisé `paste` pour pouvoir donner en entrée à xargs à la fois le nom 386 du fichier voulu *et* l'url de la vidéo à télécharger ainsi qu'une substitution 387 pour simplifier leur ingestion par xargs. 388 389 Nous avons dorénavant un format de fichier pour déclarer une playlist, un moyen 390 de télécharger toutes les musiques s'y trouvant et un moyen pour lire la dite 391 playlist. L'essentiel est là. Evidemment vous pourriez vouloir appeler les 392 fichiers différèmment, sélectionner la second résultat youtube, choisir une 393 autre qualité si vous êtes sur une mauvaise connexion par exemple, parraléliser 394 les téléchargements. Notre commande est suffisament flexible et courte pour 395 pouvoir faire tout cela. 396 397 ### Astuces d'usage : 398 399 * Si vous voulez que `yt-dlp` n'écrive pas un roman à chaque téléchargement 400 401 Utilisez l'option `--quiet`. Si vous voulez tout de même avoir un retour sur ce 402 qu'il se passe vous pouvez modifier la commande de la sorte : 403 404 * Si vous voulez télécharger l'audio en moins bonne qualité 405 406 Vous pouvez opter pour le format `worstaudio`. 407 408 Il existe pleins d'options différentes pour choisir très précisèment le format 409 que l'on veut. On peut jouer sur la taille du fichier, le codec, le conteneur, 410 le bitrate etc. Pour plus de détails voir la [documentation de yt-dlp]. 411 412 * Si vous voulez n'écouter qu'une sous partie de la playlist 413 414 Vous pouvez filtrer sur le nom d'un artiste et passer tous les fichiers en 415 réultant à mpv à la chaîne. 416 417 grep M83 playlist.m3u | xargs -d'\n' mpv 418 419 Lira toutes les chansons d'M83 de la playlist. 420 421 J'utilise plus récemment `fzy` pour ce genre de besoins. `fzy` est une commande 422 prenant dans stdin du texte, présentant chaque ligne dans un petit menu 423 interactif et écrivant dans stdout le contenu de la ligne que l'on a selectionné. 424 On peut y écrire une recherche qui s'effectuera sur la liste d'éléments. 425 L'algorithme de recherche est dit "fuzzy". On peut le voir comme une sorte de 426 grep fuzzy interactif. J'utilise [ce fork] qui a l'avantage de permettre la 427 multi-sélection. Un exemple d'usage simple de `fzy` dans notre cas pour faire 428 une recherche dans notre playlist serait : 429 430 cut -f1 playlist.m3u | 431 fzy -m | 432 sed 's,^,/chemin/vers/le/dossier/avec/les/fichiers/audio' | 433 xargs -d'\n' mpv 434 435 * Si vous utilisez mpv, quelques raccourcis utiles 436 437 `>` pour passer à la chanson suivante\ 438 `<` pour passer à la chanson précédente\ 439 `0` pour augmenter le volume\ 440 `9` pour baisser le volume 441 442 * Si vous constatez des erreurs 443 444 Si vous utilisez beaucoup ce système vous verrez que le script ne télécharge 445 pas toujours la chanson que vous voulez. Sur ma playlist le taux d'erreur est 446 d'environ 5%. Elles sont majoritairement dues au fait que le premier résultat 447 de la recherche youtube n'est pas toujours la version spécifique que vous 448 cherchez de cette chanson. J'estime que les erreurs sont suffisament rares pour 449 être corrigées "à la main". Je fais une recherche youtube, récupère l'url de la 450 version que je cherche et exécute le téléchargement moi-même. Il est assez 451 fréquent que si le premier résultat youtube n'est pas celui que vous cherchez, 452 le second sera le bon. Pour automatiser un peu cette affaire on peut donc 453 imaginer noter les titres des chansons qui posent problème dans un fichier et 454 les télécharger mais en choisissant la seconde option à chaque fois. Le filtre 455 ne sera donc plus 456 457 ytcli "M83 - Highway of Endless Dreams" | grep -m1 URL: | sed 's/URL: \+//' 458 459 mais 460 461 ytcli "M83 - Highway of Endless Dreams" | grep -m2 URL: | tail -n1 | sed 's/URL: \+//' 462 463 On peut facilement imaginer la première version être présente dans un script ou 464 un alias et la seconde dans un autre script ou un autre alias nommé 465 "correction". 466 467 * Si vous voulez ajouter une ou plusieurs musiques 468 469 Ajouter un morceau revient simplement à écrire une nouvelle ligne dans notre 470 fichier de playlist. L'emplacement dans le fichier determinera quand il sera 471 lu. Ajouté tout en haut du fichier il sera lu en premier, tout en bas il sera 472 lu en dernier etc. Ensuite si vous relancez le téléchargement avec la commande 473 vue précédemment vous retéléchargerez toutes les chansons. Trois façon de se 474 prémunir de cela : 475 476 1. Vous filtrez le fichier de playlist pour n'inclure que les chansons que vous 477 venez d'ajouter. 478 479 Par exemple si vous avez ajouté deux chansons au début du fichier, commencez 480 par un `head -n2` plutôt qu'un `cat`. Il faudra ajouter un tee quelque part 481 pour écrire un fichier temporaire ne contenant que les fichiers filtrés sinon 482 le paste sera bancale. Exemple : 483 484 head -n2 playlist.m3u | 485 tee temp | 486 xargs -d'\n' -n1 sh -c 'ytcli "$1" | grep -m1 URL: | sed "s/URL: \+//"' -- | 487 paste temp - | 488 sed 's/ /\n/' | 489 xargs -d'\n' -n2 sh -c 'yt-dlp -f worstaudio -o "$1" "$2"' -- 490 rm temp 491 492 2. Ajoutez l'option `--no-overwrites` à yt-dlp. 493 494 Avec cete option yt-dlp vérifiera si un fichier au nom que vous voulez donner 495 au nouveau téléchargement existe déjà. Si oui alors yt-dlp sautera le 496 téléchargement. Cependant il téléchargera quand même la page web de la vidéo. 497 Ma théorie est que cela est nécessaire quand on ne donne pas le nom du fichier 498 nous même. En effet, dans ce cas yt-dlp doit d'abord récupérer quelques infos 499 (le titre de la vidéo sur youtube notamment) pour savoir si le nom de fichier 500 qu'il génèrera pour le nouveau téléchargement sera le même qu'un fichier déjà 501 existant. Puisque l'on force le nom du fichier avec `-o` ce comportement n'a 502 pas vraiment de sens, il suffirait pour yt-dlp de vérifier que l'argument donné 503 à `-o` n'est pas le nom d'un fichier déjà existant et ce sans jamais avoir 504 besoin d'obtenir quoi que ce soit comme information sur la vidéo. 505 506 3. Pour remédier au souci de 2. on peut nous même filtrer le fichier playlist 507 pour ne retenir que les titres non téléchargés - c'est à dire ceux qui n'ont 508 pas de fichier à leur nom. 509 510 Pour cela nous allons utiliser une commande nommée `comm` : 511 512 sort playlist.m3u > temp 513 find * | 514 comm -23 temp - 515 rm temp 516 517 > En shell POSIX il n'est, je crois, pas possible de rediriger deux entrées 518 > dans une commande. Il nous faut donc créer un fichier intermédiaire `temp` 519 > pour contenir les titres des chansons de la playlist triées par ordre 520 > alphabétique. On compare ensuite ce contenu avec les chemins des fichiers du 521 > dossier local et on n'affiche que ce qui est unique au fichier playlist.m3u. 522 > `comm` construit des données sous la forme de trois colonnes. La première est 523 > tout ce qui est unique au premier fichier, la seconde au second et la 524 > troisième ce qui est commun au deux fichiers. Ici on passe `temp` - c'est à 525 > dire le contenu du fichier `playlist.m3u` - en premier. C'est bien ce qui 526 > existe dans ce fichier et pas dans le dossier que l'on veut récupérer. On 527 > utilise donc les options `-2` et `-3` que l'on peut concatener en `-23` pour 528 > dire à comm de supprimer la deuxième et la troisième colonne du résultat. 529 > Finalement on supprime le fichier temporaire. 530 531 En réalité ce filtre pourrait être celui par défaut. Si c'est la première fois 532 que vous déclarez la playlist il permettra de tout télécharger. Si jamais vous 533 ajoutez quoi que ce soit il permettra de télécharger les nouveautés. Attention 534 si vous modifiez le nom d'une chanson dans le fichier sans modifier le nom du 535 fichier audio correspondant vous retéléchargerez la chanson. Si vous supprimez 536 un fichier ce filtre ne permettra rien. En somme cela ne permet une 537 synchronisation qu'en ajout. 538 539 * Si vous voulez supprimer une ou des musiques 540 541 Même approche que pour l'ajout mais avec des options différentes pour `comm` 542 543 sort playlist.m3u > temp 544 find * | 545 comm -13 temp - | 546 grep -v "playlist.m3u" | 547 xargs -d'\n' rm 548 549 > Cette fois-ci c'est ce qui se trouve uniquement dans le dossier et plus dans 550 > le fichier que l'on souhaite. On utilise donc les options `-13`. On ajoute 551 > également un grep pour éviter d'inclure les fichiers playlist.m3u dans le 552 > lot. En effet ce fichier existe bien dans le dossier sans pour autant être 553 > dans la playlist mais nous ne voudrions pas le supprimer. On pipe le tout 554 > dans un xargs pour supprimer les fichiers correspondants. 555 556 * Si vous voulez faire des recherches 557 558 J'utilise fzy, voir ce que j'ai écrit plus haut, sous le point "Si vous voulez 559 n'écouter qu'une sous partie de la playlist". 560 561 * Si vous voulez avoir un système de tag 562 563 J'ai récemment eu l'envie de classifier les chansons d'une playlist en fonction 564 de certains thèmes. Pour cela on pourrait créer autant de playlist différentes, 565 c'est tout à fait naturel. Cela ferait autant de fichiers. Alternativement si 566 vous souhaitez classer les chansons au sein d'une même playlist nous pouvons 567 ajouter des tags avec la syntaxe `artiste - titre[tabulation]tag1 tag2 tag3...`. 568 Cela donne par exemple : 569 570 Fistaille - 13h12 acab 571 Maya Dunietz - The wine of love (feat. David Lemoine) 572 AURORA, Pomme - Everything Matters sadgirl 573 Edouard Ferlet - Reflex 574 Emile Londonien - Missing Arrow jazz 575 Emile Londonien - Covered Bridges jazz 576 Sampa the great - Never Forget hiphop 577 Fred again... - Marea dance electro 578 Sampa the Great - Shadows hiphop 579 Sébastien Tellier - L'amour et la violence 580 DOMi & JD BECK - SMiLE jazz 581 Brutalist - Movements dance electro 582 Shubh Saran - Enculture 583 Gala - Freed From Desire dance 584 Mara, Sleazy Stereo - Foufoune dance hiphop 585 586 On peut ensuite faire un `grep` pour filtrer sur un tag 587 588 grep -i " .*dance.*" playlist.m3u 589 590 ce qui renvoie 591 592 Fred again... - Marea dance electro 593 Brutalist - Movements dance electro 594 Gala - Freed From Desire dance 595 Mara, Sleazy Stereo - Foufoune dance hiphop 596 597 et pourra être lu dans mpv en pipant tout ça 598 599 grep -i " .*dance.*" playlist.m3u | cut -f1 | shuf | xargs -d'\n' mpv 600 601 Le petit `shuf` pour désordonner le résultat.\ 602 *Attention*, avec ce système faire `mpv playlist.m3u` ne fonctionnera plus pour 603 les chansons sur lesquelles vous avez mis un tag puisqu'il n'existera pas de 604 fichier avec un nom correspondant ("Fistaille - 13h12 acab" n'est pas le 605 fichier que l'on souhaite lire). Il faut donc adapter vos alias et le script de 606 synchro de façon à omettre les tags. Ça tombe bien, cela revient à piper le 607 fichier dans `cut -f1`. 608 609 L'ajout de ce système de tag et cette courte documentation m'a pris quelques 610 dizaines de minutes et a résulté en la modification et l'écriture de quatre 611 lignes de codes (ajout de trois `cut -f1` et écriture d'un nouvel alias pour 612 filtrer sur les tags). 613 614 * Si vous voulez télécharger ce que vous avez entendu sur fip avec l'outil fip 615 616 Pour télécharger cet outil : 617 618 git clone git://katzele.netlib.re/fip 619 620 Les instructions d'usage sont dans le README.\ 621 Si votre alias pour lancer la lecture est `fip` vous pouvez faire ceci 622 623 fip | tee session 624 625 pour enregistrer les informations de toutes les chansons diffusées dans le 626 fichier session. Vous pouvez ensuie télécharger les chansons comme nous l'avons 627 vu précédemment. Si vous kiffez ce que vous êtes en train d'écouter à l'instant 628 vous pouvez aussi ouvrir votre fichier de playlist dans vim, taper 629 630 tail -n1 chemin/vers/session 631 632 et l'exécuter avec `:.!sh` pour directement récupérer les infos. 633 Alternativement vous pouvez aliaser cette commande : 634 635 sed -i "1 s/^/$(tail -n1 /chemin/vers/session)\n/" /chemin/vers/playlist.m3u 636 637 * Savoir si l'un ou l'une des artistes de votre playlist passe en concert à 638 Strasbourg 639 640 L'outil concerts est disponible avec la commande suivante : 641 642 git clone git://katzele.netlib.re/concerts-light 643 644 Avec on peut faire le croisement des données et savoir quand et où passe un 645 artiste de votre playlist : 646 647 cut -f1 playlist.m3u | 648 cut -f1 -d- | 649 sed 's/ *$//' | 650 sort -u | 651 sed 's/, /\n/g' | 652 xargs -n1 -d'\n' sh -c 'grep "$1" emplacement_des_données_des_concerts' -- 653 654 Ou un peu plus performant sur des gros fichiers 655 656 concerts=$(cut -f2 emplacement_données_concerts | sed 's/, /\n/g' | sort -u) 657 artists=$(cut -f1 emplacement_fichier_playlist | cut -f1 -d- | sed 's/ *$//' | sed 's/, /\n/g' | sort -u) 658 echo $concerts $artists | 659 sort | 660 uniq -d 661 662 Côté performance quand il s'agit de croiser des données entre deux sources il 663 est souvent préférable de jouer sur le tri et la détéction de doublons plutôt 664 que de faire des recherches à répétition. 665 666 ### Synchronisation 667 668 Une fonctionnalité pratique de spotify est la synchronisation des playlists sur 669 plusieurs terminaux. J'estime que cette fonctionnalité est suffisamment utile 670 pour être répliquée. L'information de la playlist est entièrement détenue dans 671 le fichier playlist.m3u. J'ai donc opté pour un dépôt git, hébergé sur un 672 serveur distant, avec pour `.gitignore` 673 674 * 675 !.gitignore 676 !playlist.m3u 677 678 de façon à ne tracker que la playlist et le .gitignore. Quand j'arrive sur un 679 nouveau terminal je fais un `git pull` et je lance mon script de synchro. Pour 680 économiser de la bande passante il reste préférable de transférer les fichiers 681 audios par clef usb. 682 683 ## Migration depuis spotify 684 685 Si vous avez de très grandes playlists spotify j'ai écrit quelques scripts pour 686 récupérer les infos des titres. Pour les télécharger : 687 688 git clone git://katzele.netlib.re/downloadmusic 689 690 Les instructions d'usage sont dans le README. A noter, cela fait un moment 691 que je n'ai pas testé les scripts de migration, ils peuvent ne plus 692 fonctionner. 693 694 ## L'existant 695 696 Il existe déjà des outils permettant de télécharger des musiques depuis youtube 697 en fonction d'une playlist spotify, notamment [spotdl]. J'ai tout de même voulu 698 en faire ma propre version parce que spotdl 699 700 * nécessite python or je veux vouloir gérer mes playlist sur des systèmes 701 n'ayant pas ce langage 702 * est relativement peu performant, à tester plus en détail 703 * est un logiciel assez conséquent, je n'ai ni le temps ni l'envie de le 704 comprendre pour pouvoir le modifier 705 * contient bien plus de fonctionnalités que ce dont j'ai besoin or l'abus de 706 fonctionnalités est l'un des facteurs qui participent à l'obsolescence 707 logicielle 708 709 Parmi les fonctionnalités supplémentaires qui pourraient vous intéresser, spotdl peut : 710 711 * récupérer tout un tas de métadonnées (artiste, titre, date de parution, nom 712 de l'album, n° de la chanson dans l'album, pochette) 713 * sauter les pubs avec sponsorblock 714 * télécharger un album depuis un lien spotify (devrait pas être très difficile) 715 * afficher une interface web 716 * télécharger les paroles 717 * ... 718 719 [electron]: https://github.com/electron/electron 720 [spotify-tui]: https://github.com/Rigellute/spotify-tui 721 [Psst]: https://github.com/jpochyla/psst 722 [spotifyd]: https://github.com/Spotifyd/spotifyd 723 [DRM ou Gestion des Droits Numériques]: https://fr.wikipedia.org/wiki/Gestion_des_droits_num%C3author:9riques 724 [vous ne voleriez pas une voiture n'est-ce pas]: https://www.youtube.com/embed/HmZm8vNHBSU 725 [fip]: http://lien-a-venir.com 726 [l'article sur ma façon de lire des vidéos youtube]: http://people.netlib.re/notes/221019/interfaces_alternatives_youtube/index.html 727 [yt-dlp]: https://github.com/yt-dlp/yt-dlp 728 [documentation de yt-dlp]: https://github.com/yt-dlp/yt-dlp#filtering-formats 729 [frontends]: https://codemadness.org/git/frontends/files.html 730 [spotdl]: https://github.com/spotDL/spotify-downloader 731 [^1]: Ce qui ne veut pas nécessairement dire que ce sera le fichier le plus petit. Pour que worst corresponde effectivement au stream avec le bitrate le plus faible il faut redéfinir le critère de "qualité" sur la taille avec `-S`. 732 [ce fork]: https://github.com/leo-arch/fzy 733 [^2]: non sans adaptation, certains chemins sont en dur