Communitygithub.com

beachyphotoandfilm-arch/video-skills

Transformez des rushes bruts en un montage préliminaire assemblé dans DaVinci Resolve. Extrait les clips de votre disque de rushes, les transcrit localement, supprime les prises ratées, les apartés, les redémarrages et les silences, puis crée un nouveau projet Resolve avec deux timelines prêtes pour votre affinage.

Qu'est-ce que video-skills ?

Cette compétence pour agent IA automatise le montage préliminaire de vidéos tête parlante en extrayant les rushes bruts, en les transcrivant localement avec whisper.cpp, puis en créant deux timelines de montage papier dans DaVinci Resolve. Elle réduit typiquement une vidéo de 14 minutes à environ 10 minutes, en supprimant les apartés, les prises ratées, les faux départs et les silences, tout en conservant les répétitions délibérées et les digressions utiles. La compétence génère d'abord `segments-v1.json` avec les coupes de jugement, puis `segments-v2.json` qui resserre également les pauses à 0,22 seconde. Elle supporte un affinage supplémentaire via des incrustations de cadrage (wide/med/close) sur une troisième timeline optionnelle, et peut appliquer un LUT pour les profils log. Les utilisateurs peuvent déclencher la compétence par des phrases comme 'paper edit', 'cut my raw footage', 'make a rough cut', ou 'clean up this video', et elle s'intègre avec DaVinci Resolve via un serveur MCP Resolve.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beachyphotoandfilm-arch/video-skills/tree/HEAD/skills/paper-edit

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Montage papier

Rushes bruts en entrée, montage préliminaire assemblé dans Resolve en sortie. Lors de son premier test réel : brut 14:17, sortie 10:16, contre le montage manuel du créateur de 10:32.

La répartition des tâches : Claude fait le montage large, le créateur fait l'affinage fin. N'essayez pas de livrer un montage finalisé, et ne soyez pas trop conservateur au point de devoir refaire les parties évidentes.

Configuration : à remplir

PlaceholderDescriptionExemple
<FOOTAGE_DRIVE>Où se trouvent les rushes bruts, un dossier par vidéo/Volumes/MyWorkDrive
<LUT_PATH>LUT optionnel, relatif au dossier LUT de ResolveMyLuts/SLog3-to-709.cube
WHISPER_MODEL (env)Fichier modèle whisper.cppdéfaut ~/.cache/whisper-models/ggml-small.en.bin
RESOLVE_APP (env, optionnel)Chemin de l'application Resolve si non standarddéfaut /Applications/DaVinci Resolve/DaVinci Resolve.app

Prérequis : ffmpeg, ffprobe, whisper-cli (whisper.cpp), Python 3, DaVinci Resolve avec un serveur MCP Resolve qui expose execute_resolve_code.

Exécution

Répertoire de travail : utiliser le scratchpad de la session, par ex. <scratchpad>/paperedit. Le répertoire de la compétence ci-dessous est .claude/skills/paper-edit.

1. Trouver les rushes

Les rushes se trouvent sur <FOOTAGE_DRIVE>, un dossier par vidéo, souvent nommé de manière approximative.

find "<FOOTAGE_DRIVE>" -maxdepth 4 -iname "*<mot-clé>*" -not -path "*/.*"

Confirmer le dossier avec l'utilisateur si plusieurs correspondent. Ne copiez pas les fichiers ; Resolve les lie sur le disque.

2. Transcrire chaque clip

bash <skill>/scripts/transcribe.sh "<FOOTAGE_DRIVE>/<dossier>" "<work>"

Écrit <clip>.json (niveau mot), <clip>.wav, et clips.ndjson avec les durées. Environ 90s pour 15 minutes de rushes. Ignore les clips déjà faits, donc sécurisé pour une ré-exécution.

3. Lire vous-même la transcription

python3 <skill>/scripts/sentences.py "<work>"

Lisez-la entièrement. C'est la partie qui ne peut pas être scriptée. Un détecteur de phrases répétées a été essayé et a échoué lamentablement : il voulait couper 428 des 737 secondes, car les enseignants répètent les phrases intentionnellement ("voici ce qui marche, voici ce qui ne marche pas").

4. Écrire la liste de coupes

<work>/cuts.json, un objet par suppression, temps en secondes depuis le début de ce clip :

