Que fait Rough Cut : dégraisser le gras ?
Les monteurs appellent ça l'assemblage et le premier montage (rough cut). Chaque ligne utilisable est conservée, dans l'ordre, et tout ce qui ne mérite pas sa place est retiré. Ce n'est pas la vidéo finale. C'est la version où chaque seconde montre le locuteur en train de bien dire sa phrase, pour que les passes ultérieures (rythme, couleur, graphismes, son) travaillent sur du bon matériel.
L'idée derrière tout ça : éditer les mots, pas la forme d'onde. Obtenez une transcription où chaque mot a un début et une fin, décidez ce qu'il faut garder en lisant, et les coupes suivent les timings. Descript et l'édition textuelle dans Premiere et Resolve fonctionnent ainsi. Cette compétence ajoute deux choses qu'ils ne font pas : elle ajuste chaque coupe au son réel, et elle vérifie le rendu en l'écoutant à nouveau.
Configuration (une fois)
sh ~/simcraft/skills/rough-cut/setup.sh
Crée .venv à côté de ce fichier avec Whisper (mlx-whisper sur Apple Silicon, faster-whisper ailleurs). Nécessite ffmpeg : ffmpeg dans le PATH, ou $FFMPEG, ou ~/neatlogs-motion/ffmpeg. Exécutez chaque script ci-dessous avec ~/simcraft/skills/rough-cut/.venv/bin/python.
Espace de travail
Un dossier par vidéo. Si l'utilisateur n'en a pas créé, faites ~/Movies/edits/YYYY-MM-DD-<slug>/ et copiez (ne déplacez jamais) les fichiers bruts dans raw/. Les scripts écrivent dans audio/, cuts/ et renders/ à côté. Rien dans raw/ n'est jamais modifié.
Le processus, dans l'ordre
1. Transcrire
python scripts/transcribe.py <workspace> [--lang en]
Écrit audio/words.json (chaque mot : début, fin, texte, confiance) et audio/transcript.txt (une ligne par prise). Environ 1 minute pour 2 minutes de métrage sur un Mac à puce M.
Passez --lang en quand c'est de l'anglais (plus précis). Omettez-le pour un mélange hindi/anglais.
Comment cela reste précis (chaque point corrige un échec rencontré sur des séquences réelles) :
- Chaque prise est transcrite individuellement. L'audio est découpé à chaque pause de 0,5 s ou plus. En transcriant un fichier entier d'un coup, Whisper écrit une ligne dite cinq fois une seule fois, donc les prises supplémentaires n'ont pas de mots et ne peuvent pas être coupées.
- Les mots de remplissage sont conservés dans la transcription. Whisper supprime par défaut "euh" et "hum". Un prompt rempli d'hésitations les fait revenir pour pouvoir les couper.
- Les boucles de transcription sont supprimées. Whisper répète parfois une phrase des dizaines de fois sur du bruit ("there you go there you go..."). Plus de 7 mots par seconde est impossible, donc ces lignes sont jetées.
2. Trouver les coupes
python scripts/find_cuts.py <workspace> [--gap 0.35] [--keep-fillers]
Écrit cuts/edl.json (les morceaux à garder, dans l'ordre) et cuts/cut_sheet.md (chaque coupe et sa raison, plus les mots de faible confiance à vérifier).
| Coupe | Règle |
|---|---|
| Blanc | Toute pause plus longue que --gap (0,35 s). Silence de tête et de queue aussi. |
| Mots de remplissage | euh, hum, erm, hmm, mm, ah. |
| Répétitions | Un mot ou un groupe de jusqu'à 4 mots dit deux fois de suite ("donc le donc le") : garde le second. |
| Prises reprises | La même ligne dite à nouveau dans les 20 s, appariée par lettres pour que les erreurs d'audition correspondent encore ("Vanta"/"Wanda", "1"/"one") : garde la dernière prise. |
| Faux départs | Une ligne abandonnée en cours puis dite en entier ("A 300 billion." puis "A 300 million dollar business."). |
| Même fin | Une ligne reformulée au début mais finissant de la même façon ("That's, it's Vanta's own founder" puis "And that's not me saying it, it's Vanta's own founder"). |
| Mots fantômes | Un mot tout seul sans voix dessous. Whisper les invente dans le silence ("Thank you.", "hallelujah"). |
Où atterrit chaque coupe :
- Chaque bord est ajusté là où la voix commence et s'arrête vraiment, mesuré à partir du volume par pas de 10 ms avec un seuil qui s'adapte à la pièce. Les horodatages de Whisper peuvent être décalés de 0,1 à 0,3 s.
- Un bord ne se déplace que de 0,12 s maximum plus tard, car couper un mot est pire que garder une respiration.
- 0,06 s de blanc sont laissés avant la voix et 0,10 s après.
- Quand il n'y a pas de vrai trou, par exemple un "euh" collé au mot suivant, la coupe se fait au point le plus silencieux (10 ms) entre eux.
- Une pause cachée à l'intérieur d'un long "mot" Whisper est quand même trouvée et coupée.
3. Passage de jugement (le vrai montage, ne jamais le sauter)
Lisez cuts/cut_sheet.md à côté de audio/transcript.txt et corrigez cuts/edl.json à la main. Un script ne peut pas juger ces éléments :
- Quelle prise est la meilleure. La dernière prise est conservée par défaut, mais la meilleure est celle avec de l'énergie, une fin propre et sans rire qui la coupe. Parfois, la première moitié d'une prise plus la fin d'une autre est la meilleure.
- Les mots de remplissage qui font partie de la blague. Un "euh" délibéré avant une chute reste.
- "comme", "tu sais", "je veux dire", "en gros". Ceux-ci ne sont jamais coupés automatiquement. Coupez uniquement ceux qui sont de la pure hésitation. Les couper tous donne l'impression que le locuteur n'est pas lui-même.
- Les pauses qui sont des temps. Une pause avant une chute, une réaction ou un regard caméra reste. Ce n'est pas parce qu'il y a du silence que c'est du vide.
- Dire deux fois la même chose avec des mots différents. Coupez des phrases entières.
- Les moments non-parlés, comme une chanson, un gag visuel ou un plan de réaction. Seule la parole est conservée, donc ajoutez ces morceaux à la main.
- L'ordre. Les morceaux suivent l'ordre des fichiers. Déplacez la ligne la plus forte en haut pour une ouverture à froid si l'utilisateur le souhaite.
- La liste "vérifiez ces mots". Une faible confiance signifie souvent du marmonnement. Si la ligne n'est pas claire, cherchez une prise plus nette.
Chaque morceau est {"clip", "in", "out", "text"}, et "speed" est optionnel. Gardez les coupes entre les mots.
4. Rythme (demander d'abord)
La feuille de coupe indique les mots par seconde. Un contenu dynamique de tête parlante se situe autour de 3,3–3,8. Si le locuteur est plus lent, suggérez une vitesse de 1,05–1,2 et définissez "speed" dans edl.json pour toute la vidéo, ou par morceau. La hauteur reste la même. N'accélérez jamais la musique ou les réactions.
5. Rendu de prévisualisation
python scripts/render.py <workspace> --w 854 --v 1 [--aspect 9:16]
Un aperçu en 480p va dans renders/v1_854.mp4. Augmentez --v pour chaque série de commentaires afin que les anciennes versions restent.
- Chaque morceau est rendu avec un nombre exact d'images et un audio non compressé, puis tous les morceaux sont assemblés par décodage. Les jonctions par stream-copy perdent des images aux coupes et l'audio dérive d'environ 2 s en quelques minutes.
- Chaque morceau reçoit un fondu de 12 ms à l'entrée et 20 ms à la sortie, pour que les coupes ne cliquent pas.
- Les clips de forme différente reposent sur une copie floutée d'eux-mêmes au lieu de barres noires.
6. Vérification (toujours, avant de montrer à l'utilisateur)
python scripts/verify.py <workspace> --v 1 [--lang en]
Il écoute à nouveau le rendu, morceau par morceau, le compare avec la liste de coupe, et écrit cuts/verify_v1.md. Le rapport comporte quatre sections :
- Coupes qui tombent alors que la voix est encore en cours : un test sonore qui ne dépend pas de Whisper. C'est le vrai détecteur de mots coupés. Corrigez chaque cas en déplaçant ce bord dans edl.json.
- Mots manquants : attendus mais pas entendus.
- Mots inattendus : un mot de remplissage ou un bout de prise qui fuit.
- Erreurs d'audition : les deux transcriptions divergent sur le wording. C'est généralement du marmonnement, pas un problème de coupe.
Sur un audio propre, l'objectif est 100 % des mots présents, 0 coupe dans le son et 0 mot inattendu. Un audio bruité ou marmonné donne quelques paires manquant/inattendu qui sont en fait des erreurs d'audition. Fiez-vous au test sonore plutôt qu'à elles.
Corrigez ce qu'il trouve, rendez à nouveau et vérifiez à nouveau.
7. Montrer à l'utilisateur, puis le rendu final
- Dites à l'utilisateur : la durée avant et après, le nombre de coupes, le résultat de la vérification, et les choix de jugement que vous avez faits (quelle prise vous avez gardée, une pause que vous avez volontairement conservée).
- Notez leurs commentaires avant de faire la version suivante.
- Ce n'est qu'après leur approbation de l'aperçu :
python scripts/render.py <workspace> --w <source width> --v N.
Résultats sur des séquences réelles
Sur 3 minutes de séquences brutes de tête parlante avec de nombreuses reprises (9 prises d'une ligne, 4 d'une autre), 2:55 de parole sont devenus 0:36. Il a gardé la dernière prise propre de chaque ligne, et la vérification a trouvé 100 % des mots présents, 0 coupe dans le son et 0 fuite.
Le goût de l'utilisateur
- Dynamique. Les jump cuts sur les espaces entre les mots sont bons ; les zooms alternés constants ne le sont pas.
- Gardez les jurons, les plaisanteries et les passages drôles. Ne nettoyez jamais la personnalité.
- Pas de whoosh, et pas d'étalonnage à ce stade.
- Quand l'utilisateur demande "seulement les bons passages, X minutes maximum", coupez des moments entiers, pas seulement les pauses.