261001-les playlistes de Claude sur Navidrome
En une phrase
AudioMuse-AI écoute réellement les morceaux (analyse sonore, pas les tags), les regroupe par parenté musicale, fait nommer les groupes par Gemini, et dépose le résultat en playlists dans Navidrome — où elles restent, même PC éteint.
1. Pourquoi sur le PC, et nulle part ailleurs
AudioMuse n'est pas un greffon : c'est une pile d'analyse (Flask + worker ONNX + PostgreSQL embarqué, 2,4 Go installés) qui exige AVX2 et 8 Go de RAM.
| Machine | AVX2 | RAM disponible | Verdict |
|---|---|---|---|
| NAS sasnexte | non — Celeron J4025 | 0,6 Go | éliminé, ne démarrera jamais |
jux-debian |
non — même CPU hôte | 3 Go | éliminé, même raison |
| VPS Jux | oui (Haswell, 6 cœurs) | 2,5 Go, swap à 4,9/8 Go | trop juste |
PC julie |
oui — Ryzen 5 2600X, 12 threads | 16 Go | retenu |
L'absence d'AVX2 sur le J4025 est définitive : ni le NAS ni la VM qui tourne dessus ne pourront héberger AudioMuse, quelle que soit la version.
2. Ce que le PC éteint change — et ne change pas
Point vérifié dans le code (tasks/mediaserver/navidrome.py) et non supposé : AudioMuse crée les playlists dans Navidrome, par l'API Subsonic (createPlaylist, puis updatePlaylist public=true). Elles vivent donc dans la base du VPS, comme si elles avaient été faites à la main.
| PC allumé | PC éteint | |
|---|---|---|
| Écouter les playlists (web, Symfonium, Feishin) | oui | oui |
| Fabriquer / rafraîchir les playlists | oui | non |
Instant Mix & Radio (greffon .ndp) |
oui | non |
3. Emplacement, et les deux pièges du poste
D:\AudioMuse-AI\
├── app\ le bundle (PostgreSQL embarqué compris), 2,4 Go
├── donnees\AudioMuse-AI\ base, audio temporaire, modèles, journaux, secrets
├── sauvegardes\ dumps produits par sauvegarder_base.py
├── Demarrer AudioMuse.cmd
├── Arreter AudioMuse.cmd
└── sauvegarder_base.py
Hors de l'arbre Syncthing, volontairement : 1,5 Go d'archive et plusieurs Go de données n'ont rien à faire sur les 7 appareils du maillage, dont un téléphone. Même raison que D:\Procedures photos\ et D:\Musique\.
⚠ Piège n°1 — MSIX
native-build/windows/paths.py construit les chemins de données à partir de la variable d'environnement LOCALAPPDATA. Or Claude Code tourne dans un conteneur MSIX : tout processus lancé depuis une session Claude voit son %LOCALAPPDATA% redirigé vers …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\. Lancé ainsi, AudioMuse installerait sa base dans un chemin fantôme — exactement l'incident Android Studio du 2026-08-26.
Demarrer AudioMuse.cmd force donc LOCALAPPDATA=D:\AudioMuse-AI\donnees avant d'appeler l'exécutable. Double bénéfice : hors périmètre de virtualisation, et hors du SSD système (95 Go libres, 146 arrêts brutaux au compteur, contre 596 Go sur D:).
C'est Julien qui lance, jamais Claude Code.
⚠ Piège n°2 — l'espace dans le chemin
Toujours dans paths.py : si le chemin de données contient une espace, AudioMuse bascule en silence vers %PROGRAMDATA%. Le lanceur vérifie et refuse de démarrer le cas échéant, plutôt que d'écrire ailleurs sans rien dire.
4. Mise en route
- Double-cliquer
Demarrer AudioMuse.cmd. Au premier lancement, PostgreSQL s'initialise : compter 1 à 2 minutes. Le lanceur attend que le port 8000 réponde, puis ouvre le navigateur. Une icône apparaît dans la zone de notification (état, journal, arrêt). - Dans l'assistant, serveur de musique : Navidrome,
https://navidrome.juxjux.ovh, utilisateurjulien, mot de passe Navidrome. - Authentification AudioMuse : un identifiant, un mot de passe, un jeton d'API. Le jeton ne sert qu'au greffon (non installé) mais l'assistant l'exige.
- Première analyse — page Analysis and Clustering → Start Analysis.
Le coût de la première analyse
AudioMuse télécharge chaque morceau en entier par l'API Subsonic (download_track → stream), l'analyse, puis passe au suivant. Un seul fichier à la fois : rien ne s'accumule sur le disque. Mais au total ~133 Go transitent depuis le VPS (donc depuis kDrive), une seule fois.
Durée annoncée par le projet : « de quelques heures à plusieurs jours ». L'analyse est reprenable — les titres déjà traités sont en base, une interruption ne fait rien perdre — et incrémentale ensuite : un nouvel album ne coûte que sa propre taille.
5. Noms de playlists par Gemini
Il n'y a aucun greffon à installer : c'est de la configuration. Le modèle ne reçoit que des étiquettes de genre et d'humeur, jamais la musique ni les fichiers.
- Créer la clé (gratuite, sans facturation) sur
aistudio.google.com→ Clés API → Créer une clé API. C'est à Julien de le faire : Claude ne crée pas d'identifiants. - AudioMuse → Administration → Configuration → Configuration avancée → Fournisseur d'IA & Nommage de playlist :
AI_MODEL_PROVIDER=GEMINIGEMINI_API_KEY= la cléGEMINI_MODEL_NAME=gemini-flash-latest— alias toujours à jour ; le défaut livré estgemini-2.5-pro, qui échoue souvent en version gratuite
- AI Prompt → Clustering Naming → style Titre complet de l'IA, et ajouter en fin de prompt la consigne de langue et de longueur (2 à 4 mots, sans underscore, jamais le mot « automatic »).
- Aperçu des titres teste sans rien enregistrer. Si les noms restent des étiquettes (
no AI title so the tag name is kept), la clé ou le nom de modèle est faux.
Si Gemini cesse un jour de répondre, les playlists sont quand même créées, avec les anciens noms à base d'étiquettes.
6. ⚠ Le suffixe _automatic — à savoir avant de s'attacher à une playlist
Toute playlist produite se termine par _automatic. Au début de chaque clustering, AudioMuse appelle delete_automatic_playlists() qui supprime dans Navidrome toutes les playlists dont le nom finit par ce suffixe — y compris celles d'une exécution précédente. C'est voulu : il les recalcule.
Pour garder une playlist définitivement : la renommer dans Navidrome en retirant
_automatic. Elle devient invisible de ce ménage et survit à tout, y compris à une réinstallation.
7. La base d'analyse, et sa sauvegarde sur kDrive
Son poids — calculé sur le schéma réel
Trois empreintes par titre, toutes en BYTEA float32 :
| Empreinte | Dimensions | Octets/titre |
|---|---|---|
MusiCNN (EMBEDDING_DIMENSION) |
200 | 800 |
CLAP (CLAP_EMBEDDING_DIMENSION) |
512 | 2 048 |
Paroles GTE (LYRICS_EMBEDDING_DIMENSION) |
768 | 3 072 |
Métadonnées (score) |
— | ~1 000 |
~7 Ko/titre × 16 069 ≈ 113 Mo de données brutes, que l'index de recherche (ivf_cell) double à peu près. Base vivante attendue : 250 à 350 Mo ; dump : 150 à 250 Mo.
⚠⚠ Pourquoi la base VIVANTE n'est pas sur kDrive
Demande initiale de Julien : « on mettra la base d'analyse dans le kDrive, on y a de la place, c'est pérenne ». L'objectif est le bon — cette base vaut des heures de calcul et 133 Go téléchargés — mais une base PostgreSQL vivante ne peut pas être posée sur kDrive : WebDAV n'offre ni fsync fiable, ni verrouillage de fichier, ni renommage atomique, et un fichier de base synchronisé pendant qu'il est ouvert se corrompt. C'est le mode de panne classique, pas une précaution théorique.
La pérennité s'obtient par un dump poussé sur kDrive — exactement le schéma de vps_backup.sh pour les 7 autres services. Restaurable sur n'importe quelle machine, et survit à un formatage.
Le script
py -3.12 D:\AudioMuse-AI\sauvegarder_base.py REM dump + envoi kDrive
py -3.12 D:\AudioMuse-AI\sauvegarder_base.py --simulation REM dump local seulement
py -3.12 D:\AudioMuse-AI\sauvegarder_base.py --restaurer REM recupere et reinjecte
- AudioMuse doit tourner : le PostgreSQL embarqué n'écoute que pendant ce temps. Le script refuse poliment sinon.
- Destination kDrive :
SYNC-pour_VPS/backups/audiomuse, dossier id 1517484, créé le 2026-10-01 à côté des sept autres sauvegardes. - Un seul nom,
audiomuse_base.dump, avecconflict=version: kDrive conserve lui-même les versions précédentes. pg_dump -Fc(format personnalisé, déjà compressé), écriture atomique.partielpuisos.replace, et refus d'envoyer un dump de moins de 1 Ko — un dump vide ne doit jamais écraser un bon.- Au-delà de 900 Mo il bascule sur l'envoi par session et morceaux : l'upload simple de kDrive refuse au-delà de 1 000 000 000 octets (leçon du 2026-09-27). Ce seuil ne sera probablement jamais atteint ici, mais le chemin existe.
- Identifiants PostgreSQL : utilisateur et base
postgressur127.0.0.1:5432, mot de passe aléatoire lu dansdonnees\AudioMuse-AI\secrets\pg_password.
8. Désinstallation
Arreter AudioMuse.cmd- Supprimer
D:\AudioMuse-AI\
C'est tout : archive portable, rien dans Program Files, rien dans le registre, aucun service, aucun résidu dans %LOCALAPPDATA% puisque les données sont sur D:.
Les playlists déjà créées restent dans Navidrome — elles ne lui appartiennent pas. Seule disparaît la base d'analyse ; d'où le dump kDrive, qui permet de revenir sans refaire les 133 Go.
9. Repères
- Version installée : v3.6.3 (2026-09-26),
AudioMuse-AI-amd64-windows.zip, 1 588 225 001 octets, téléchargé en 187 s - Ports locaux : 8000 (interface), 8001 (contrôle), 5432 (PostgreSQL embarqué) — les trois vérifiés libres avant installation, tous sur
127.0.0.1 - Portmaster : l'interface est en
127.0.0.1, couverte par la règleAllow Localhost. Rien à ouvrir, aucune connexion entrante - Le PC appelle
navidrome.juxjux.ovhen sortant : rien à ouvrir sur la Livebox - Dépôt : https://github.com/NeptuneHub/AudioMuse-AI (AGPL-3.0)
10. Mesures réelles du 2026-10-01 (première analyse)
Analyse lancée à 20h55 (heure de Paris) sur les 1 161 albums / 16 069 titres.
| Grandeur | Mesure |
|---|---|
| Durée par piste | médiane 19,5 s, moyenne 20,6 s (min 4,8 — max 93,1) |
| dont étape paroles | médiane 1,6 s, moyenne 3,1 s (max 78,7) |
| Part des paroles | 15 % du temps |
| CPU pendant l'analyse | 90 %, le worker à lui seul ~6 cœurs, 713 Mo |
| Durée totale projetée | ~92 h, soit 3,8 jours |
Trois méthodes indépendantes concordent sur ~90 h : comptage des lignes de score en base, horodatage du journal piste par piste, et la progression « Albums N/1161 ».
Le goulot est le CPU, pas le réseau : les 133 Go ne ralentissent rien, c'est l'inférence ONNX (CLAP + MusiCNN + GTE) qui limite.
Désactiver les paroles : mesuré, et non retenu
Question posée par Julien le 2026-10-01. Mesure faite sans rien désactiver, en horodatant l'étape dans le journal sur 216 pistes réelles : gain de 14 h sur 92 (92 h → 78 h, 3,8 → 3,2 jours).
Non retenu : 15 % de gain contre la perte du regroupement par le sens des textes (ce qui distingue AudioMuse d'un classeur purement acoustique), de la page Lyrics Search et de la fonction Album Creation (conditionnée à lyrics_enabled and clap_enabled). Comme l'analyse est suspendable, les 0,6 jour gagnés ne changent pas la nature du problème.
Détail : Whisper se déclenche bien (74 pistes sur 216 en échec d'API externe, repli whisper_small, timeout 300 s) mais seules 23 transcriptions aboutissent — le reste est reconnu instrumental avant. D'où une médiane basse avec quelques pointes à 78 s.
⚠ Suspendre et reprendre : sans perte
Vérifié dans le code, pas seulement dans la FAQ : tasks/analysis/main.py saute les albums entièrement analysés (Skipping album … all N tracks already analyzed) et album.py saute les étapes déjà faites piste par piste (SKIPPED MusiCNN … already analyzed).
| Moyen | Coût |
|---|---|
| Bouton Cancel Current Task (Analysis and Clustering) | rien, la tâche passe en REVOKED |
Arreter AudioMuse.cmd ou le menu de l'icône |
la piste en cours |
| Extinction du PC | la piste en cours |
Pour reprendre : relancer AudioMuse si besoin, puis Start Analysis — il repart où il s'était arrêté. Le PC n'a donc pas à rester immobilisé 3,8 jours d'affilée.
Et plus tard, l'analyse reste incrémentale : un nouvel album ne coûte que ses pistes (~5 min pour 15 titres). Le clustering, lui, recalcule toutes les playlists à chaque exécution, mais à partir des empreintes déjà en base — aucun téléchargement, aucune ré-analyse.
11. Deux corrections à la configuration documentée
- ⚠ PostgreSQL n'écoute PAS sur 5432.
native-build/windows/paths.pyannoncepg_port() = 5432, mais le serveur embarqué prend un port libre au hasard (56290 au premier démarrage) qui change à chaque redémarrage. Le seul endroit fiable est la 4ᵉ ligne depgdata/postmaster.pid.sauvegarder_base.pyle lit de là ; coder 5432 en dur donne un « Connection refused » trompeur. - ⚠ Les horodatages de la base et de l'interface sont en UTC, pas en heure de Paris (le build natif ne reçoit pas de
TZ). Deux heures d'écart en été : une analyse démarrée à 20h55 s'affiche à 18h55. Ne pas en conclure à un blocage. - ⚠ Le port 8000 écoute sur
0.0.0.0, pas sur127.0.0.1comme écrit plus haut au §9 : l'interface est donc joignable depuis le réseau local. Portmaster l'autorise (règleAllow LAN) et la bloque depuis l'extérieur (Block *), et l'interface est protégée par le compte créé dans l'assistant — mais ce n'est pas une écoute purement locale.
12. ⚠⚠ Le choix du modèle Gemini — testé le 2026-10-01
Les deux modèles conseillés (par AudioMuse et par le billet Reddit d'origine) ne fonctionnent pas. Testé en appelant directement l'API Google avec la clé de Julien :
| Modèle | Résultat |
|---|---|
gemini-2.5-pro — défaut livré par AudioMuse (config.py) |
404 — « no longer available to new users » |
gemini-flash-latest — conseillé par le billet Reddit |
503 — « currently experiencing high demand », deux fois à 96 s d'écart, puis encore 3 min plus tard |
gemini-2.5-flash |
✅ 200, réponse réelle |
gemini-2.5-flash-lite |
404 — plus ouvert aux nouveaux comptes |
gemini-2.0-flash |
404 — retiré |
Valeur à retenir : GEMINI_MODEL_NAME = gemini-2.5-flash. Son seul inconvénient face à un alias -latest est qu'il faudra le changer à la main le jour où Google sortira un Flash plus récent — bien moindre mal qu'un modèle qui ne répond jamais.
Comment distinguer les trois pannes
Le code HTTP dit tout, et évite de soupçonner la clé à tort :
| Code | Sens |
|---|---|
| 401 / 403 | la clé est mauvaise |
| 404 | le nom de modèle n'existe pas (ou plus) pour ce compte |
| 429 | quota dépassé |
| 503 | modèle surchargé chez Google — ni la clé ni le quota ne sont en cause |
Méthode de diagnostic, sans rien modifier dans l'interface :
grep -E "generativelanguage" .../logs/audiomuse.log | head
Chaque ligne donne le modèle appelé et le code obtenu.
⚠ Aucune relance automatique sur erreur HTTP
tasks/ai/providers/gemini.py : les 3 tentatives de EMPTY_RESPONSE_RETRIES ne couvrent que les réponses vides. Sur une erreur SDK (503 comprise), la fonction renvoie directement "Error: AI service is currently unavailable." sans réessayer. Un délai de 7 s précède chaque appel (GEMINI_API_CALL_DELAY_SECONDS).
Conséquence le jour du clustering : si Google est surchargé à cet instant, les playlists concernées garderont leur nom d'étiquette (Electronic_Pop_Indie_Medium_Relaxed_Danceable). Ce n'est pas perdu : relancer le clustering suffit — il travaille sur les empreintes déjà en base, donc quelques minutes, sans téléchargement ni ré-analyse, et Gemini est réinterrogé.
Valider la clé sans attendre l'analyse complète
La page Instant Playlist appelle Gemini directement (app_chat.py → config.AI_MODEL_PROVIDER). C'est le test le plus rapide : une demande en langage naturel, et le journal dit si l'IA a planifié ou si AudioMuse est retombé sur rescue: matching your words directly (= l'IA n'a pas répondu).
Validé le 2026-10-01 à 22h29 : deux appels gemini-2.5-flash en 200, playlist de 50 titres cohérente, aucun repli.
13. ⚠ Pourquoi « Preview titles » échoue en début d'analyse
Message : « No playlist was large enough to keep. » Ce n'est ni Gemini ni une erreur de réglage, c'est de l'arithmétique :
| Paramètre | Valeur |
|---|---|
NUM_CLUSTERS_MIN / MAX |
40 à 100 grappes |
MIN_PLAYLIST_SIZE_FOR_TOP_N |
20 titres minimum pour qu'une playlist soit retenue |
TOP_N_CLUSTERING_PLAYLIST |
10 playlists conservées au final |
CLUSTERING_MAX_PLAYLIST_SONGS |
200 titres maximum |
MAX_SONGS_PER_ARTIST |
3 par playlist |
Avec 237 titres analysés et 40 grappes au minimum, cela fait 6 titres par grappe au mieux. Le journal l'a confirmé au titre près : 5 playlists de 1, 4, 6, 9 et 16 titres, toutes écartées.
Il faut donc au moins ~800 titres pour que l'aperçu donne quelque chose, et en pratique davantage. Attendre ~2 000 titres (une dizaine d'heures d'analyse) avant de refaire l'essai.
Note sur le résultat final : seules 10 playlists seront conservées sur 40 à 100 grappes. Pour en avoir plus, augmenter TOP_N_CLUSTERING_PLAYLIST.
No comments to display
No comments to display