Style Vidéo Cinematic Beats
Philosophie Fondamentale
Les visuels dictent le rythme. L'audio suit. Les animations et scènes ASCII se déroulent à leur durée naturelle — elles ne sont PAS tronquées, accélérées, ou figées sur les dernières trames pour correspondre à la longueur audio. Le silence entre les rythmes est un choix de conception intentionnel, pas un vide à combler.
- TTS : Une phrase par clip. Rapport signal-bruit maximal. Pas de narration de remplissage.
- Visuels : Durée naturelle complète. Laissez les animations respirer.
- Coupures : Coupures franches uniquement. Pas de fondus.
- Musique : Pistes fournies par l'utilisateur avec baisse automatique pendant les sections parlées.
- Points de contrôle : Après chaque phase de production, livrer les assets à l'utilisateur pour validation avant de continuer.
Structure du Projet
~/videos/[nom-du-projet]/
project.md # Document vivant — storyboard, décisions, notes de révision
beats/ # Assets individuels des rythmes
beat-01/
visual.mp4 # Visuel généré (image avec mouvement ou animation)
audio.mp3 # Clip TTS pour ce rythme (MP3 uniquement — voir Règles Critiques)
note.txt # Description en une ligne de ce que montre le rythme
beat-02/
...
music/ # Pistes musicales de fond fournies par l'utilisateur
output/ # Rendu intermédiaire et final
Phase 1 : Script des Rythmes
Créer project.md avec la répartition des rythmes. Chaque rythme = un visuel + une phrase TTS.
Écrire les Rythmes
Règles TTS :
- UNE phrase par rythme. Point.
- Rapport signal-bruit maximal — chaque mot mérite sa place.
- Si une pensée nécessite deux phrases, c'est deux rythmes.
- Objectif : 5-15 mots par clip. Plus court est mieux.
- Pas de remplissage d'introduction ("Alors...", "Regardons maintenant..."). Allez droit au but.
Règles visuelles :
- Décrivez ce que montre le visuel — pas combien de temps il dure.
- La durée du visuel est déterminée par son achèvement naturel, PAS par la longueur TTS.
- Coupures d'image : image statique avec mouvement Ken Burns (zoom/dézoom lent). Durée : 4-6s minimum.
- Coupures animées (p5js/manim/ascii) : l'animation complète se joue. Quel que soit le temps nécessaire — 8s, 12s, 15s.
- La durée du rythme = max(durée_visuelle, durée_audio) + pause.
Modèle de rythme dans project.md :
# [Nom du Projet]
## Concept
[Un paragraphe — de quoi parle cette vidéo et l'ambiance recherchée]
## Musique
- Piste : [nom du fichier ou description de la musique que l'utilisateur fournira]
- Ambiance : [description]
## Rythmes
### Rythme 01
**Visuel :** [type : image | p5js | manim | ascii] — [description/consigne]
**TTS :** "Une phrase percutante."
**Statut :** [ ] visuel [ ] audio [ ] approuvé
### Rythme 02
...
## Notes
[Journal des décisions, révisions, retours utilisateur]
Types de Coupures
| Type | Outil | Durée | Idéal pour |
|---|---|---|---|
image | image_generate + Ken Burns | 4-6s | Photos, scènes, portraits, plans d'établissement |
p5js | compétence p5js | Naturelle (8-15s) | Art génératif, particules, data viz, champs de flux |
manim | compétence manim-video | Naturelle (8-20s) | Animations mathématiques, diagrammes, explications techniques |
ascii | compétence ascii-video | Naturelle (6-12s) | Esthétique terminal, informatique rétro, sujets de hacking |
caption | ffmpeg drawtext | 4-8s | Texte TTS centré sur fond sombre — attire l'attention sur les mots |
CRITIQUE : Avant de produire un rythme p5js/manim/ascii, chargez la compétence avec skill_view(name) d'abord. Ces compétences contiennent des palettes de marque, des règles typographiques et des schémas d'implémentation à suivre exactement.
Phase 2 : Porte d'Approbation du Script
STOP. Présenter project.md à l'utilisateur. Ne pas générer d'assets avant approbation explicite.
Mettre à jour la section Notes de project.md avec l'horodatage de l'approbation.
Phase 3 : Générer les Visuels
Générer tous les assets visuels selon leur type. Enregistrer sous beats/beat-XX/visual.mp4.
Rythmes d'image (Ken Burns filtré VHS)
- Générer l'image via
image_generate - Appliquer le filtre VHS à l'image (grain, lignes de balayage, vignette, aberration chromatique) :
python3 scripts/vhs-filter.py \
--input beat-XX-image.png \
--output beat-XX-vhs.png \
--seed 42 \
--intensity 1.0
Prérequis : pip install numpy Pillow (numpy pour les effets de tableau, Pillow pour l'entrée/sortie d'image).
Niveaux d'intensité : 0.7 (subtil — grain + vignette seulement), 1.0 (standard — tous les effets), 1.5 (fort — aberration chromatique marquée, lignes de balayage visibles). Par défaut 1.0.
- Appliquer le mouvement Ken Burns à l'image filtrée VHS pour créer le MP4 :
ffmpeg -loop 1 -i beat-XX-vhs.png -t 5 \
-vf "zoompan=z='min(zoom+0.001,1.3)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=125:s=1920x1080:fps=25" \
-c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4
Pourquoi VHS d'abord, puis Ken Burns ? Le filtre zoompan brouillerait le grain et les lignes de balayage. Appliquez VHS à l'image statique d'abord, puis ajoutez le mouvement par-dessus. Le mouvement Ken Burns sur l'image filtrée VHS crée une sensation analogique vécue — comme regarder de vieilles images à travers un CRT légèrement dégradé.
Rythmes animés (p5js/manim/ascii)
Charger la compétence concernée d'abord, puis générer. Enregistrer la sortie sous beats/beat-XX/visual.mp4.
Résolution : Tous les visuels doivent être en 1920x1080 à 25ips. Mettre à l'échelle les sorties manim :
ffmpeg -y -i raw-manim.mp4 \
-vf "scale=1920:1080:flags=lanczos,setsar=1:1,fps=25" \
-c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4
Appels image_generate par lots de 6. En cas de signalement, reformuler de manière neutre et réessayer une fois.
Référence du Filtre VHS
Le filtre VHS (scripts/vhs-filter.py) applique ces effets à une seule image :
| Effet | Ce qu'il fait | Résultat visuel |
|---|---|---|
| Aberration chromatique | Décalage des canaux R/B (0-2px) | Franges colorées sur les bords, comme un CRT mal aligné |
| Bruit analogique | ±8 de grain par canal (échelonné par intensité) | Texture cinématographique dans les ombres et les tons moyens |
| Lignes de balayage | Toutes les 4èmes lignes obscurcies à 96% | Superposition de la grille de phosphores CRT |
| Vignette CRT | Assombrissement des bords (15-35% selon l'intensité) | Coins d'écran arrondis, comme une vieille télé |
Pour les images : Tous les effets s'appliquent une fois avec une seule graine aléatoire. L'aberration chromatique et le bruit sont visibles ; la gigue et les pistes de suivi sont subtiles car il n'y a qu'une seule trame.
Remarque : Ce filtre est réservé aux images — il ne traite pas l'entrée vidéo. Pour obtenir du mouvement, appliquez le filtre à une trame statique d'abord, puis ajoutez Ken Burns/zoompan par-dessus.
Phase 3.5 : Porte de Validation des Visuels
STOP. Envoyer chaque clip visuel à l'utilisateur pour validation.
Inclure la capture d'écran ou le MP4 avec les chemins MEDIA:. Les présenter numérotés :
Rythme 01 : [chemin MEDIA] — [brève description]
Rythme 02 : [chemin MEDIA] — [brève description]
...
Demander : "Des modifications nécessaires avant de passer à l'audio ?"
Ne pas générer le TTS tant que l'utilisateur n'a pas approuvé les visuels. Enregistrer les retours dans les Notes de project.md.
Si des changements sont demandés, régénérer uniquement les rythmes concernés et refaire le point de validation.
Phase 4 : Générer l'Audio TTS
Générer TOUS les clips TTS — un par rythme. Utiliser l'outil text_to_speech avec output_path en .mp3. Enregistrer sous beats/beat-XX/audio.mp3.
CRITIQUE : Toujours utiliser le format MP3 pour l'audio. OGG a des problèmes de compatibilité de codec avec la livraison Telegram et les opérations de concaténation ffmpeg. Configurer le fournisseur TTS sur OpenAI avec sortie MP3.
Règles :
- Une phrase par appel. Pas de concaténation.
- Mesurer la durée de chaque clip avec ffprobe après génération.
- Enregistrer les durées dans project.md à côté de chaque rythme.
ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio.mp3
Phase 4.5 : Porte de Validation Audio
STOP. Présenter les clips audio à l'utilisateur.
Appliquer le filtre vocal (obligatoire)
Appliquer la chaîne de bitcrush sec/humide à chaque clip TTS — c'est notre signature vocale. Voir references/dry-wet-bitcrush.md pour la technique complète et les pièges.
Deux approches disponibles :
A) Mix statique (simple, cohérent) :
# Étape 1 : Créer la version crushée via un intermédiaire wav (conserve la durée)
ffmpeg -y -i beats/beat-XX/audio.mp3 \
-af "aresample=resampler=soxr:osr=2000,aformat=sample_fmts=u8,aresample=resampler=soxr,lowpass=f=2500" \
temp-crushed.wav
# Étape 2 : Mélanger sec + humide avec colle de compression
ffmpeg -y -i beats/beat-XX/audio.mp3 -i temp-crushed.wav \
-filter_complex "[0:a]volume=0.7[dry];[1:a]volume=0.3[wet];[dry][wet]amix=inputs=2:duration=first:normalize=0,acompressor=threshold=0.05:ratio=4:attack=10:release=100[out]" \
-map "[out]" beats/beat-XX/audio-filtered.mp3
rm temp-crushed.wav
B) Mix dynamique (effet de dégradation du signal — préféré) :
Utilise le script Python (scripts/vibey-mix.py) avec sur-échantillonnage par maintien d'ordre zéro pour un bitcrush authentique à la bonne hauteur.
Prérequis : pip install numpy pydub (numpy pour le traitement de tableaux, pydub pour la lecture/écriture MP3).
Paramètres verrouillés (variante dec5-bit8) :
- Décimation : 5× (supprime un échantillon sur 5, puis répète via maintien d'ordre zéro)
- Quantification : 8 bits (constante)
- Ligne de base sec/humide : 80% sec / 20% humide
- Motif de creux : Environ toutes les 1,2s, le sec chute à ~35%, l'humide monte à ~65% (durée ~0,25s)
- Trémolo uniquement sur l'humide : Onde triangulaire à 4 Hz, profondeur 70% (l'humide pulse entre 30-100%)
- Retard slapback : 80ms à -18dB (~0,12 de volume), appliqué au mix final
python3 scripts/vibey-mix.py beats/beat-XX/audio.mp3
cp beats/beat-XX/audio-dynamic.mp3 beats/beat-XX/audio-filtered.mp3
Détail de la chaîne : Signal sec propre superposé à des artefacts numériques extrêmes (décimation 5×, quantification 8 bits via sur-échantillonnage par maintien d'ordre zéro), creux périodiques augmentant le niveau humide pour un effet de "transmission qui se dégrade", trémolo sur le signal humide pour des pulsations rythmiques, et retard slapback pour l'espace. Garder la structure de la chaîne intacte — n'ajuster les paramètres individuels que si nécessaire.
Utiliser audio-filtered.mp3 dans toutes les phases suivantes. Garder l'original audio.mp3 pour référence.
Enregistrer les décisions dans les Notes de project.md.
Phase 5 : Composer les Rythmes
Pour chaque rythme, fusionner le visuel + l'audio avec une coupure franche (pas de transition). La durée du rythme est déterminée par le plus long entre le visuel et l'audio.
Si visuel >= audio :
L'audio joue sous la totalité du visuel. Aucun remplissage nécessaire.
ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
-c:v libx264 -pix_fmt yuv420p -c:a aac \
-shortest -r 25 output/beat-XX-composed.mp4
Si audio > visuel :
Le visuel tient sa dernière trame pour remplir le temps restant. Utiliser tpad sur la vidéo :
AUDIO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio-filtered.mp3)
ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
-vf "tpad=stop_mode=clone:stop_duration=$AUDIO_DUR" \
-c:v libx264 -pix_fmt yuv420p -c:a aac \
-t $AUDIO_DUR -r 25 output/beat-XX-composed.mp4
Si aucun filtre audio n'a été appliqué, utiliser audio.mp3 au lieu de audio-filtered.mp3.
Pause entre les rythmes
Ajouter une courte trame noire entre les rythmes pour la respiration :
ffmpeg -f lavfi -i color=c=black:s=1920x1080:d=0.15:r=25 \
-c:v libx264 -pix_fmt yuv420p output/pause-XX.mp4
Rythmes de légende ASCII (focus sur les mots)
Lorsque la narration elle-même est le point focal — pas le visuel — utiliser un rythme de style ASCII avec le texte TTS centré à l'écran. Les marquer dans project.md comme type [caption] :
Modèle de rythme :
### Rythme 03 [caption]
**Visuel :** légende ASCII — texte centré, fond sombre, esthétique terminal subtile
**TTS :** "Les mots exacts qui apparaissent à l'écran."
**Statut :** [ ] visuel [ ] audio [ ] approuvé
Générer avec ffmpeg drawtext sur un fond noir/sombre avec une police monospace et le texte en couleur ALLMIND or (#C5A55A) :
TEXT="Votre phrase TTS ici"
ffmpeg -f lavfi -i color=c=black:s=1920x1080:d=6:r=25 \
-vf "drawtext=text='${TEXT}':fontsize=42:fontcolor='#C5A55A':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:x=(w-tex