[{"clip":"C0002","start":32.58,"end":39.76,"why":"bafouillage : 'ce que j'ai réalisé, c'est que même parfois...'"}]

Coupez ceci :

  • Apartés et paroles à la caméra : "c'était plutôt bien, je dois l'avouer", "cette caméra est sur le point de mourir", "ça va probablement être une vidéo de sept minutes"
  • Faux départs, en gardant la dernière tentative. Les orateurs reformulent souvent une phrase deux fois, mieux la deuxième fois.
  • Prises ratées du CTA. Il y en a souvent 3-4 à la fin ; conservez la dernière.
  • Longs silences entre les sections, bruit entre parenthèses ([BLANK_AUDIO], (clavier qui clique), (froissements))
  • Phrases abandonnées en plein milieu et reconstruites ("la raison pour laquelle je ne faisais pas ça avant, c'est parce que j'avais peur, et...")
  • Courts redémarrages à l'intérieur d'une phrase, marqués par une virgule et une clause reformulée : "tout ce que j'ai demandé en retour, c'est un simple avis et c'est, et ajouter la partie avis..." Coupez de la clause abandonnée jusqu'au redémarrage. Cela dure 1-2s et est facile à lire sans.
  • Les timings des mots de Whisper dérivent d'environ 0.5s. Sur un faux départ qui reformule les mêmes mots ("j'adore venir offrir, j'adore commencer"), terminez la coupe au début du second "j'adore", pas à la fin de la première tentative, sinon un mot isolé survit.
  • Commencez une coupe à l'offset to du mot conservé, jamais à son from. Lors d'un test, une coupe a commencé à 40.30 alors que le mot conservé s'étendait de 40.19 à 40.92, donc le dernier mot de l'accroche a été coupé et a dû être glissé manuellement. Affichez les offsets avec from|to pour le mot avant chaque coupe.
  • Après une longue séquence de [BLANK_AUDIO], les timings sont peu fiables. Whisper a compressé les mots de la première prise d'accroche après 30s de silence, et la coupe a laissé un fragment de mot comme toute première seconde de la vidéo. Lorsqu'une prise commence après du silence, vérifiez le niveau audio (ffmpeg astats) pour trouver où la parole commence réellement au lieu de vous fier aux offsets des mots.

Conservez :

  • Les répétitions délibérées utilisées pour le rythme pédagogique
  • Les digressions qui apportent encore quelque chose, sauf indication contraire de l'utilisateur
  • Tout ce dont vous n'êtes pas sûr. Signalez-le dans votre résumé au lieu de le couper.

5. Construire les segments

python3 <skill>/scripts/segments.py "<work>"

Produit segments-v1.json (coupes de jugement uniquement), segments-v2.json (réduit également les pauses de plus de 0.50s à 0.22s), et cutlist.txt. Paramètres ajustables via env : MIN_GAP, KEEP_PAUSE, NOISE_DB.

Il supprime également les blips sans parole : segments v2 de moins de 1s sans audio au niveau de la parole. Ce sont des clics de souris et des regards vers un ordinateur portable, laissés comme des îlots entre les pauses réduites. Paramètres ajustables : BLIP_MAX, SPEECH_DB.

Lisez chaque ligne join: dans cutlist.txt avant de la montrer à l'utilisateur. Elle indique comment la phrase se lit à travers chaque coupe. Si la même phrase apparaît des deux côtés du |, la coupe est trop courte.

Les deux passes sont importantes. Avec seulement les coupes de jugement, le retour était "il y a de grandes pauses partout, surtout au début". La réduction des pauses est ce qui a fait passer de 11:32 à 10:16. Ne descendez pas KEEP_PAUSE en dessous d'environ 0.20s ; cela commence à sembler précipité.

6. Montrer la liste de coupes avant de construire

Collez le résumé : durée brute, v1, v2, nombre de coupes, et les coupes notables avec leurs raisons. L'utilisateur oppose son veto à ce qu'il souhaite.

7. Construire dans Resolve

Nécessite Préférences > Système > Général > Scripting externe via : Local (à définir une fois, cela persiste). Ne demandez pas à l'utilisateur d'ouvrir Resolve. Exécutez d'abord ceci ; cela lance Resolve s'il est fermé et attend que l'API réponde :

