Add Kaika video-clip pipeline spec#1
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the specification document for Kaika, a local application designed to generate music videos by driving a fluid simulation with audio analysis and styling it via a video diffusion model. The review feedback focuses on technical refinements to the proposed pipeline: addressing potential temporal drift from non-integer audio-to-video hop lengths, optimizing remote GPU transfers by compressing frame sequences into video containers, using fluid simulation metrics instead of styled frame luminance for audio synchronization checks, and adding a default fallback prompt to the recipe schema.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| **in** `track.wav` / `track.mp3` · **out** `score.json` | ||
|
|
||
| Analyse hors-ligne complète avec `librosa`. Le `hop_length` est calé sur le framerate vidéo cible (`hop = sr / fps`) pour que chaque frame vidéo ait sa ligne de données audio, sans interpolation. |
There was a problem hiding this comment.
Le calcul hop = sr / fps peut donner un nombre non entier (par exemple, 44100 / 24 = 1837,5). Comme hop_length doit être un entier pour les fonctions de traitement de signal (comme STFT dans librosa), l'arrondir (ex. à 1838 ou 1837) introduira une dérive temporelle cumulative entre l'audio et la vidéo au fil du morceau. Il est préférable de spécifier qu'il faut soit adapter le taux d'échantillonnage (ex. 48000 Hz pour 24 fps donne un hop exact de 2000), soit interpoler/ajuster dynamiquement le pas pour éviter tout décalage.
| Analyse hors-ligne complète avec `librosa`. Le `hop_length` est calé sur le framerate vidéo cible (`hop = sr / fps`) pour que chaque frame vidéo ait sa ligne de données audio, sans interpolation. | |
| Analyse hors-ligne complète avec librosa. Le hop_length doit être un entier calé au plus près du framerate vidéo cible (hop = int(sr / fps)). Attention aux taux d'échantillonnage et framerates qui ne se divisent pas parfaitement (ex: 44100 Hz et 24 fps), car l'arrondi cumulera une dérive temporelle au fil du morceau (à compenser par interpolation ou en imposant des couples sr/fps compatibles comme 48000 Hz et 24 fps). |
| - **Prompt schedule auto-générée** depuis `score.json` + recette : chaque section musicale mappe vers un prompt (« bourgeons sombres, macro » sur l'intro, « éclosion massive de pivoines, pétales en suspension » sur le drop). | ||
| - **Seed fixe** par rendu, pour la reproductibilité et la comparaison d'itérations. | ||
|
|
||
| **Infra** : GPU loué à l'heure (Vast.ai / RunPod, RTX 5090 ou A100 selon la taille du modèle), provisionné par un script (image Docker avec ComfyUI + modèles, montage du dossier `control/`, rendu, rapatriement). Ordre de grandeur attendu : quelques heures de GPU par clip de 3 minutes, soit quelques euros par rendu complet. Toutes les itérations esthétiques se font sur des extraits de 10 s. |
There was a problem hiding this comment.
Le transfert de milliers de frames PNG individuelles (depth, canny, flow, et frames stylisées en retour) pour un clip de 3 minutes (~4300 frames) représentera plusieurs gigaoctets de données. Sur une connexion internet domestique standard, l'upload et le download de ces fichiers individuels via l'API de Vast.ai/RunPod constituera un goulot d'étranglement majeur. Il est fortement recommandé de compresser ces séquences de frames dans un conteneur vidéo temporaire à haut débit (ex: MP4 avec encodage sans perte ou quasi-sans perte comme H.264/HEVC en YUV420p/YUV444p) pour le transfert, puis de les extraire sur le GPU distant. Cela réduira drastiquement la taille des transferts et le temps de traitement.
|
|
||
| - **Interpolation RIFE** si E4 a généré à 12 ou 16 fps (économie de GPU) : remontée à 24 ou 48 fps. | ||
| - **Upscale** Real-ESRGAN ou équivalent vers 2048², puis crop/letterbox vers le format de diffusion (carré pour Instagram, 16:9 sinon). | ||
| - **Mux ffmpeg** de l'audio original, avec vérification automatique de l'offset (corrélation entre l'enveloppe RMS et la luminance moyenne des frames : si la sync dérive, ça se mesure). |
There was a problem hiding this comment.
La corrélation directe entre l'enveloppe RMS de l'audio et la luminance moyenne des frames stylisées (E4) risque d'être très peu fiable, car la luminance dépend fortement du prompt et du style visuel de la recette (qui peut être sombre lors d'un drop intense). Pour mesurer précisément une dérive de synchronisation, il est beaucoup plus fiable de corréler l'enveloppe RMS de l'audio avec l'énergie cinétique ou la densité globale de la simulation de fluide (E2), qui est directement et déterministement pilotée par les signaux audio.
| - **Mux ffmpeg** de l'audio original, avec vérification automatique de l'offset (corrélation entre l'enveloppe RMS et la luminance moyenne des frames : si la sync dérive, ça se mesure). | |
| - **Mux ffmpeg** de l'audio original, avec vérification automatique de l'offset (corrélation entre l'enveloppe RMS de l'audio et l'énergie cinétique ou la densité globale de la simulation de fluide E2, beaucoup plus fiable et déterministe que la luminance des frames stylisées). |
| prompts: | ||
| base: "macro photography, botanical, dark background, soft light" | ||
| intro: "closed flower buds emerging from black water, mist" | ||
| build: "buds swelling, petals straining, tension" | ||
| drop: "explosive bloom of peonies, petals suspended mid-air" | ||
| outro: "petals dissolving back into dark water" |
There was a problem hiding this comment.
Il serait utile de clarifier comment les prompts spécifiques aux sections sont combinés avec le prompt base (par exemple, s'il s'agit d'un préfixe/suffixe systématique) et quel est le comportement par défaut si une section détectée dans score.json (ex: verse) n'a pas de clé correspondante dans le dictionnaire prompts de la recette. L'ajout d'une clé de repli (ex: default) permet de sécuriser le pipeline.
| prompts: | |
| base: "macro photography, botanical, dark background, soft light" | |
| intro: "closed flower buds emerging from black water, mist" | |
| build: "buds swelling, petals straining, tension" | |
| drop: "explosive bloom of peonies, petals suspended mid-air" | |
| outro: "petals dissolving back into dark water" | |
| prompts: | |
| base: "macro photography, botanical, dark background, soft light" # Modificateur global appliqué à chaque section | |
| intro: "closed flower buds emerging from black water, mist" | |
| build: "buds swelling, petals straining, tension" | |
| drop: "explosive bloom of peonies, petals suspended mid-air" | |
| outro: "petals dissolving back into dark water" | |
| default: "botanical organic forms, abstract motion" # Repli si le label de section est inconnu |
…gy sync, default prompt
Ajoute
project_ideas/kaika.md: la spécification v0.2 de Kaika 開花, convertie depuis la source HTML vers le format markdown auto-suffisant utilisé par les autres specs du dossier (llm-arena.md,personal-memory-wiki.md).Kaika est une app locale qui transforme un morceau de musique en clip vidéo via un pipeline en cinq étages : analyse audio (librosa) → simulation de fluides (Taichi) → signaux de contrôle (depth/canny/flow) → métamorphose vid2vid (ComfyUI/Wan 2.2) → post-production (RIFE/upscale/mux), le tout piloté depuis une interface web locale lancée en une commande.
Contenu préservé fidèlement (texte original en français) : vision, architecture, les cinq étages, format recette YAML, l'application, stack & structure du repo, jalons M0–M5, risques et questions ouvertes.
Generated by Claude Code