Monteur de Reels Cinématique
Transformez un dossier de plans bruts + une piste musicale en un reel cinématique de 15 à 45 s, au format 9:16, synchronisé sur le rythme. Tout le montage est effectué avec FFmpeg depuis la ligne de commande. Le plan de montage est stocké dans une liste modifiable (edl.json) pour pouvoir modifier et re-rendre sans repartir de zéro.
0. Règles strictes
- NE JAMAIS modifier ou supprimer quoi que ce soit dans
raw/. Écrivez toutes les sorties danswork/etout/. - La musique doit être fournie par l'utilisateur (sous licence / libre de droits). Si le dossier
music/est vide, demandez un fichier — ne téléchargez pas de musique protégée par des droits d'auteur. - Montrez à l'utilisateur le plan de montage (étape 4) et obtenez son accord avant le rendu final.
- Privilégiez les coupes franches sur les battements. Utilisez les transitions avec parcimonie (max 2–3 par reel).
1. Vérification des prérequis
ffmpeg -version && ffprobe -version
python3 -c "import librosa, numpy" || pip install librosa numpy soundfile
Si FFmpeg est manquant, demandez à l'utilisateur de l'installer (Windows : winget install ffmpeg, Mac : brew install ffmpeg, Linux : sudo apt install ffmpeg) et arrêtez-vous.
2. Structure des dossiers
projet/
raw/ # clips de la caméra (lecture seule)
music/ # une piste musicale
luts/ # éventuel fichier .cube pour l'étalonnage
work/ # vignettes, segments, edl.json, beats.json
out/ # rendus finaux (reel_v1.mp4, reel_v2.mp4 ...)
3. Inventaire et examen des rushes
Pour chaque clip, enregistrez la durée, la résolution, les images par seconde (fps) et l'orientation :
ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate,codec_type -of json raw/CLIP.mp4
Générez un planche-contact par clip (une image toutes les 2 secondes) et VISUALISEZ-la avec l'outil Read pour savoir ce que contient chaque plan :
ffmpeg -y -i raw/CLIP.mp4 -vf "fps=1/2,scale=320:-1,tile=4x3" -frames:v 1 work/thumbs/CLIP.jpg
Étiquetez chaque moment utilisable : type de plan (large / moyen / gros plan / détail), sujet, mouvement, qualité (net, stable, bien éclairé), et s'il est capable de ralenti (source ≥ 50 fps).
4. Construire l'histoire (plan de montage)
Structurez chaque reel ainsi :
- Accroche (0–2 s) — le plan le plus frappant. Pas de logo ni d'introduction textuelle.
- Montée — détails et anticipation (gros plans, ralenti).
- Moment héroïque — sur le plus gros battement / drop musical.
- Émotion / récompense — réactions, personnes, célébration.
- Outro (2–3 dernières secondes) — plan large propre, texte ou logo optionnel, fondu musical.
Modèle pour une livraison de voiture (à adapter aux rushes) : plan extérieur large → logo en gros plan → détails roue/optique → famille qui arrive (ralenti) → dévoilement du véhicule (sur le drop) → remise des clés → réactions / sourires → intérieur + volant → gâteau / guirlande / pooja → premier départ (plan large, outro).
Règles : variez les tailles de plan (jamais deux plans larges à la suite), gardez chaque plan entre 0.5 et 2.5 s, utilisez le ralenti uniquement pour les plans émotionnels ou de révélation, coupez sur le mouvement dès que possible.
5. Détection des battements
# work/beats.py
import librosa, json, sys
y, sr = librosa.load(sys.argv[1])
tempo, frames = librosa.beat.beat_track(y=y, sr=sr)
beats = librosa.frames_to_time(frames, sr=sr).tolist()
onset = librosa.onset.onset_strength(y=y, sr=sr)
json.dump({"tempo": float(tempo), "beats": beats}, open("work/beats.json", "w"), indent=1)
print(f"tempo {float(tempo):.1f} BPM, {len(beats)} battements")
Coupez sur les battements (chaque battement pour les sections rapides, tous les 2e ou 4e battement pour les sections lentes). Trouvez le drop (le plus grand saut d'énergie) et placez-y le plan héroïque.
6. Écrire la liste de montage work/edl.json
{
"output": {"w": 1080, "h": 1920, "fps": 30},
"music": {"file": "music/track.mp3", "start": 12.0, "fade_out": 1.5},
"grade": {"lut": "luts/teal_orange.cube", "vignette": true},
"shots": [
{"id": 1, "src": "raw/C0001.mp4", "in": 4.20, "dur": 1.40, "speed": 1.0, "crop_x": "center", "note": "accroche – plan large voiture"},
{"id": 2, "src": "raw/C0007.mp4", "in": 10.0, "dur": 1.00, "speed": 0.5, "crop_x": "center", "note": "roue ralenti"}
],
"transitions": [{"after_shot": 4, "type": "fade", "dur": 0.3}],
"text": [{"text": "Bienvenue à la maison", "start": 18.0, "end": 21.0}]
}
dur est la durée sur la timeline. Avec speed 0.5, la durée source utilisée est dur × speed secondes. Montrez ce plan à l'utilisateur sous forme d'un tableau simple (plan, temps, description) avant le rendu.
7. Rendu de chaque plan en segment uniforme
Chaque segment doit avoir une résolution, un fps, un format de pixel identiques et pas d'audio, pour qu'ils s'assemblent proprement :
# source paysage → recadrage 9:16, vitesse, étalonnage
ffmpeg -y -ss IN -t SRC_DUR -i raw/CLIP.mp4 -an -vf "\
setpts=PTS/SPEED,\
scale=-2:1920,crop=1080:1920,\
fps=30,\
lut3d=luts/teal_orange.cube,\
eq=contrast=1.06:saturation=1.10,\
vignette=PI/5,\
format=yuv420p" \
-c:v libx264 -crf 16 -preset medium work/seg_01.mp4
SRC_DUR = dur × speed. Pour le ralenti, utilisez une source haute fréquence ; évitezminterpolatesauf demande explicite (lent et artefacts).- Source verticale : utilisez
scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920. - Pas de LUT disponible : utilisez
eq=contrast=1.08:saturation=1.15:gamma=0.98suivi decurves=preset=increase_contrastpour un rendu cinématique. - Les barres cinématiques optionnelles ne sont PAS utilisées dans les reels 9:16.
8. Assemblage des segments
Sans transitions — démutiplexeur concat :
printf "file 'seg_%02d.mp4'\n" 1 2 3 ... > work/list.txt
ffmpeg -y -f concat -safe 0 -i work/list.txt -c copy work/video.mp4
Avec une transition entre deux segments, utilisez xfade (décalage = durée du premier clip − durée de la transition) :
ffmpeg -y -i work/seg_04.mp4 -i work/seg_05.mp4 -filter_complex \
"[0][1]xfade=transition=fade:duration=0.3:offset=1.2,format=yuv420p" work/seg_04_05.mp4
Chaque transition raccourcit la timeline de sa durée — revérifiez l'alignement sur les battements.
9. Musique, texte, export final
ffmpeg -y -i work/video.mp4 -ss MUSIC_START -i music/track.mp3 -filter_complex \
"[1:a]afade=t=in:d=0.3,afade=t=out:st=FADE_START:d=1.5,loudnorm=I=-14:TP=-1:LRA=11[a];\
[0:v]drawtext=fontfile=FONT.ttf:text='Bienvenue à la maison':fontsize=72:fontcolor=white:\
x=(w-text_w)/2:y=h*0.72:enable='between(t,18,21)':alpha='if(lt(t,18.4),(t-18)/0.4,1)'[v]" \
-map "[v]" -map "[a]" -shortest \
-c:v libx264 -crf 18 -preset slow -profile:v high -pix_fmt yuv420p -r 30 \
-c:a aac -b:a 192k -movflags +faststart out/reel_v1.mp4
Trouvez un fichier de police sur la machine pour drawtext (ou demandez). Gardez le texte minimal, dans la zone sécurisée (évitez les 15% du haut et 25% du bas, où se trouve l'interface d'Instagram).
10. Contrôle qualité (toujours)
ffprobe out/reel_vN.mp4→ 1080×1920, 30 fps, H.264, AAC, durée conforme au plan.- Planche-contact du reel final (
fps=2,scale=270:-1,tile=6x5) et visualisez-la : pas d'images noires, pas de mauvais recadrages (têtes coupées), couleur cohérente. - Vérifiez le niveau sonore et que le plan héroïque tombe sur le drop.
- Rapportez à l'utilisateur : durée, nombre de plans, chemin du fichier, et tout ce dont vous n'étiez pas sûr.
11. Révisions
Ne repartez jamais de zéro. Modifiez work/edl.json (remplacez un plan, changez in/dur, vitesse, texte, étalonnage), refaites le rendu des seuls segments modifiés, reassemblez et exportez sous la version suivante (reel_v2.mp4). Conservez les anciennes versions pour que l'utilisateur puisse comparer.