Le site arthur.bebou.netlib.re - retour accueil
Anonyme, en lecture seule : git clone git://bebou.netlib.re/arthur.bebou
Authentifié·e, en écriture : git clone ssh://git@bebou.netlib.re:1459/srv/git/arthur.bebou
Log | Files | Refs | zip | tar.gz |
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