Communitygithub.com

aion88/derush

Dérusher une vidéo parlée (face caméra, vocal, screen rec) : couper les silences, les euh/hum/mmh, les bégaiements, les faux départs et les phrases reprises. Sortie = un MP4 monté propre, un export prêt à poster et le rapport des coupes.

Qu'est-ce que derush ?

Cette skill permet de réaliser un montage « jump cut » automatique d'une prise de parole (vidéo ou audio seul). Elle découpe les silences, les euh/hum/mmh (écrits et non écrits par le modèle ASR), les bégaiements, les faux départs, les phrases reprises et les consignes de régie, tout en préservant le contenu légitime. Le processus s'articule autour de plusieurs commandes (prep, words, edit, render, export, etc.) et d'une rubrique de détection des rétractions (THE RETRACTION-DETECTION RUBRIC) ; l'étape 6 est manuelle et nécessite que l'agent lise le transcript mot à mot pour écrire le fichier retraction_cuts.json. La skill supporte les vidéos et les fichiers audio (m4a, mp3, wav, aiff, caf) ; elle utilise par défaut Qwen3-ASR pour la transcription, avec un fallback sur Whisper. Le résultat est un MP4 monté (ou m4a pour l'audio seul), un export prêt à poster (1080x1920, 30 fps, -14 LUFS) et un rapport détaillé des coupes (cuts.md). Les plateformes compatibles incluent Claude Code et tout agent capable d'exécuter les scripts du dépôt (bash, Python). Le fonctionnement est basé sur plusieurs passes : détection des silences, alignement forcé CTC, détection des fillers (euh/mmh), puis édition manuelle (via derush edit ou derush studio) pour les faux départs et les rétractions sémantiques.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aion88/derush/tree/HEAD/skill

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 derush ?

Montage « jump cut » automatique d'une prise parlée. Ne fait QUE la coupe et l'export : pas de sous-titres. Cette skill embarque la rubrique de rétraction ci-dessous ; les scripts (fillers, prune, cut) sont dans le dépôt.

Les vidéos vivent dans $DERUSH_OUT_ROOT/<STEM>/ (défaut ~/Movies/Derush, voir derush config show).

Un audio seul (m4a, mp3, wav, aiff, caf) passe la même chaîne : le montage sort en <STEM>.derush.m4a, l'export en <STEM>.export.m4a (-14 LUFS) ; fcpxml, logos et look n'existent pas pour lui.

Les trois commandes

derush prep "<video>"          # range la source dans $DERUSH_OUT_ROOT/<STEM>/, audio, silences, transcription (qwen),
                               # alignement, euh, trous, contrôle des trous. ~1.5x la durée
derush words <STEM>            # transcript mot à mot avec bornes : l'étape 6 se lit là-dessus
derush studio                  # TOUT dans le navigateur : déposer une vidéo brute, derush, montage par le
                               # texte, montage serré proposé, rendu. Parole dans un trou = gardée, barrable
derush edit <STEM>             # montage par le texte : page locale, barrer des mots (Suppr), rattraper un
                               # euh/silence (Entrée), Valider → retraction_cuts.json + restore.json
                               # « Proposer un montage serré » : Claude propose des coupes (redites,
                               # digressions, reprises), en orange, rien n'est coupé sans son OK
derush render <STEM>           # fusion + garde + coupe + retranscription de la sortie + cuts.md
derush logos <STEM>            # optionnel : logos.json → <STEM>.logos.mp4, export le prend s'il existe
derush fcpxml <STEM>           # <STEM>.fcpxml, écrit aussi par render : timeline Resolve, clips sur la
                               # source entière, un bord tiré rend ce qui a été coupé
derush export <STEM>           # <STEM>.reel.mp4 : 1080x1920, 30 fps, -14 LUFS, prêt à poster

