Vous n’avez pas besoin d’images. Vous avez besoin de retrouver les vôtres.
Vous connaissez le sentiment : 2 To de rushs, d’animes, de clips — et 40 minutes pour retrouver les 0,8 seconde qui tombent juste sur le drop. Le génératif promet d’inventer, mais invente de travers, coûte une fortune en GPU et pose des questions de droits à chaque frame. Le Remix Studio fait l’inverse : il rend votre disque dur interrogeable.
Pas une image n’est inventée. Le système cherche, note chaque plan, puis assemble en FFmpeg. Résultat : toujours vrai, toujours à vous, rendu en secondes — pas en minutes.
Pour qui, concrètement ?
- Monteurs Shorts/TikTok — sortez dix variations 9:16 d’un même son sans rouvrir la timeline.
- AMV & fan edits — “Megumi sombre + glow violet” devient un MP4 en 30 secondes.
- Archivistes — posez “plans de nuit sous la pluie” et laissez la base répondre.
| Génératif | Remix Studio | |
|---|---|---|
| Coût / vidéo | 0,20–2 $ GPU | ~0 $ |
| Temps | 2–10 min | 10–40 s |
| Fidélité | Aléatoire | Source |
| Droits | Flous | Vos fichiers |
Ce n’est pas un assistant qui suggère. C’est la table qui coupe à votre place — et recommence si le score ne suit pas.
Offline : le muscle. Online : le cerveau.
La séparation est volontaire : le lourd, une fois ; le léger, à la demande. C’est ce qui le rend crédible sur un laptop.
Indexation
Le muscle, en local
- Dépôt dans
data/library/ - Découpe PySceneDetect
- Audio / couleurs / mouvement
- YOLO → Florence-2 (séquentiel)
- SigLIP → LanceDB
0,5–2 min / vidéo · incrémental : on ne retraite jamais deux fois.
Studio
Le cerveau, déporté
- Intent → JSON
- Retriever → 50
- Analyzer → 15
- Planner → timeline
- Editor → FFmpeg
- Validator → boucle si < 70
10–40 s · 0 $ en repli local, ~0,01 $ cloud.
Le muscle ne rencontre le cerveau qu’en un point : LanceDB. Tout le reste est remplaçable.
Six rôles, un état partagé
Chaque agent est un nœud StateGraph avec une responsabilité unique. L’état StudioState circule et s’enrichit. L’arête Validator → Planner permet l’auto-correction.
La stack, sprint par sprint
- Découpe — S1
- PySceneDetect (seuil 27) + FFmpeg.
shot_01.mp4… - Audio — S2
- Librosa : BPM, beats, drops, énergie, sections.
- Couleurs & mouvement — S2
- OpenCV : keyframe milieu, HSV, Optical Flow (pan/zoom/shake).
- Vision — S3
- YOLO11 + Florence-2 — jamais ensemble en mémoire.
- Embeddings — S4
- SigLIP 768-d cross-modal. Repli déterministe si besoin.
- Base — S4
- LanceDB hybride.
- Orchestration — S5-9
- LangGraph + 1 agent = 1 clé.
- Mémoire & CLI — S10
- Style Memory JSON + Typer/Rich.
De la vidéo à la base interrogeable
Relancer index-all ne retraite que les nouveaux fichiers.
- 1
Découpe
ContentDetector (seuil 27, mini 0,6 s) →
Shot. Exports FFmpeg limités à 2 en parallèle pour ne pas saturer. - 2
Keyframes, couleurs, mouvement
Milieu de shot → HSV + Optical Flow →
static / pan / zoom / shake. AlternativeInternVideo2si GPU. - 3
Audio
Librosa à 22 050 Hz : BPM, force de chaque beat, drops, courbe d’énergie, sections intro/build/drop.
- 4
Vision séquentielle
YOLO11n d’abord (~200 Mo) sur toutes les keyframes, déchargé, puis Florence-2-base (~1 Go) si demandé. Option
--no-captionpour sauter Florence.Florence demande 8–12 Go libres. En dessous : OOM → mode léger.
- 5
Embeddings → LanceDB
SigLIP patch16-224 (768-d). Repli déterministe : HSV + hashing MD5 — rapide, sans téléchargement.
# Léger, 8 Go RAM — garde YOLO, saute Florence
.venv312/bin/python -m src.cli.main index-all --reset --no-caption
# Complet — YOLO + Florence + SigLIP
.venv312/bin/python -m src.cli.main index-all --reset
# 100% offline — aucun modèle
.venv312/bin/python -m src.cli.main index-all --reset --no-vision
# Ensuite, incrémental
.venv312/bin/python -m src.cli.main index-allDe la phrase au MP4
Intent — le traducteur
Llama 70B · repli regex“edit sombre avec flashs” → Intent{ mood, character, color, effects[], target_bpm, duration }. Injecte votre preferred_mood si mémoire.
Entrée : promptSortie : Intent
Retriever — le bibliothécaire
Llama 8B · repli vecteurHybride LanceDB : embedding SigLIP + filtres (objets, couleur). 50 candidats. Si < 12 après filtre, complète sans filtre.
Entrée : Intent + LanceDBSortie : 50
Analyzer — le juge
Llama 70B · scoring pondéréNote (style, mouvement, couleur, rareté) et garde 15. Sans LLM : distance vecteur + tags.
Entrée : 50Sortie : 15
Planner — le cerveau ★
Claude 3.5 · repli déterministeLe cœur. Le LLM ordonne pour raconter ; le moteur cale sur les beats (calme → 1,8 s, drop → 0,5 s), pace slow/fast, anti-répétition, fenêtres glissantes, effets sur intensité.
Entrée : 15 + AudioSortie : Timeline
Editor — l’exécutant
DeepSeek · templateUne seule commande filter_complex : trim, crop 9:16, vitesse, fade/flash/zoom, concat, mix audio → data/output/*.mp4.
Entrée : TimelineSortie : MP4
Validator — le contrôleur
Llama 8B · métadonnéesffprobe → durée, fluidité, sync → score /100. < 70 et < 3 tentatives → retour Planner.
Entrée : MP4Sortie : Validation + route
{
"entries": [
{ "start": 0.0, "end": 1.2, "clip": "data/shots/shot_03.mp4", "source_in": 0.0, "source_out": 1.2, "effect": "fade" },
{ "start": 1.2, "end": 2.1, "clip": "data/shots/shot_11.mp4", "source_in": 0.5, "source_out": 1.4, "effect": "zoom" },
{ "start": 2.1, "end": 3.0, "clip": "data/shots/shot_07.mp4", "source_in": 0.0, "source_out": 0.9, "effect": "flash" }
], "total_duration": 15.0, "width": 1080, "height": 1920, "fps": 30
}Ce qui est stocké
LanceDB — ShotRecord
id·video_path·shot_indexshot_start / shot_end / duration / fpssiglip_embedding: Vector(768)description·objects[]·effects[]dominant_color / brightness / saturationmotion_score / camera_motion
Style Memory
preferred_moodpreferred_bpmavg_durationfavorite_effects[3]avg_shot_len
Consultée par Intent & Planner.
StudioState
user_prompt·music_pathintent·candidates[50]·selected[15]audio·timelineoutput_path·validation·attempts
AudioAnalysis
- BPM ·
beat_positions[]·beat_strengths[] drops[]·onsets[]·downbeats[]energy_times[] / values[]sections[] {start,end,intensity}
Sur un laptop. Mieux sur une station.
Un seul modèle en mémoire à la fois, LLMs déportés. Voici la réalité.
| Minimal offline | Recommandé léger ★ | Optimal complet | Pro GPU | |
|---|---|---|---|---|
| CPU | Dual-core | Quad-core | 6+ cœurs | 8+ cœurs + CUDA |
| RAM | 4 Go | 8 Go | 16 Go | 32 Go |
| RAM libre Florence | — | — | 8–12 Go | 12 Go+ / VRAM 8 Go+ |
| GPU | Aucun | Aucun | Optionnel | NVIDIA 8 Go+ |
| Stockage | 2 Go + vidéos | 5 Go + | 10 Go + | 50 Go+ |
| Python | 3.12 | 3.12 | 3.12 | 3.12 |
| Modèle | Poids | RAM | Vitesse CPU |
|---|---|---|---|
| YOLO11n | 6 Mo | ~200 Mo | ~80 ms |
| Florence-2-base | ~1 Go | ~1,2 Go | ~1,5 s |
| SigLIP | ~400 Mo | ~600 Mo | ~300 ms |
| LanceDB | 3 Ko / vecteur | Disque | < 50 ms / 10k |
Pourquoi ça ne rame pas
SequentialModelLoader: un seul modèle en RAM.- FFmpeg limité à 2 coupes en parallèle.
- LLMs hors machine : 0 Mo VRAM.
- Indexation incrémentale.
Trois modes, un flag
100% offline
--no-vision + --offlineAucun téléchargement. Repli déterministe. Idéal CI.
Léger — YOLO seul ★
--no-captionYOLO + SigLIP, pas Florence. 90% qualité pour 30% RAM.
Complet
(aucun flag)YOLO + Florence + SigLIP. Le max, si 16 Go+ ou GPU.
Huit paliers, du laptop au studio
GPU ×3–5 · 0 $ Kaggle
DEVICE=cuda. 100 vidéos : 1 h → 15 min. Notebook Kaggle fourni.
YOLO s/m/l/x +25–40% précision
YOLO_MODEL=yolo11l.pt — armes, véhicules, animaux rares.
Florence-large & SigLIP-large +15–25%
Captions riches, embeddings 1152-d. ~2,5 Go, 16 Go+.
InternVideo2 GPU
MOTION_BACKEND=internvideo2 — tracking, action.
LLMs cloud ~0,02 $ / montage
Groq gratuit + Claude 3.5 pour le Planner. 1 agent = 1 clé.
10k+ vidéos scale
LanceDB 100k shots, <100 ms. Au-delà : partition ou cloud.
Effets pro visuel
Glow, shake, xfade, LUT — un seul fichier : editor.py.
API ~15–30 €/mois
FastAPI POST /remix + file d’attente.
Moins cher qu’une heure de monteur
| Config | Coût / 15s |
|---|---|
| Sans clés | 0,00 $ |
| Groq gratuit | 0,00 $ |
| Full Claude+DeepSeek | 0,02–0,05 $ |
1 agent = 1 clé
- Planner → Claude 3.5
- Editor → DeepSeek
- Intent/Analyzer/Retriever/Validator → Groq
Solo : 0 $. 50/jour : ~1–2 $. Pro : ~30 $/mois.
Ce que la V1 ne fait pas
Limites
- Pas de génération — si vous n’avez pas le plan, il ne l’invente pas.
- Effets basiques : zoom/flash/fade.
- Recherche offline couleur-dominante.
- Validation heuristique.
Suite
- CLIP esthétique
- Whisper (paroles)
- Face clustering
- xfade + LUT
- API REST
Ce que ça donne
Trois montages — même bibliothèque, trois rythmes. Chaque coupe est posée sur un beat, chaque effet sur un drop. Vertical 9:16, 30 fps, CRF 20.
Cliquez pour lire. Double-clic pour plein écran. La galerie boucle sur tous les .mp4 de site/videos/.
Votre premier montage en 5 minutes
- 0
Prérequis
ffmpeg -versiondoit répondre. - 1
Installer
uv venv --python 3.12 .venv312 source .venv312/bin/activate uv pip install -r requirements.txt cp .env.example .env - 2
Vérifier
.venv312/bin/python -m src.cli.main doctor - 3
Indexer
mkdir -p data/library && cp vos_videos/*.mp4 data/library/ .venv312/bin/python -m src.cli.main index-all --reset --no-caption - 4
Monter
.venv312/bin/python -m src.cli.main remix "AMV sombre avec flashs et zoom" \ --music data/demo_music.wav --out data/output/mon_edit.mp4
Tests
.venv312/bin/python -m pytest -qArborescence
src/indexer/ db/ agents/ memory/ cli/
data/library/ data/lancedb/ data/output/Questions fréquentes
Pas de GPU ?—
Oui. CPU + mode léger sur 8 Go. Le GPU accélère seulement l’indexation (×3–5), pas le montage.
Pas de clés API ?—
Oui. Repli déterministe local — 0 $. Ajoutez Groq gratuit quand vous voulez plus de finesse.
Combien de vidéos ?—
~100k shots en local, recherche <100 ms. Au-delà, partition ou LanceDB Cloud.
Florence OOM (exit 137) ?—
En dessous de 8–12 Go libres : passez en --no-caption ou utilisez Kaggle (notebook fourni).
Python 3.14 ?—
Florence exige 3.12 — tokenizers 0.19 ne compile pas en 3.14.
Sortie 16:9 au lieu de 9:16 ?—
Changez RENDER_WIDTH / RENDER_HEIGHT dans .env (ex. 1920×1080).
Besoin de musique ?—
Non. Sans musique, le Planner génère une grille régulière à 120 BPM (ou target_bpm).
À vous de remixer.
data/library/ → index-all → remix à volonté. Le studio apprend votre style à chaque export validé.
V1 Sprints 1→10 — août 2026