Générateur de vidéos musicales réactives — local, rapide, sans abonnement.
Transforme n'importe quel fichier audio en vidéo visualisée frame par frame,
synchronisée beat par beat, exportée en qualité broadcast.
Audio ──► Analyse librosa ──► Features (bass / kick / rms / spec / raw)
│
Rendu OpenCV + PIL 30 fps
┌────────────────────┼────────────────────┐
│ Spectre │ Atmosphère │
│ Pochette │ Particules │
│ Texte │ Vinyle │
│ Fond │ Glow / Vignette │
└────────────────────┴────────────────────┘
│
FFmpeg ──► MP4 (NVENC GPU · libx264 CPU · encodage 1 passe)
| Composant | Détail |
|---|---|
| 10 styles de spectre | Barres premium · Barres néon · Symétrie miroir · Cercle radial · Arc plasma · Onde plasma · Waveform miroir · Oscilloscope · Ligne fine · Cercle + barres |
| Spectre tricolor | 3 bandes indépendantes (bass · mid · high) avec flash réactif aux kicks |
| 7 effets atmosphère | Aucune · Légère · Cinématique · Dense · Voiles · Lueur ambiante · Traces plasma |
| Particules | 5 presets · cycle de vie · fade in/out · drift organique · bloom two-pass |
| Disque vinyle | Rotatif · réactif aux beats · pochette image ou noir classique |
| Fond | Photo floue · Dégradé · Image perso · Fond flottant · Micro-oscillation |
| Texte | Artiste + Titre + Sous-titre · 12+ polices · taille · position XY · ombre paramétrable |
| Mode | Comportement |
|---|---|
📷 Photo floue |
La pochette album est utilisée comme fond, floutée et assombrie |
🌈 Dégradé |
Fond uni deux couleurs, personnalisable via color pickers |
📂 Image perso |
Image de fond indépendante de la pochette, avec flou et luminosité |
| Mode | Résolution | Durée | Usage |
|---|---|---|---|
| SHORT | 1080 × 1920 | ~1 min (centre audio) | Reel · Story · Short |
| VERTICAL | 1080 × 1920 | Fichier entier | Vertical complet |
| COMPLET | 1920 × 1080 | Fichier entier | Publication finale |
| DUAL | 1920×1080 + 1080×1920 | Complet + ~1 min | Les deux en un seul export |
- Encodage GPU automatique (NVIDIA NVENC) si disponible, sinon CPU libx264
- Preview live 30 fps dans l'éditeur avant export
- Historique des exports avec miniatures
| Preset | Style | Ambiance |
|---|---|---|
| Dark Premium | Cercle radial | Cinématique sombre |
| Clean White | Barres premium | Épuré lumineux |
| Neon Club | Barres néon | Club · Énergie |
| Reggae Smoke | Arc plasma tricolor | Rouge · Jaune · Vert |
| Chill Lo-Fi | Onde plasma | Doux · Relaxant |
| Short Vertical | Symétrie miroir | Format 9:16 |
| Vinyl Classic | Barres premium | Vinyle noir · Dégradé |
| Vinyl Gold | Cercle + barres | Vinyle doré · Flottant |
| Acid Wave | Oscilloscope | Vert néon · Dégradé |
| Purple Dream | Cercle radial | Vinyle · Violet |
| Midnight Vinyl | Symétrie miroir | Vinyle · Bleu nuit |
| Neon Tricolor | Barres néon | Rose · Violet · Cyan |
| Sunrise | Symétrie miroir | Orange · Or |
Les presets intégrés sont cachables individuellement et restaurables en un clic.
Les presets personnels sont sauvegardables, étoilables (★) et supprimables.
Depuis l'accueil, bouton 📺 Publier sur YouTube — trois entrées :
| Entrée | Usage |
|---|---|
| 🎬 Upload manuel | Sélectionne un fichier vidéo précis à publier |
| 📁 Upload dossier | Scanne un dossier ; seules les vidéos jamais publiées (anti-doublon nom + taille) sont proposées ; un .json de métadonnées présent dans le dossier est associé automatiquement (voir ci-dessous) |
| 📚 Mes vidéos | Parcourt playlists et vidéos déjà en ligne (filtrable par visibilité), édition titre/description/tags/visibilité, et réorganisation du planning |
- File d'attente éditable : titre (pré-rempli depuis le nom de fichier), tags, description (fenêtre dédiée), date de publication
- Dates automatiques J+1 : une date de départ est choisie, chaque vidéo suivante de la file prend +1 jour ; la session suivante repart du lendemain de la dernière vidéo réellement publiée (mémorisé dans la config, par chaîne)
- 🔄 Synchro YouTube : va chercher directement sur YouTube la date de la dernière vidéo encore programmée sur la chaîne et règle la date de départ sur le lendemain — évite de devoir vérifier manuellement sur YouTube avant de lancer une nouvelle file
- Profils (👤) : nom + tags par défaut + description par défaut, réutilisables en un clic sur toute la file
- Préfixe / Suffixe de titre : deux listes réutilisables (⚙ Gérer) pour encadrer automatiquement le titre de chaque vidéo, ex. préfixe
El Cheshire→ titre publiéEl Cheshire - NomDuFichier; combinables (préfixe + suffixe), « Appliquer à tous » reformate toute la file d'un coup
Pour publier beaucoup de vidéos d'un coup avec un titre/description/tags précis par vidéo (préparés à l'avance, par IA ou autre outil), dépose un fichier .json dans le même dossier que les vidéos avant de faire 📁 Upload dossier — il est détecté et appliqué automatiquement (le plus récent si plusieurs .json traînent).
Format attendu, une liste d'entrées avec un ID = nom du fichier vidéo (sans extension) :
[
{
"ID": "Voile Actée",
"title": "Voile Actée (Lofi Remix)",
"description": "Description complète de la vidéo...",
"tags": ["lofi", "chill", "voile"]
}
]- La correspondance ID ↔ nom de fichier est souple (accents, majuscules, espaces/tirets/underscores ignorés) :
voile-acteecorrespond àVoile Actée.mp4 - Chaque champ (
title,description,tags) est optionnel et remplace individuellement la valeur par défaut (nom de fichier / profil actif) si présent ; une vidéo sans entrée JSON garde ses valeurs par défaut sans bloquer l'import - Le
titleimporté passe quand même par le préfixe/suffixe actif - En cas d'ID en double dans le JSON, la dernière entrée du fichier l'emporte
- Un résumé après import signale les vidéos sans correspondance JSON et les ID du JSON sans vidéo correspondante
- 📤 Exporter modèle JSON (dans la file de publication) génère un JSON avec un ID par vidéo de la file actuelle et des champs vides à remplir — pratique pour démarrer sans tout retaper
Plusieurs chaînes YouTube (comptes Google différents) peuvent être gérées depuis la même app :
- Sélecteur 📺 Chaîne visible sur l'upload, la bibliothèque et l'historique de publication
- ➕ Nouvelle chaîne : donne un nom, puis lance une autorisation Device Flow dédiée à ce compte Google
- Chaque chaîne a son propre jeton d'autorisation, son propre historique anti-doublon et sa propre date de reprise J+1 — totalement indépendants d'une chaîne à l'autre
⚠️ Si le compte Google de la nouvelle chaîne est différent du tien, il doit être ajouté comme utilisateur test dans le même projet Google Cloud (voir section Authentification ci-dessous) avant de pouvoir s'autoriser
- Menu playlists à gauche (dont « Toutes les vidéos »), liste de vidéos à droite avec miniature, badge de statut (🌍 Publique · 🔗 Non répertoriée · 🔒 Privée · ⏰ Programmée + date), aperçu des tags
- Filtre par statut de visibilité
- Édition complète par vidéo (titre, tags, description, visibilité, date de programmation) écrite directement sur YouTube
Ré-planifie toutes les vidéos privées programmées à venir pour éviter d'enchaîner plusieurs vidéos de la même playlist quand d'autres sont disponibles :
- Regroupe les vidéos programmées par playlist d'appartenance (les vidéos hors playlist forment un groupe « Sans playlist »)
- Calcule un nouvel ordre par algorithme glouton (type Reorganize String) — n'impose une répétition consécutive que si elle est mathématiquement inévitable (une playlist trop dominante)
- Réassigne les dates en conservant exactement le même pool de jours déjà programmés (aucune vidéo n'est avancée/retardée dans le temps) et l'heure d'origine de chaque vidéo
- Affiche un aperçu (ancienne date → nouvelle date, playlist, titre) avant tout envoi — rien n'est appliqué sans validation
La page Historique a deux onglets : 🎬 Génération (créations locales) et 📺 Publication YouTube (vidéos uploadées de la chaîne active — date d'envoi, date programmée, lien direct « Ouvrir sur YouTube », suppression individuelle qui n'efface que la protection anti-doublon locale, jamais la vidéo en ligne).
🧹 Nettoyer les publiés (onglet Génération) : croise l'historique de génération avec l'historique de publication YouTube. Pour chaque création déjà publiée : supprime le fichier vidéo, supprime l'audio source (sauf s'il est encore utilisé par une variante Complet/Short sœur non publiée), et conserve à la place une vignette vidéo + une pochette compressées comme trace visuelle. L'entrée reste dans l'Historique (toutes les infos texte conservées), marquée « 📦 Publié · nettoyé ». Aperçu de l'espace libéré et confirmation explicite avant toute suppression.
OAuth2 Google via Device Authorization Grant (comme autoriser une app sur une smart TV) — pas de serveur web local requis. L'écran d'autorisation affiche un lien et un code copiables individuellement (📋). Le refresh token ne périme jamais ; toute réponse 401/403 de l'API (scope insuffisant, token révoqué) déclenche automatiquement une proposition de ré-autorisation.
Plusieurs chaînes / comptes Google : un seul client OAuth (un seul projet Google Cloud) suffit pour autoriser plusieurs chaînes — chaque chaîne obtient son propre jeton. Si un compte Google différent du tien doit s'autoriser (deuxième chaîne), et que le client OAuth est en mode Test (cas par défaut, voir étapes ci-dessous), il faut d'abord l'ajouter comme utilisateur test :
- console.cloud.google.com/apis/credentials/consent → sélectionner le projet contenant le client OAuth utilisé par l'app
- Onglet Utilisateurs test → + Add users → ajouter l'adresse Gmail du compte de la chaîne à autoriser (jusqu'à 100 comptes en mode Test)
- Relancer l'autorisation dans l'app (➕ Nouvelle chaîne) — l'erreur
403 access_denieddisparaît une fois le compte ajouté
Créer ses identifiants OAuth YouTube (étapes)
- Aller sur console.cloud.google.com, créer un nouveau projet
- APIs et services → Bibliothèque → chercher YouTube Data API v3 → l'activer
- APIs et services → Écran de consentement OAuth → type Externe → renseigner un nom d'app, se rajouter soi-même comme utilisateur test (pas besoin de publier l'app)
- APIs et services → Identifiants → Créer des identifiants → ID client OAuth
- Type d'application : TV et appareils à entrée limitée (indispensable pour le Device Flow utilisé ici — pas "Application de bureau")
- Récupérer le ID client et le code secret du client affichés
- Lancer TAC MP4 Studio une première fois pour qu'il crée
%APPDATA%\DoktorP3st\TAC_MP4\config.json, puis y ajouter ces deux clés :"youtube_oauth_client_id": "VOTRE_ID_CLIENT.apps.googleusercontent.com", "youtube_oauth_client_secret": "VOTRE_CODE_SECRET"
- Dans l'app : 📺 Publier sur YouTube → Autoriser → ouvrir le lien affiché, entrer le code, valider avec son compte Google
Ne jamais commiter ni partager config.json (déjà exclu par .gitignore) ni les fichiers youtube_token_*.json du même dossier — ce sont vos identifiants et jetons d'accès personnels.
- Windows 10 / 11
- Python 3.11+ — python.org
- FFmpeg (avec
ffplay) — gyan.dev/ffmpeg/builds
Installer FFmpeg (étapes)
- Télécharger
ffmpeg-release-essentials.zip - Extraire dans
C:\ffmpeg\ - Ajouter
C:\ffmpeg\binau PATH Windows :Démarrer→ Variables d'environnement →Path→ Nouveau →C:\ffmpeg\bin
- Vérifier dans un terminal :
ffmpeg -version
git clone https://github.com/Lekarov/TAC-MP4-Studio
cd TAC-MP4-Studio
pip install -r requirements.txt
python main.pyOu via le lanceur Windows :
double-clic sur TAC.bat
TAC.bat ne réinstalle les dépendances que si requirements.txt a changé depuis le dernier lancement (hash SHA256 comparé à .requirements.hash) — pas de pip install inutile à chaque démarrage.
1. ✦ NOUVELLE CRÉATION
2. Importer un fichier audio MP3 · WAV · FLAC · OGG · M4A · AAC · WMA
3. Importer une pochette PNG · JPG · WEBP · BMP
4. Régler les visuels
5. 🚀 Export → nommer → choisir le mode → GÉNÉRER
| Onglet | Contenu |
|---|---|
| ⚡ Presets | Bibliothèque unifiée intégrés + perso · favoris · sauvegarde · suppression |
| 📸 Image | Taille pochette · Réactivité · Vinyle · Fond (flou · luminosité · dégradé · image perso · oscillation) |
| ✨ Effets | Particules · Atmosphère · Couleur atmosphère |
| 📊 Spectre | Style · Taille · Position · Couleur mono ou 3 bandes · Flash beats |
| 📝 Texte | Artiste · Titre · Sous-titre · Police · Taille · Position · Ombre |
| 🚀 Export | Dossier de sortie · Mode (grille 2×2) · Génération |
| Touche | Action |
|---|---|
Espace |
Play / Pause preview audio |
R |
Recharger la preview |
F11 |
Preview plein écran |
Échap |
Quitter le plein écran |
TAC-MP4-Studio/
│
├── main.py Point d'entrée
├── TAC.bat Lanceur Windows
├── requirements.txt
│
├── img/ Assets (logo, disque vinyle, icône)
├── fonts/ Polices TTF incluses (Liberation, Carlito, Caladea)
│
└── app/
├── audio.py Analyse audio — librosa · soundfile · scipy
├── config.py Persistance JSON — AppData (écriture atomique)
├── errors.py Exceptions métier — TACError et sous-classes
├── exporter.py Pipeline export — rendu + FFmpeg
├── loading.py Écran de chargement animé
├── logger.py Logging centralisé — fichier rotatif + console
├── models.py RenderSettings (dataclass)
├── particles.py Particules · Fumée · Voiles · Plasma · Lueur
├── presets.py Constantes · Presets visuels · Palettes
├── renderer.py Rendu frame — image · texte · fond · vignette · glow
├── spectrum.py 10 styles de spectre + orbe audio
├── vinyl.py Disque vinyle rotatif + pochette
├── youtube_auth.py OAuth2 Google — Device Authorization Grant
├── youtube_api.py Lecture/édition playlists + vidéos (API Data v3, HTTP brut)
├── youtube_upload.py Upload résumable de vidéos (API Data v3, HTTP brut)
│
└── ui/
├── app.py App — état · lifecycle · navigation · construction éditeur
├── editor.py EditorMixin — onglets + callbacks + gestion presets
├── export_ui.py ExportMixin — projet · settings courants · export simple/DUAL/test
├── pages.py PagesMixin — accueil · historique · turbo
├── preview.py PreviewMixin — preview live · waveform · audio
├── turbo.py TurboMixin — export par lot (mode Turbo)
├── youtube_ui.py YoutubeMixin — upload programmé · bibliothèque · réorganisation
└── widgets.py Widgets réutilisables
App
├─ EditorMixin · PagesMixin · PreviewMixin · TurboMixin · ExportMixin
├─ renderer ──► spectrum · vinyl · particles
├─ exporter ──► renderer · audio
├─ errors · logger
└─ config · models · presets
Chaque composant utilise des exceptions métier typées. Les messages utilisateur sont affichés en popup, les détails techniques sont loggués dans :
%APPDATA%\DoktorP3st\TAC_MP4\logs\tac.log
| Exception | Déclencheur |
|---|---|
AudioImportError |
Fichier absent · format invalide · lecture librosa échouée |
ImageImportError |
Image absente · corrompue · format non supporté |
FFmpegError |
FFmpeg introuvable · crash encodage |
ExportError |
Dossier absent · permission refusée · export interrompu |
ConfigError |
Config JSON corrompue · écriture impossible |
PreviewError |
Crash preview · widget détruit · callback tardif |
RenderError |
Dimensions invalides · erreur OpenCV frame |
PresetError |
Preset invalide ou incomplet |
YoutubeError |
Échec API YouTube (upload, lecture/édition playlists ou vidéos) |
YoutubeAuthError |
Réponse 401/403 — jeton absent, expiré ou scope OAuth insuffisant (déclenche une proposition de ré-autorisation) |
Sauvegarde automatique dans :
%APPDATA%\DoktorP3st\TAC_MP4\config.json
Dossier de sortie par défaut (modifiable dans l'app) :
%APPDATA%\DoktorP3st\TAC_MP4\Creations\
Jeton OAuth YouTube (Device Authorization Grant, ne périme jamais) — un fichier par chaîne :
%APPDATA%\DoktorP3st\TAC_MP4\youtube_token_<id_chaîne>.json
Identifiants du client OAuth (youtube_oauth_client_id / youtube_oauth_client_secret), chaînes avec leur historique d'upload anti-doublon et dernière date programmée par chaîne (youtube_channels), profils (youtube_profiles) et préfixes/suffixes de titre (youtube_title_prefixes / youtube_title_suffixes) sont stockés dans le config.json ci-dessus.
Purge sélective à la carte, avec confirmation explicite des conséquences avant toute suppression :
| Option | Effet |
|---|---|
| Historique de génération | Efface les métadonnées des créations — les fichiers vidéo restent sur le disque |
| Historique de publication YouTube | Efface la protection anti-doublon locale — les vidéos restent en ligne sur YouTube |
| Fichiers vidéo générés (dossier Creations) | Supprime les fichiers eux-mêmes du disque — irréversible |
Journal de l'application (tac.log) |
Vide le fichier de diagnostic technique |
pip install pyinstaller
pyinstaller --onefile --windowed --name "TAC_MP4_Studio" ^
--add-data "img;img" ^
--add-data "fonts;fonts" ^
--collect-data customtkinter ^
--collect-data tkinterdnd2 ^
--icon "img/icone.ico" ^
main.pyLe .exe se trouve dans dist/TAC_MP4_Studio.exe.
FFmpeg doit être installé séparément sur la machine cible.
| Lib | Rôle |
|---|---|
numpy |
Calcul vectorisé — audio et rendu |
opencv-python |
Pipeline vidéo frame par frame |
Pillow |
Traitement image · texte · polices |
librosa |
Analyse audio (STFT · onset · RMS) |
soundfile |
Chargement WAV/FLAC/OGG (fast path) |
scipy |
Resampling audio · interpolation |
customtkinter |
Interface dark theme moderne |
tkinterdnd2 |
Drag & drop fichiers (optionnel) |
requests |
Appels API YouTube (OAuth, upload résumable, lecture/édition) |
FFmpeg |
Encodage MP4 (NVENC / libx264) |
- Fini les exports Turbo qui plantent silencieusement : un preset (particules/fumée) introuvable ou corrompu ne fait plus échouer l'export — l'app retombe sur un réglage par défaut au lieu de s'arrêter
- Erreurs Turbo détaillées : le message d'erreur affiché dans la file n'est plus tronqué à 30 caractères, et le détail technique complet est désormais enregistré dans le journal (
%APPDATA%\DoktorP3st\TAC_MP4\logs\tac.log) pour un diagnostic rapide en cas de nouveau souci
- 📥 Import JSON de métadonnées (Upload dossier YouTube) : dépose un
.json(titre/description/tags par ID = nom de fichier) dans le dossier de vidéos, il est détecté et appliqué automatiquement — correspondance souple (accents/casse/séparateurs ignorés), résumé des vidéos/ID non associés, et bouton 📤 Exporter modèle JSON pour générer un squelette à remplir - 🎲 Aperçu aléatoire (Turbo V2) : ne retombe plus sur le même fichier deux fois de suite
- 📚 Mes vidéos (bibliothèque YouTube) : les miniatures se chargent désormais en parallèle — une chaîne avec beaucoup de vidéos ne reste plus bloquée de longues secondes sur « Chargement des vidéos... »
- Le champ Titre en mode Turbo V2 reste modifiable même quand le preset désactive le texte à l'écran (auparavant grisé dans ce cas)
- Le nom du fichier vidéo généré en Turbo V2 utilise désormais le Titre saisi plutôt que le nom du fichier audio d'origine — utile quand les noms de fichiers ne correspondent pas au titre voulu
- 📺 Chaînes multiples : gestion de plusieurs comptes YouTube depuis la même app — jeton, historique anti-doublon et date J+1 séparés par chaîne, sélecteur visible sur upload/bibliothèque/historique, ajout d'une nouvelle chaîne en un clic
- Préfixe / Suffixe de titre : listes réutilisables pour encadrer automatiquement le titre de chaque vidéo (ex.
El Cheshire - NomDuFichier), applicables à toute la file en un clic - 🧹 Nettoyer les publiés (Historique) : pour les créations déjà publiées sur YouTube, supprime vidéo + audio source et ne garde qu'une trace texte + vignette/pochette compressées — avec aperçu de l'espace libéré et confirmation avant suppression
- 🔄 Synchro YouTube dans la file de publication : récupère automatiquement la date de la dernière vidéo programmée sur la chaîne et règle la date de départ sur le lendemain, sans avoir à vérifier sur YouTube
- Historique de publication YouTube : nouvel onglet dans la page Historique (à côté de l'historique de génération existant) — liste des vidéos uploadées avec dates, lien direct vers YouTube, suppression individuelle
- ⚙ Réglages → 🗑 Données : purge sélective (historique de génération, historique YouTube, fichiers vidéo générés, journal technique), avec confirmation explicite des conséquences de chaque suppression avant d'agir
- Upload programmé vers YouTube depuis l'accueil : upload manuel (fichier) ou upload dossier (scan + anti-doublon nom+taille), file d'attente éditable (titre · tags · description · date), dates automatiques J+1, profils réutilisables (tags + description par défaut)
- Bibliothèque (📚 Mes vidéos) : parcours des playlists et vidéos déjà en ligne, filtre par visibilité (publique · non répertoriée · privée · programmée), édition complète (titre/description/tags/visibilité/date) écrite directement sur YouTube
- 🔀 Réorganiser (diversifier) : ré-planifie les vidéos privées programmées à venir pour éviter d'enchaîner plusieurs vidéos de la même playlist (algorithme glouton type Reorganize String), sans changer le pool de dates déjà utilisées ; aperçu obligatoire avant application
- Authentification OAuth2 Google par Device Authorization Grant (lien + code copiables individuellement), scope complet
youtube, ré-autorisation automatique proposée sur toute réponse 401/403 TAC.bat: mise à jour des dépendances (pip install) uniquement sirequirements.txta changé (hash SHA256), plus de réinstallation à chaque lancement
- Turbo V2 : nouveau mode d'export en série à partir d'un dossier. Les musiques et pochettes de même nom de fichier sont appariées automatiquement (
Titre.mp3+Titre.png), avec une image de fond commune optionnelle et un aperçu aléatoire. - Les vidéos Turbo V2 sont exportées directement dans le dossier source, nommées comme l'audio d'origine (pas de sous-dossier, pas de copie de la pochette) ; rendu écrit dans un dossier temporaire puis déplacé en une opération atomique pour ne jamais laisser de fichier partiel.
- Historique persistant : les paires déjà rendues (empreinte taille + date de modif) sont mémorisées entre deux lancements de l'appli et ne sont pas ré-exportées ; un bouton 🔁 permet de rescanner le dossier.
- Sécurités : vérification d'écriture du dossier, estimation d'espace disque libre, détection des noms ambigus (deux audios/images de même nom), anti-collision de nom de sortie, limite de longueur de chemin Windows.
- Écran de choix au clic sur ⚡ TURBO : Interface originale ou Turbo V2.
- Historique : bouton « 🎬 Convertir en Short » pour régénérer une création existante au format 1 min · 9:16 avec exactement les mêmes réglages visuels.
- Export vidéo en une seule passe : les frames sont pipées directement vers FFmpeg (
stdinrawvideo) au lieu de passer par un fichier temporairecv2.VideoWriter(mp4v) ré-encodé ensuite. Plus rapide, et supprime une perte de qualité intermédiaire. - Erreurs FFmpeg lues depuis un fichier log dédié (au lieu d'un pipe stderr non lu, qui pouvait bloquer)
- Waveform de la preview : le curseur de lecture se déplace sans redessiner toutes les barres (
_update_waveform_cursor), au lieu d'un redraw complet 5x/seconde app/ui/app.pydécoupé : extraction deTurboMixin(turbo.py) etExportMixin(export_ui.py) — 2237 → ~1460 lignes- Exceptions silencieuses de
audio.py/exporter.pydésormais tracées (niveau debug) danstac.log - Bornes de version ajoutées dans
requirements.txt - Correctif : la preview restait noire (pochette et effets absents, seul le spectre s'affichait) — imports partagés (
PREVIEW_W,FPS,RenderSettings...) supprimés par erreur lors du découpage deapp.py, restaurés
- Onglet ⚡ refactorisé : bibliothèque unifiée intégrés + perso dans une seule liste
- Presets intégrés cachables individuellement (✕) et restaurables en un clic
- Badge intégré / perso · bande couleur · favoris (★) remontent en tête
- Modes d'export redessinés en grille 2×2 : icône + résolution + badge durée
- Sélection d'export colorée par mode (chaque mode a sa propre couleur de bordure)
- Taille de police ajustable par curseur
- Sous-titre indépendant
- Ombre paramétrable : intensité · couleur · décalage XY
- Nouveau mode fond
Image perso: image de fond indépendante de la pochette album - Couche d'erreurs centralisée (
errors.py) avec 8 exceptions métier typées - Logger rotatif (
logger.py) — trace complète danstac.log
- Cache LRU sur
compute_audio_features— refresh preview instantané - Cache disque vinyle (~12 ms/frame économisés)
- Vectorisation numpy de l'oscilloscope
- Redimensionnement preview BILINEAR (~2.5 ms/tick)
- 3 couleurs indépendantes par bande (bass · mid · high)
- Flash couleur synchronisé sur les kicks
- Vinyle rotatif réactif aux beats
- Choix image pochette ou noir classique
- Fond dégradé avec color pickers
- Historique des exports avec miniatures
- Mode plein écran preview
Développé par DoktorP3st