Logos (derush logos) : $DERUSH_OUT_ROOT/<STEM>/logos.json = {"cues":[{"logo":"canva","t":14.27}]}, t lu dans derush words (instant SOURCE, converti par keep.json). Fichiers dans $DERUSH_OUT_ROOT/_logos/src/<logo>.svg|png (détourés, fond transparent ; sans fichier, carte texte). Carte blanche arrondie 30 % de largeur, en haut à GAUCHE par défaut (face caméra : le visage occupe le tiers haut centré), 2 s, fondu 0,2 s ; une liste dite vite range les cartes côte à côte. Contrôle : extraire une image par cue et la REGARDER. IMG_4596 (2026-10-11) : Canva ×2, Microsoft 365, Gamma, Higgsfield (« Xfield » dans le transcript : lui demander les noms, whisper n'en connaît pas la moitié).

derush = bin/derush du dépôt. Options de prep : --lang en, --noise -40 (voix faible), --min 0.3 --pad 0.08 (plus serré), --min 0.8 --pad 0.2 (plus posé). Deux vidéos : lancer les prep à la suite en arrière-plan, lire les words pendant ce temps.

Ce qui est coupé, et qui décide

CoucheSignalQui décide
Silenceswaveform, silencedetect (pas les trous whisper, trop grossiers)script
(prérequis) vraies bornes de motsalignement forcé CTC sur le son (align_words.py)script
euh / hum / hein écrits par whisper, bégaiements « je je », « et et »timestamps mot (detect_fillers.py)script
euh / mmh NON écrits (la majorité)trou non silencieux entre 2 mots (gap_fillers.py)script
faux départs, phrase reprise, « non attends », mot abandonné, consignes dites à la caméralecture du transcriptTOI, étape 6

Prime directive de la skill : une coupe fausse de vrai contenu est la pire faute. Dans le doute, on garde, et on le dit dans cuts.md (« gardé exprès »).

Étape 6, la seule à la main : les faux départs

Lis derush words <STEM> (mot@début-fin, ? = borne interpolée, pas alignée) et écris $DERUSH_OUT_ROOT/<STEM>/retraction_cuts.json = {"retraction_cuts":[{start,end,cue_text,rationale}]}. Rubrique : « THE RETRACTION-DETECTION RUBRIC » plus bas dans ce fichier, avec ces cas du parlé spontané :

  • Faux départ « je vais... on va voir » : couper « je vais » jusqu'au début de la reprise.
  • Mot reformulé « c'est un truc, un outil qui » : couper le premier seulement si le second le REMPLACE (pas s'il précise).
  • Phrase reprise de zéro, y compris après un aparté : couper la première tentative entière.
  • Consignes de régie dites à la caméra (« on enlève ça », « pas dans mon micro, non », « on garde ») : ce sont des instructions, pas du contenu. Les appliquer, puis les couper. IMG_4566 : les 40 dernières secondes étaient 3 faux départs et 2 consignes.
  • Ne pas couper : répétition d'insistance (« toujours, toujours »), liste, « en fait » qui ajoute, pause expressive, autocorrection comique (« XXIe et XXIIe siècles. Non, du XXIe »).
  • Bornes, lues dans words : start = milieu entre la fin du dernier mot gardé et le début du premier mot abandonné ; end = début du premier mot gardé − 0.04 s. Pour couper jusqu'à la fin : end = durée de la vidéo.

Pour un transcript long (> 1000 mots), déléguer la lecture à un sous-agent qui rend le JSON, puis relire ses bornes contre words.

Vérifier avant de rendre (re-dériver, pas reconnaître)