bash <skill>/scripts/ensure_resolve.sh

Si cela expire alors que Resolve est en cours d'exécution, les scripts sont désactivés ; c'est la seule chose à demander à l'utilisateur de corriger.

Écrivez <work>/params.json :

{"project":"<Nom de la vidéo> - AAAA-MM-JJ","work":"<work>",
 "files":["<FOOTAGE_DRIVE>/<dossier>/C0001.MP4","..."],
 "fps":23.976,"width":1920,"height":1080}

Puis un appel execute_resolve_code :

PARAMS = "<work>/params.json"
exec(open("<skill>/scripts/resolve_build.py").read())

Plusieurs vidéos : construisez-les une par une, jamais en appels d'outils parallèles. Resolve a un seul projet courant, donc deux constructions simultanées entrent en conflit. Une fois, deux constructions ont été exécutées ensemble et une v2 est sortie vide, même si le script rapportait que chaque élément avait été ajouté. Après chaque construction, vérifiez vous-même le nombre d'éléments de chaque timeline.

Nommez le projet <Vidéo> - AAAA-MM-JJ afin que les projets de même nom ne soient jamais confondus. Il crée un nouveau projet, importe les clips, et construit Paper Edit v1 et Paper Edit v2 (tight). Rien d'existant n'est touché. C'est une utilisation autorisée de execute_resolve_code ; append_to_timeline ne peut pas prendre de points d'entrée/sortie, donc il n'y a pas d'alternative. Montrez le code à l'utilisateur la première fois dans une session.

Solution de repli si Resolve est inaccessible (exécution cloud/planifiée, ou ensure_resolve.sh a échoué) : écrivez un FCPXML d'éléments asset-clip, un par segment, avec start et duration en frames*1001/24000s, et laissez l'utilisateur l'importer. Même résultat, un clic supplémentaire.

8. Passation

Informez l'utilisateur que les deux timelines existent, laquelle parcourir en premier (v2), et que v1 est le filet de sécurité si v2 semble trop serrée. Demandez ensuite si la coupe est verrouillée, car les incrustations viennent après (voir video-overlays, si vous l'avez).

9. Incrustations de cadrage (troisième timeline optionnelle)

Une variation de cadrage statique rend une tête parlante regardable. L'API de Resolve n'a pas d'accès aux images clés, donc les pushs lents sont impossibles à scripter ; le cadrage statique par clip ("de temps en temps, l'un des clips est un peu plus zoomé") est ce que vous pouvez faire.

Lie chaque changement à la transcription, jamais à un minuteur. Une version basée sur un minuteur semblait aléatoire. Incrustez sur les lignes percutantes ou là où un nouveau sujet commence, pour que cela ait du sens.

Écrivez <work>/framing.json :

[{"clip":"C0002","at":361.40,"framing":"med","why":"CONSEIL 3"},
 {"clip":"C0002","at":371.80,"framing":"close","why":"'c'est la partie qui compte'"}]

at est le début de la phrase depuis sentences.py. Ensuite python3 <skill>/scripts/punchins.py "<work>" et définissez "punchins": true dans params.json. Cela divise un segment partout où une marque tombe à l'intérieur, au point le plus silencieux près du début de la phrase, car les têtes parlantes durent souvent longtemps sans pause et sinon le changement glisse en retard.

Si l'utilisateur a affiné manuellement v2 dans Resolve, sa timeline est la coupe. Lisez ses éléments (GetLeftOffset/GetDuration, images x 1.001/24 = secondes) dans segments-locked.json, exécutez avec SEGMENTS=segments-locked.json, et ajoutez seulement v3 au projet existant avec "timelines": ["v3"]. Visez un changement toutes les ~20-40s : large à chaque nouveau sujet, moyen pour l'enseignement, serré sur la ligne percutante. Le constructeur dépose un marqueur bleu à chaque changement nommant la raison, donc la logique est visible.

Cadrages : wide 1.00, med 1.11 (inclinaison -12), close 1.21 (inclinaison -24).

Si l'utilisateur a étalonné v2 pendant son affinage, v3 est construit à partir de zéro avec seulement le LUT, donc copiez l'étalonnage de v2 sur v3 immédiatement après la construction :

