Communitygithub.com

Synchronisation lapel

Synchronise les clips de la caméra avec une piste audio distincte d'un enregistreur (ex. Tascam DR-10L) et les intègre dans un projet DaVinci Resolve, avec une piste lapel découpée par clip.

Qu'est-ce que Synchronisation lapel ?

Cette compétence automatise la synchronisation audio d'une prise de vue avec un micro-cravate (lapel) et un enregistreur séparé. Elle assemble les fichiers splittés de l'enregistreur, transcrit l'audio de la caméra et de l'enregistreur, puis aligne chaque clip avec précision en combinant une recherche de mots uniques et une corrélation de forme d'onde. Le résultat est une piste lapel nette par clip, prête à être utilisée par les compétences `paper-edit` et `video-reels`. La compétence crée également un projet DaVinci Resolve synchronisé, avec les clips vidéo sur la piste V1 et leurs pistes lapel correspondantes sur la piste A1. Elle est idéale pour les talks en direct, événements et ateliers où l'audio de la caméra est inexploitable.

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

Demander à votre IA préférée

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

Documentation

Que fait Synchronisation lapel ?

Clips caméra + piste d'enregistreur séparée en entrée, une piste lapel par clip et une timeline Resolve synchronisée en sortie. Testé pour la première fois sur un talk en direct : 5 clips caméra contre une piste d'enregistreur de 59 minutes. Chaque clip a atterri à moins de 20 ms, bien en dessous d'une frame.

Pourquoi c'est important : lors d'un événement en direct, le micro de la caméra est à travers la pièce. Son audio est inutilisable, et le lapel est le seul son propre. Après cette compétence, <work>/<clip>.wav et <clip>.json sont le lapel, de sorte que paper-edit et video-reels lisent un audio propre et des transcriptions propres sans rien savoir du changement.

Configuration : à remplir

Espace réservéCe que c'estExemple
<FOOTAGE_DRIVE>Où se trouvent les rushes bruts, un dossier par vidéo, fichiers d'enregistreur dans un sous-dossier audio//Volumes/MyWorkDrive
<SYNC_OUT>Où vont les tranches lapel pleine qualité~/Movies/<video>-sync
<LUT_PATH>LUT optionnelle, relative au dossier LUT de ResolveMyLuts/SLog3-to-709.cube
WHISPER_MODEL (env)Fichier modèle whisper.cpppar défaut ~/.cache/whisper-models/ggml-small.en.bin

Prérequis : ffmpeg, ffprobe, whisper-cli (whisper.cpp), Python 3 (numpy et scipy sont installés automatiquement dans ~/.cache/lapel-sync-venv), DaVinci Resolve avec un serveur MCP Resolve exposant execute_resolve_code, et la compétence paper-edit (pour ensure_resolve.sh).

Exécution

Répertoire de travail : le scratchpad de la session, par ex. <scratchpad>/<video>. Le répertoire de la compétence ci-dessous est .claude/skills/lapel-sync. Les tranches pleine qualité vont dans <SYNC_OUT>.

Piège zsh : dans un shell en ligne, $ss:end_sample interprète :e comme un modificateur et mange silencieusement le texte. Écrivez toujours ${ss}.

1. Trouver les rushes et l'audio

Un dossier par vidéo sur <FOOTAGE_DRIVE>. Les fichiers de l'enregistreur se trouvent dans un sous-dossier audio/ :

find "<FOOTAGE_DRIVE>" -maxdepth 4 -iname "*<keyword>*" -not -path "*/.*"
ls "<folder>" "<folder>/audio"

Un Tascam DR-10L, par exemple, écrit 000_YYMMDD.wav, 001_..., fractionné toutes les 15 minutes, plus des jumeaux _D. Les fichiers _D sont la piste de sécurité double, environ 20 dB plus silencieuse. Utilisez les fichiers principaux ; gardez _D pour rapiécer les zones écrêtées.

2. Assembler les fichiers de l'enregistreur

bash <skill>/scripts/stitch.sh "<folder>/audio" "<SYNC_OUT>/lav-master.wav"