render fait les contrôles mécaniques et écrit cuts.md. Ce que TU relis :

  • La section diff de cuts.md (transcript source → sortie). Chaque delete doit être une coupe voulue. Un replace/insert bizarre (« c'est c'est c'est ») est souvent une boucle de whisper : retranscrire la région seule avant d'accuser la coupe.
  • Un trou marqué PAROLE DANS LE TROU par gap_check (fin de prep) : écouter la fenêtre. Si c'est un faux départ, la coupe est bonne. Si c'est du contenu, retirer ce trou de _work/gap_cuts.json avant render.
  • Un euh, un mmh CITÉ est du contenu. « les silences, les mmh », « surtout sur les euh » : le mot est l'objet de la phrase, il reste. Après « les », « des », « un », « sur les » devant un euh/mmh/hum, écouter et retirer le trou qui le couvre. Ne jamais traiter « sur les » comme un faux départ : la phrase finit sur le euh. (2026-10-27, A001_10272011_C008.)
  • Transcription : Qwen3-ASR par défaut depuis le 2026-11-04 (transcribe_qwen.py, DERUSH_ASR=whisper pour revenir ; qwen absent ou en panne → whisper, dit dans le log). Qwen écrit les bégaiements et faux départs que whisper fond (C010 : « des des trucs », « j'aurais pas mes, j'aurais pas mes, tous mes »), donc ils apparaissent dans derush words et dans derush edit. Il n'écrit pas plus les euh : gap_fillers.py reste. Plus faible sur les noms propres (« claudito » → « claudio »).
  • Faux départ fondu par whisper : whisper peut n'écrire qu'une fois une phrase dite deux fois. IMG_4543 : « je t'en mets… je vais mettre » transcrit « je vais mettre ». Une phrase qui sonne bancale à un raccord dans la sortie = retranscrire la source mot par mot à cet endroit.
  • Sigles, noms de domaine, chiffres : CTC aligne mal les lettres épelées. IMG_4549 : le trou avant « SI » (SpaceX SI) portait le « ès ». Tout trou qui touche un sigle ou un .com : retranscrire la fenêtre, et ne pas le couper au moindre doute. Les tokens à chiffre (« 5h », « J3 ») sont interpolés, jamais alignés.
  • Sync : cuts.md donne l'écart A/V. Au-delà de 40 ms, regarder.
  • Remplir la ligne Sujet de cuts.md.

THE RETRACTION-DETECTION RUBRIC

You (the invoking agent) read derush words <STEM> and write this JSON to $DERUSH_OUT_ROOT/<STEM>/retraction_cuts.json, the file derush render reads:

Detector output contract

{
  "retraction_cuts": [
    {
      "start": 6.4,
      "end": 9.8,
      "cue_text": "Scratch that",
      "rationale": "Reparandum 'runs every time the user opens a file' + cue 'Scratch that'; repair 'it actually runs on session start' is kept."
    }
  ]
}
  • start = where the abandoned thought (reparandum) begins. SEMANTIC judgment; it may fall mid-sentence. Read the exact time off the word timestamps of derush words (see "Boundary anchoring" below). Times are in seconds of the SOURCE video.
  • end = end of the retraction cue (interregnum). The reparandum + cue are BOTH removed; the repair that FOLLOWS is KEPT. In practice end lands at the boundary where the corrected utterance begins.
  • Empty list {"retraction_cuts": []} when no genuine retraction. Decoys and topic-shifts produce NO cut.

The self-repair model (Levelt / Clark & Wasow)

[REPARANDUM] [INTERREGNUM/CUE] [REPAIR]
 abandoned        the cue        replacement
   CUT              CUT             KEEP

The cut = reparandum + cue. The repair is preserved.

Positive test (cut) : ALL must hold

  1. The speaker is invalidating prior content (negating, deleting, or judging it wrong/incoherent), AND
  2. They replace it or drop it : a corrected version follows, or the thought is abandoned, AND
  3. There is an actual reparandum present in the transcript to remove (a cue with no preceding speech to retract → NO cut; see edge case below).

Negative tests (do NOT cut) : any one rejects the candidate

These superficially resemble cues but are not retractions:

  • Time-qualified topic-shift : "forget the budget for a second/for now", "oublie le budget deux secondes". The "for a second/for now" qualifier (often plus a later deferral like "we'll cover it next week") means the prior content is still VALID, just deferred. NO cut.
  • Additive escalation : "en fait c'est encore mieux", "non mais attends, c'est encore plus puissant que ça". "en fait"/"non mais" here UPGRADE the prior claim; it still stands. NO cut.
  • Affirmation : "non mais c'est exactement ça", "actually, that's a good point". The "non"/"actually" intensifies agreement, not correction. NO cut.
  • Procedural pause : "attends, je te montre" / "wait, let me show you". Speech pauses for a demo; nothing is retracted. NO cut.
  • Nuance/scope refinement : "c'est plus subtil que ça", "enfin, c'est un peu plus compliqué". The prior claim is qualified/extended, not discarded. NO cut.
  • Topic-closer : "bref, c'est compliqué", "de toute façon". Closes a chain without invalidating it. NO cut. (bref is ambiguous : only a cut when it is followed by an actual abandonment like "bref, peu importe les critères".)

How far back does the reparandum start?

The start boundary is a semantic judgment:

  • Ask what the speaker is replacing. The reparandum begins where the abandoned idea first diverged from the correct replacement.
  • Restart markers ("je reprends", "let me start over", "non attends je recommence") → wider reparandum: back to the start of the redone stretch.
  • Correction pivots ("non en fait", "actually no", "wait no") → narrow reparandum: just the immediately preceding predicate/clause.
  • Natural topic boundary rule : never cut past a different subject. A valid shared topic-introduction that both the wrong and correct versions build on is KEPT (e.g. a "for the sound installation project…" intro stays; only the wrong technical claim after it is cut).
  • SETUP vs ELABORATION test (keep the last still-true claim). When a setup/intro CLAIM remains true and only a following ELABORATION, ENUMERATION, LIST, or DETAIL is abandoned, the reparandum starts at the elaboration, not the setup. The decisive question is: "is the speaker negating THIS clause, or only what came after it?" If the clause is still true after the repair, KEEP it; begin the cut at the first clause the repair invalidates.
    • "It uses four criteria: A, B, C, D. Anyway, never mind the criteria : what matters is X." → the setup "it uses four criteria" is still TRUE (it does use criteria); only the enumeration "A, B, C, D" is dropped. Cut starts at the enumeration, NOT at "it uses four criteria". Keeping the setup is mandatory : cutting it is a false cut of real content.
    • Contrast: if the speaker negates the setup itself ("it uses four criteria… actually no, it uses none, it's a flat rule"), then the setup IS the reparandum and the cut starts there. Read what the repair replaces.
  • Minimum-cut / conservatism : when unsure how far back, prefer the NARROWER cut. Leaving a slightly imprecise prior clause is far better than cutting a correct sentence.
  • Multi-sentence reparanda: when the abandoned thought spans several sentences or lines of derush words, the cut covers all of them.
  • Boundary anchoring: use the word timestamps, never arithmetic. derush words <STEM> prints every word as word@start-end (? after a word = the bound is interpolated, not aligned on the sound; treat it as less exact). Anchor on those:
    1. start = the middle of the gap between the END of the last word you keep and the START of the first abandoned word.
    2. end = the START of the first word you keep (the repair head) minus 0.04 s. The reparandum and the cue are cut, the repair head is never touched. To cut up to the end of the video, end = the duration of the video.
    3. Cue and repair head in the same sentence (split by "mais", "c'est", "it's", a comma, a dash): end the cut at the last word of the cue, not later. Use the FIRST punctuation that follows the cue, never a later comma inside the repair clause. When the cue carries a trailing comma ("non attends,", "scratch that,"), the words after it are repair and are KEPT.
    4. Reparandum at the tail of one line and the cue at the head of the next: end the cut at the end of the reparandum rather than reaching forward to also grab the cue. A brief leftover cue ("non attends") is harmless; eating the repair head is the cardinal sin.
    5. Interpolated bounds (?): round INWARD (see below).

Skills associés