src = v2.GetItemListInTrack("video", 1)[5]          # tout élément v2 étalonné
src.CopyGrades(v3.GetItemListInTrack("video", 1))    # fonctionne entre timelines ; zoom/inclinaison survivent

Vérifiez avec GetNodeGraph().GetToolsInNode(1) sur chaque élément v3. N'utilisez pas la voie de la galerie (GrabStill + ExportStills vers .drx) : l'exportation renvoie False via l'API. Si GrabStill a été utilisé, supprimez l'image fixe pour que la galerie reste propre.

Lecture d'une v2 verrouillée : GetLeftOffset() et GetDuration() donnent les images source. Le premier segment vous indique si l'accroche a été coupée. Différenciez les segments verrouillés contre segments-v2.json et notez ce qui a changé, pour calibrer la prochaine édition.

10. Couleur

Définissez "lut": "<CHEMIN_LUT>" dans params.json pour l'appliquer à chaque clip sur le nœud 1. Si la caméra tourne en profil log (par ex. S-Log3), les rushes non étalonnés semblent plats et gris, donc un LUT vaut la peine d'être défini. L'API ne peut pas ajouter un second nœud ; pour un étalonnage multi-nœuds, étalonnez un clip à la main et propagez-le avec CopyGrades.

11. Photos pendant le discours (optionnel)

Lorsque l'orateur parle de quelque chose dont il a des photos, placez-les sur V2 de v3, sur un fond blanc.

  • Cartes, pas un diaporama. Rendez des PNG 1920x1080 sur fond blanc pur : trois portraits côte à côte (redimensionnés à h840, espacements de 50px), deux portraits (h880, espacement de 60px), ou un paysage (h900). Regroupez les photos par ce qui est dit.
  • Temporalisez chaque carte au début d'une phrase de la transcription verrouillée, et changez de carte à la phrase suivante. Environ 2-5s par carte. Restez sur les photos uniquement pendant qu'elles sont décrites.
  • Importez-les en tant que .mov ProRes de durée exacte, pas en tant qu'images fixes. Les images fixes arrivent dans Resolve à une durée fixe de 2s et se chevauchent. Les noms numérotés (card1.png, card2.png) s'importent en une seule séquence d'images, donc utilisez des noms de mots. Rendez avec ffmpeg -loop 1 -framerate 24000/1001 -i x.png -frames:v N -c:v prores_ks -profile:v 3.
  • Pour un .mov, AppendToTimeline nécessite endFrame = le nombre d'images (pas nombre-1), sinon chaque carte atterrit une image trop court et l'orateur apparaît à l'écran entre les cartes. Passez "mediaType": 1 pour qu'aucun audio ne soit inclus.
  • Nommez la piste " photos", placez les cartes dans leur propre dossier de la médiathèque, et ne mettez jamais le LUT dessus (elles sont déjà étalonnées).
  • Montrez à l'utilisateur une planche contact des cartes dans le chat avant de les placer.

Faits utiles à retenir

  • Calibration à partir de montages réels : après une v2, le créateur supprime généralement 10-20s à la main d'un montage d'environ 10 minutes. La plupart est un resserrage au niveau de l'image aux bords des segments, plus des lignes reformulées, où un point est dit puis redit mieux en quelques secondes. Lorsqu'une phrase reformule celle qui la précède, coupez la première version. Cela diffère de la répétition pédagogique délibérée, qui répète une phrase entre sections, pas dos à dos. Lorsqu'un point est fait deux fois loin l'un de l'autre, signalez la prise la plus faible comme une coupe possible.
  • L'inquiétude habituelle est de trop couper, donc les choses doivent être rajoutées ; resserrez uniquement sur des preuves, jamais sur une intuition.
  • Format source exemple : 4K 23.976 MP4 avec audio 48kHz ; timeline de livraison 1920x1080 23.976, commençant à 01:00:00:00. Ajustez fps/width/height dans params.json pour vos rushes.
  • Timecode à 23.976 compte 24 images par seconde de timecode : frames = round(seconds / 1.001 * 24).
  • AppendToTimeline traite endFrame comme exclusif : passez l'image après la dernière que vous voulez. Une règle "inclusif, soustraire 1" supprime une image de chaque segment (environ 4s sur une timeline de 10 minutes, et tout segment d'une image disparaît).
  • Certains orateurs n'utilisent presque pas de mots de remplissage ; vérifiez avant de construire autour de la suppression des mots de remplissage.
  • Environ 20% des rushes bruts tête parlante sont supprimables, et environ les trois quarts de cela sont du jugement (prises et redémarrages), un quart est du silence.
  • Modèle Whisper : ggml-small.en.bin est suffisamment précis ; il méentend quelques mots, ce qui n'a pas d'importance pour les points de coupe mais en a si vous citez l'orateur.