Il lit time_reference (échantillons depuis minuit) de chaque fichier BWF et vérifie que chaque fichier commence exactement là où le précédent s'est arrêté. Lorsqu'ils sont contigus en échantillons, c'est une copie de flux sans perte. S'il y a un trou, il insère autant de silence, de sorte que le master reste à l'horloge temps réel, et prévient avec la taille.

3. Transcrire les deux côtés

bash <skill>/scripts/transcribe_sources.sh "<folder>" "<SYNC_OUT>/lav-master.wav" "<work>"

Tout atterrit dans <work>/sync/, gardé en dehors de <work> lui-même pour que sentences.py de paper-edit ne le lise jamais. L'audio de la caméra est d'abord fortement amplifié (highpass=f=120,volume=40dB,alimiter, 16k mono), car il est souvent autour de -65 dB. Ignore ce qui est déjà fait, donc relancez librement.

Le lapel prend environ 8 minutes par heure d'audio. Lancez-le en arrière-plan. Whisper diffuse les timings des mots dans <work>/sync/lav.log, et align.py lit ce journal quand lav.json n'est pas encore écrit, donc l'alignement peut commencer avant que le lapel ne soit terminé. Les clips au-delà du point transcrit signalent simplement "seulement N correspondances de mots" ; relancez une fois terminé.

4. Aligner

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