Connexes

  • video-overlays : graphiques animés, à exécuter après que la coupe est verrouillée (si installé)
  • video-reels : coupes verticales à partir des mêmes rushes (si installé)
  • video-thumbnails : miniatures et titres (si installé)
  • lapel-sync : à exécuter en premier lorsque l'audio a été enregistré sur un micro-cravate/enregistreur séparé

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

beachyphotoandfilm-arch/video-skills

Sync camera footage to a separate lapel or field-recorder track (e.g. Tascam DR-10L and similar) and lay it up in DaVinci Resolve. Stitches the recorder's split files, finds each clip's exact place in the audio by matching words then waveforms, cuts one lapel slice per clip so every later skill works unchanged, checks for clipping, and builds a synced timeline in a new Resolve project. Trigger on "sync the lapel", "sync my audio", "line up the recorder", "I used a lav", or any shoot with a separate audio folder (live talks, events, workshops). Run it before paper-edit or video-reels.

beachyphotoandfilm-arch/video-skills

Design a unique Instagram cover for each reel in your house style. Reads what the reel is about, writes a short hook headline, picks one of your own photos from a tagged photo library, lays it out like your existing covers, and proofs it in grid view at phone size. Renders locally, never with AI image generation. Can be called by a scheduling skill before reels are scheduled. Trigger on "make covers", "reel covers", "cover photo for this reel", "design the IG covers".

beachyphotoandfilm-arch/video-skills

Render finished reels out of DaVinci Resolve, write captions in the creator's voice, attach a custom Instagram cover from reel-covers, and schedule them to Instagram, TikTok and YouTube Shorts through Metricool. Handles the Drive upload hop, collision checks against the existing calendar, and cleanup. Trigger on "schedule the reels", "post these", "put these on the calendar", or after reels are approved.

beachyphotoandfilm-arch/video-skills

Build animated brand overlays (motion graphics) for a talking-head video, timed to the speaker's exact words, plus a DaVinci Resolve import file. House style is in-scene type (text beside and behind the speaker's head) plus diagrams. Transcribes the rough cut locally, picks the moments, renders transparent .mov clips, and writes an FCPXML that drops every clip onto the timeline already in position. Trigger on "make animations for this video", "add overlays/motion graphics", "animate this", "b-roll graphics for my YouTube video", or when the user shares a rough cut and asks for graphics.

beachyphotoandfilm-arch/video-skills

Cut vertical Instagram reels out of a long-form talking-head video, hook first. Picks the strongest standalone moments from the transcript, opens each reel on its punchiest line, builds vertical timelines in DaVinci Resolve framed on the speaker's face with the LUT applied, and finishes them: a hook (a held text card, or a word-by-word "build" hook with punch-in) and burned-look captions on V3; this-or-that reels get product graphics and a comment-keyword CTA card. You trim and render, nothing to import. Trigger on "make reels", "clip this for Instagram", "cut some verticals", or after a YouTube video is cut.

beachyphotoandfilm-arch/video-skills

Design YouTube thumbnails and titles for a talking-head video. Pulls graded full-res frames out of the raw footage, renders brand-styled variants in two proven layouts, and proofs them at phone size where the click actually gets decided. Trigger on "make thumbnails", "thumbnail for this video", "title and thumbnail", or after a video is cut.

beachyphotoandfilm-arch/video-skills

Run the whole YouTube video pipeline end to end, one stage at a time, stopping for the creator's approval at every gate. Paper edit, punch-ins, reels, reel covers, scheduling the reels, overlays, thumbnail and title, then scheduling the long-form video, all through Metricool. Keeps state per video so you can stop anywhere and pick up later. Trigger on "/youtube", "let's do the whole video", "run the video pipeline", "continue the <name> video", or when handed raw footage for a YouTube video.

Skills associés