Écrit <work>/sync/sync.json. La première exécution crée ~/.cache/lapel-sync-venv avec numpy et scipy (le python3 système n'a souvent ni l'un ni l'autre) ; après cela, il se réexécute simplement à l'intérieur.

Comment ça marche, pour que vous puissiez faire confiance ou remettre en question la sortie :

  • Mots d'abord. Des suites uniques de 4 mots qui apparaissent dans les deux transcriptions. Décalage = temps lapel moins temps caméra. Des centaines de correspondances par clip ; groupe le plus dense, garder dans 0,5 s, médiane. Bon à environ 0,1 s.
  • Affinement par forme d'onde. Chaque bloc de 20 s d'audio caméra (blocs de 6 s sur les clips de moins de 40 s), filtré passe-bande 300-3000 Hz à 8 kHz, est corrélé croisé avec le lapel dans +-0,6 s du décalage de mots. Les pics au-dessus de 6x la médiane comptent. Les blocs à moins de 20 ms les uns des autres sont d'accord ; sur les clips de plus de 5 minutes, un ajustement linéaire donne le décalage plus la dérive.

Lisez chaque ligne qu'il imprime : décalage, blocs d'accord, étalement, dérive. Tout clip marqué CHECK BY EAR (moins de 3 blocs d'accord) peut être décalé jusqu'à 0,1 s ; vérifiez-le dans Resolve avant de lui faire confiance. La dérive sur une frame à travers un clip est également signalée.

5. Découper le lapel par clip

python3 <skill>/scripts/slice.py "<work>" "<SYNC_OUT>/lav-master.wav" "<SYNC_OUT>"

Pour chaque clip, il écrit :

  • <SYNC_OUT>/<clip>_lav.wav : 24 bits, fréquence source, échantillon exact à la durée du clip, donc le temps lapel est égal au temps clip
  • <work>/<clip>.wav (16k mono) et <work>/<clip>.json (whisper de la tranche) : ce que lisent paper-edit et video-reels
  • <work>/clips.ndjson avec un champ "audio" pointant vers la tranche

Si l'enregistreur a commencé tard ou s'est arrêté tôt pour un clip, cette partie est remplie de silence et il prévient. Whisper sur les tranches prend quelques minutes ; n'exécutez pas non plus transcribe.sh de paper-edit après (il sauterait de toute façon, puisque les json existent).

6. Vérifier l'écrêtage

slice.py compte les échantillons à ou au-dessus de 0,99 pleine échelle par tranche et imprime la plus longue série. Des centaines de courtes séries (dizaines d'échantillons) sont généralement le limiteur de l'enregistreur qui attrape les pics, pas de la distorsion. Seulement lorsqu'il répertorie des endroits à écouter (séries de 1 ms ou plus), ou que l'utilisateur dit que ça sonne crunchy, rapiécez ces moments à partir du jumeau _D (même timing, remontez-le d'environ 20 dB).

7. Construire dans Resolve

bash .claude/skills/paper-edit/scripts/ensure_resolve.sh

Écrivez <work>/sync/params.json :

{"project":"<Video> - YYYY-MM-DD","work":"<work>","name":"Synced - Full Talk",
 "lut":"<LUT_PATH>"}

lut est optionnel ; supprimez-le si vous n'en utilisez pas. Puis un appel execute_resolve_code :

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

Il crée le projet (ou l'ouvre si le nom existe), importe les clips caméra et les tranches lapel, et construit Synced - Full Talk : chaque clip sur V1 comme image uniquement (mediaType: 1), sa tranche sur A1 comme son uniquement (mediaType: 2), mêmes trames d'entrée et de sortie. recordFrame = début de la timeline + arrondi((décalage - décalage le plus ancien) * 24000/1001), de sorte que les vrais écarts entre les clips restent. LUT sur le nœud 1. L'audio brut de la caméra est laissé de côté. La timeline est en 1080x1920 lorsque les clips sont verticaux, 1920x1080 sinon (remplacez avec width/height). Si le nom de la timeline est pris, il ajoute v2 plutôt que de toucher à l'existante.

Demandez à l'utilisateur de scruter quelques endroits avec des consonnes claires (un "p" ou "t") sur chaque clip. C'est la vraie vérification.

8. Transmettre

Dites à l'utilisateur que la timeline existe, les nombres par clip de l'étape 4 en une ligne chacun, tout ce qui a été signalé, et le verdict d'écrêtage. Puis passez à autre chose : paper-edit (sautez son étape de transcription ; <work> est déjà configuré) ou video-reels.

Faits utiles

  • La corrélation de forme d'onde seule a échoué. La corrélation sur tout le clip et par blocs de 20 s sur une large fenêtre a donné des résultats incohérents lorsque le micro de la caméra était à environ -65 dB moyen dans une pièce réverbérante. Les mots d'abord, puis une recherche de forme d'onde étroite, c'est ce qui fonctionne.
  • L'horloge de la caméra est souvent erronée. Lors des tests, la caméra avait environ 149 s de retard sur l'enregistreur. Certaines caméras (ex. Sony) écrivent creation_time en UTC (se termine par Z), tandis que time_reference BWF d'un enregistreur est local. Traitez creation_time comme un indice approximatif au mieux. La correspondance de mots n'en a pas besoin.
  • La dérive est négligeable sur le matériel testé : environ 0,5 ms/min, 11 ms sur un clip de 21 minutes. Pas de ré-étirement temporel nécessaire. Les clips courts signalent 0 car un ajustement sur quelques secondes n'est que du bruit.
  • La réexécution des scripts a reproduit des tranches construites manuellement à moins de 6 ms.
  • Séquence verticale : par ex. un Sony filmant en vertical enregistre en 4K 23,976 avec une matrice d'affichage rotation=90. Resolve le lit en 2160x3840 sans correction de rotation nécessaire.
  • Exemple d'enregistreur, Tascam DR-10L : 48k 24 bits mono BWF, nouveau fichier toutes les 15 minutes, jumeau de sécurité _D environ 20 dB plus bas.
  • resolve_build.py de paper-edit prend toujours le son du fichier caméra. Sur un tournage lapel, ses timelines portent l'audio brut de la caméra jusqu'à ce qu'il apprenne à lire le champ "audio". En attendant, dites-le à l'utilisateur, ou reliez A1 aux tranches _lav.wav ; les points de coupe sont les mêmes car le temps de tranche est égal au temps clip.
  • Whisper s'exécute avec -oj -ml 1 -sow pour les timings des mots.

Associé

  • paper-edit : le montage brut, exécuté après celui-ci
  • video-reels : lit clips.ndjson ; le champ "audio" lui dit de prendre le son de la tranche (si installé)

Individual skills in this repo

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

beachyphotoandfilm-arch/video-skills

Turn raw talking-head footage into an assembled rough cut inside DaVinci Resolve. Pulls the clips off your footage drive, transcribes them locally, removes failed takes, restarts, asides and dead air, then creates a new Resolve project with two paper-edit timelines ready for your fine trim. Trigger on "paper edit", "cut my raw footage", "make a rough cut", "clean up this video", or when the user points at a folder of raw camera files for a YouTube video.

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