Communitygithub.com

ThomasHMD/rough-cut

Automatischer Rohschnitt von Talking-Head-Aufnahmen (Monologe, gesprochene Videos) für Premiere Pro. Erzeugt ein Final Cut Pro 7 XML (XMEML), dessen Timeline bereits Wiederholungen, Fehlstarts, Stolperer, Füllwörter und lange Stille entfernt hat. Der Originalclip wird nie angetastet.

Was ist rough-cut?

Dieses Skill automatisiert den Rohschnitt von Talking-Head-Aufnahmen für Premiere Pro, indem es Wiederholungen, Fehlstarts, Stolperer, Füllwörter und lange Stille erkennt und entfernt. Es erzeugt ein Final Cut Pro 7 XML (XMEML), das direkt in Premiere importiert werden kann – die Timeline ist bereits bearbeitet, ohne dass der Originalclip je verändert wird. Das Skill unterstützt Premiere Pro als primäre Plattform und nutzt sowohl das Premiere-Transkript (im .prproj) als auch eine Whisper-Transkription als Zweitmeinung, um präzise Schnittpunkte zu bestimmen. Es läuft komplett lokal (kein API-Key, kein Internet nach Modell-Download) und bietet eine detaillierte Pipeline mit mechanischen und semantischen Analyseschritten, ergänzt durch Qualitätskontrollen und einen Report.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ThomasHMD/premiere-rough-cut/tree/HEAD/skills/rough-cut

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

rough-cut: automatischer Rohschnitt für Premiere Pro

Einmalige Einrichtung: siehe INSTALL.md im Kit-Wurzelverzeichnis. Mit dem Plugin lautet die Setup-Zeile bash "${CLAUDE_PLUGIN_ROOT}/install.sh" --data "${CLAUDE_PLUGIN_DATA}"; bei einer manuellen Installation (die vier skills/-Ordner nebeneinander nach ~/.claude/skills/ kopiert) führen Sie bash install.sh aus dem Kit-Wurzelverzeichnis aus. Skripte befinden sich im scripts/-Ordner dieses Skills.

Umfang

  • JA: ein Final Cut Pro 7 XML (XMEML, .xml), dessen Timeline bereits Wiederholungen, Fehlstarts, Stolperer, Füllwörter und lange Stille entfernt hat; ein Markdown-Report; rote Markierungen für noch zu treffende Entscheidungen.
  • NEIN: Ändern des Clips, Transcodieren, Exportieren des Videos, Farbkorrektur, Mischen, Auswahl zwischen zwei Takes über offensichtliche Umformulierungen hinaus (das ist Sache des Editors).

Kernregel: Der Originalclip wird NIEMALS verändert

Das Skill schreibt nur neben den Clip:

  • <clip>_Derush_v1.xml: der zu importierende Schnitt (FCP7 / XMEML);
  • <clip>_Derush_v1.report.md, <clip>_Derush_v1.log.txt;
  • <clip>_Derush_v1_work/: der Arbeitsordner, der behalten wird (Transkripte, Zwischenschnitte).

Das XML verweist auf den Clip mittels absolutem Pfad (file://localhost/...): Premiere referenziert ihn nur. Ein neuer Durchlauf erstellt v2, v3... ohne etwas zu überschreiben.

Was der Benutzer tut (3 Schritte)

  1. In Premiere: Clip importieren, Transkription ausführen (Textbedienfeld > Transkribieren), Projekt speichern. Das Transkript ist dann IN der .prproj: Den Benutzer nie auffordern, es zu exportieren.
  2. Claude den Pfad des Clips und das Referenzskript des Videos geben, falls vorhanden (Klartext, Markdown, ein Google Doc, eine Notion-Seite, alles Lesbare). Das Skript dient nur dazu zu erkennen, ob eine Wiederholung beabsichtigt ist. Ohne Skript funktioniert der Durchlauf trotzdem; beabsichtigte Wiederholungen werden dann zu Flags statt zu Schnitten.
  3. Das .xml importieren (Datei > Importieren). Eine Derush_vN-Sequenz erscheint, bereits bearbeitet: Die Schnitte fehlen in der Timeline (Clips enden aneinander, nichts zum Schließen), und Zweifel bleiben als aktive Clips mit einer roten Markierung.

Nichts weiter fragen: Sprache, Cliptyp und Optionen werden abgeleitet (siehe unten), und eine Frage lohnt sich nur, wenn der Cliptyp wirklich mehrdeutig ist.

Sprache

Alles Sprachspezifische (Füllwörter, Fehlstartphrasen, Slate-Muster, verwaiste Konnektoren, zu schneidende Opener, Whisper-Halluzinationen, die Grundtexte der Markierungen) befindet sich in languages/<code>.json, niemals im Code. Französisch (fr) und Englisch (en) sind integriert. Die Sprache wird gewählt durch --lang <code>, sonst die im Transkript aufgezeichnete Sprache, sonst en. Details und wie man eine Sprache hinzufügt: references/languages.md.

Pipeline v2: Take-Auswahl (der normale Weg)

Das Erkennen von Defekten allein (v1, unten) erreicht maximal etwa 57% Recall, weil Whisper wiederholte Takes stillschweigend dedupliziert: sein Anti-Loop-Decoder behandelt einen wörtlich wiederholten Satz als Halluzination und transkribiert ihn einmal. Dies kann nicht durch Konfiguration behoben werden. Premiere's Transkript behält jeden Take wortwörtlich, und seine Wortanfänge driften nach langen Stillephasen nicht (Whisper tut das). Daher:

SchrittToolRolle
1extract_prproj_transcript.py project.prproj words_premiere.json [--rush CLIP.MOV].prproj zu words_premiere.json (PRIMÄRE Quelle). Exit-Code 2, wenn das Projekt kein Transkript hat: Benutzer bitten, es auszuführen und das Projekt zu speichern. Fallback: parse_premiere_transcript.py bei manuellem JSON-Export
2extract_audio.py + transcribe.pyWhisper = ZWEITMEINUNG (Text überprüfen, nie die Grenzen)
2bcalibrate_premiere_times.pyPremiere-Transkript an das Audio neu ausrichten. Bei JEDEM Rohschnitt ausführen, direkt nach der Audio-Extraktion (lässt alles in Ruhe, wenn das Transkript zeitlich korrekt ist). Misst den Offset durch Kreuzkorrelation, fensterweise; ein Drift von 1,8 s am Ende eines 21-minütigen Clips wurde beobachtet. Symptom, wenn vergessen: silence_cuts.py meldet Dutzende „suspicious noise"
3Claude im Kontextsemantische Analyse: Wiederholungen, Fehlstarts und Stolperer erkennen durch Vergleich von Premiere-Transkript mit dem Skript und mit Whisper. Regeln unten
4silence_cuts.pyStille >= 1,0 s zwischen Premiere-Wörtern, Wortenden an den Schallpegel neu ausgerichtet, Aufzählungsschutz (kurze Pausen zwischen zwei kurzen Blöcken = beabsichtigter Rhythmus), laute Zone: Flaggen oder Schneiden (siehe unten). Standardwerte sind gegen fertige Schnitte kalibriert: ohne erneute Messung nicht ändern (siehe references/lessons.md, „Measuring")
5apply_takes.py <work>Die in Schritt 3 entschiedenen Takes werden in takes.json geschrieben (Wortindizes; manuelle Grenzen oder Schnitte in Sekunden sind optional). Das Skript setzt Grenzen in Energietälern, führt sie mit der Stille zusammen, schmilzt die stummen Fragmente zwischen zwei Schnitten, richtet jede Clipkante am tatsächlichen Schall aus und flaggt ein isoliertes Geräusch unter 0,25 s an einer Clipkante, schreibt cuts_final.json. protect (Stille behalten) nur, wenn der Benutzer fragt
6build_premiere_xml.pyXMEML. Option meta["audio_file"]: Audio auf eine vollständig verarbeitete WAV-Datei verweisen (siehe bekannte Grenzen). Mehrere Clips: ein XML pro Clip, dann merge_xml.py output.xml "name" a.xml b.xml = eine einzelne Sequenz, Ende an Ende
6bDer Schnitt, erneut transkribiertEnd-to-End-Prüfung: Die behaltenen Intervalle von audio.wav verketten, Whisper darauf ausführen und den Text MIT den Schnittpunkten lesen. Fängt ein, was die anderen Prüfungen übersehen: im Schnitt verbliebene Stille (ein 8-s-Clip für 3 Wörter), abgeschnittene Wörter, ein überlebender Fehlschlag-Take
7qc_repeat_scan.pydeterministische Prüfung: Exit-Code 2, wenn ein wiederholtes 5-Gramm innerhalb von 30 s im Schnitt überlebt, oder wenn zwei Wörter, die einer Pause oder einem Schnitt folgen, bereits weniger als 8 s Schnittzeit zuvor gesagt wurden (ein Take mit Variante wiederholt). Jeder Treffer wird gegen das Skript und nach Gehör geprüft (hear.py): überlebender Take (den LETZTEN behalten) ODER beabsichtigte Rhetorik (Anapher, Aufzählungen)
7bmontage_qc.py <work>Das Audio des Schnitts wird transkribiert und Clip für Clip gelesen, Premiere-Wörter (P) gegen Whisper (W): Exit-Code 2 bei einer Leerstelle > 1,6 s oder einem Fragment < 1 s. Eine zweifelhafte Kante wird mit hear.py audio.wav 12.3-14.0 ... geprüft (Whisper auf isolierten Scheiben)
8report_v2.pyReport: Dauer des SCHNITTS und des Clips, Takes, Zweifel; --notes für „mit Absicht behalten" und Passagen, die heikle Punkte des Skripts berühren

Schritt 3, die Entscheidungsregeln

Harte Regeln:

  • Wiederholter Text: den LETZTEN Take behalten (auch wenn er weniger sauber ist als ein früherer);
  • Stolperer: das längste zusammenhängende Stück behalten;
  • Zweifel: flag, niemals disable. Unter-Schneiden schlägt immer Über-Schneiden: einen Schnitt hinzuzufügen ist einfach, eine fehlende Passage wiederherzustellen die Hölle.
  • Schnittgrenzen an Premiere-Wörtern ausrichten, mit etwa 0,15 s Luft vor dem ersten behaltenen Wort.

Aus echten Schnitten gelernte Regeln:

  • Jede Insel unter 2 s, die zwischen zwei Take-Schnitten eingeklemmt ist, wird abgehört (hear.py). Es ist fast immer ein Fehlstart. Niemals nach Premiere-Text beurteilen: Ein Atemzug kann Wörter in Premiere tragen, und eine Whisper-Halluzination der Art „Thanks for watching" bedeutet, dass es gar keine Wörter gibt.
  • Eine Stille mit Geräusch, die kein Satz des Skripts ist (ein Nebensatz, ein „hier geht's los", Hantieren an der Kamera) wird geschnitten, nicht geflaggt.
  • Ein Füll-Opener am Satzanfang (die „openers"-Liste der Sprachdatei, z.B. „Also," oder „Nun,") wird geschnitten.
  • Wörtliches Stottern innerhalb eines Satzes („Es ist es ist") wird deaktiviert. Aber ein Name, der auf beiden Seiten eines Punkts wiederholt wird („weniger dokumentiert als Nikon. Nikon hat viele Doku") ist kein Stottern: Premiere könnte es als Doppelung geschrieben haben. hear.py die Scheibe vor jedem Ein-Wort-Schnitt.
  • Verwaister Konnektor (ein isoliertes „Und / Also / Aber") direkt vor einer Schnittstille wird in den Schnitt einbezogen. Gleiches gilt für jedes einzelne Fehlstart-Wort, das zwischen einem Schnitt und einer Pause gefolgt von einem weiteren Angriff eingeklemmt ist.
  • Ein unsinniges Wort im Premiere-Transkript ohne Whisper-Äquivalent innerhalb eines redundanten Nebensatzes ist ein Stolperer: zumindest flaggen.
  • Füllphrase ohne Informationsgehalt, die den nächsten Satz wiederholt: nur flaggen (es ist redaktionell).
  • Ein „Take" kann das Ende des vorherigen Satzes sein, von Premiere schlecht datiert (ein Wort 5 s lang). Der Whisper-Text des Schnitts zeigt es.
  • Premiere teilt manchmal einen Satz in zwei: Ein Zwei-Wort-„Fehlstart" kann der Beginn des nächsten Satzes sein.
  • Premiere übersieht kleine gemurmelte Wörter: Das Schneiden eines wiederholten Satzes kann einen verwaisten Lead-In hinterlassen. Zuerst die Scheibe abhören (hear.py); die Grenze von Hand setzen (6. Element eines Eintrags in takes.json).
  • Ein einzelnes verdoppeltes Wort („the the"): Die Grenze kann das Wort davor verschlucken, weil Premiere beide im selben Atemzug datiert. Auf die Nahtstelle hören (ffmpeg atrim der beiden behaltenen Stücke, dann hear.py).
  • Eine Naht zwischen zwei Clips: Das Ende von Clip 1 und der Anfang von Clip 2 werden zusammen abgehört. Ein Satz, der am Ende von Clip 1 begonnen und am Anfang von Clip 2 wiederholt wird, wird ab seinem ersten Wort geschnitten.
  • An die Kamera gerichtete Anweisungen für den Editor („das ist für dich, setz hier etwas Grafik") werden als Anweisungen geschnitten und im Report aufgelistet, weil sie sagen, wo illustriert werden soll.
  • Nach dem Schneiden eines Takes den Angriff des behaltenen Takes abhören (ein erstes Wort kann gefressen werden, wenn Premiere zwei davon hat).

Das Premiere-Transkript befindet sich in der .prproj

Die .prproj ist gzipptes XML, das einen Block enthält: <ExternallyProvidedTranscriptDocument><TranscriptData Encoding="base64">, dessen Nutzdaten ein FlatBuffers-Puffer sind. extract_prproj_transcript.py dekodiert ihn:

Segment -> f0 i64 start_ticks, f3 vector<Word>, f4 string language
Word    -> f0 i64 start_ticks, f1 i64 duration_ticks, f2 string text, f3 f32 confidence
Premiere ticks = 254016000000 pro Sekunde

Elemente mit leerem Text sind die von Premiere markierten PAUSEN (ihre Dauer umfasst die gesamte Stille). Das Skript verwirft sie; sonst wäre jede Lücke zwischen Wörtern 0 und silence_cuts.py fände nichts (Symptom: „gaps > 1s: 0" und Wörter 39 s lang).

Mehrere Clips in einem Projekt: Die .prproj enthält ein Transkript PRO Clip. --rush NAME.MOV wählt das aus, das zur Dauer des Clips passt (ohne wird das längste gewählt, mit einer Warnung). Es vergleicht den Start des letzten Wortes, mit einer Drift-Toleranz von 0,3% der Dauer. Prüfen, dass sich die Wortanzahl zwischen den Clips unterscheidet. Ein Arbeitsordner pro Clip, dann merge_xml.py.

Zwei Fallen in diesem Transkript:

  1. Es kann relativ zur Datei driften: Schritt 2b. Schnitte erfolgen in DATEI-Zeit (das liest das XML), also werden die Wörter korrigiert, nie umgekehrt.
  2. Wortdauern können die folgende Stille verschlucken: Die Stille existiert dann nicht mehr zwischen Wörtern und wird nicht geschnitten. silence_cuts.py bringt diese Wörter auf ihr echtes Ende zurück (trim_overflow). Niemals einem Premiere-Wortende trauen; nur die Anfänge sind zuverlässig.

Weitere Fallen (Wörter, die in einer Stille datiert sind, stumme Fragmente, winzige Inseln): references/lessons.md.

Take-Schnittgrenzen: am nächsten Energietal des Wortanfangs, mit 0,12 s Luft vor dem Angriff des behaltenen Wortes. Schnitte durch Wortindizes beschreiben, nicht durch Sekunden: Sie überleben eine Neuaustrichtung.

Die v1-Pipeline (unten) bleibt der Fallback, wenn es kein Premiere-Transkript gibt (Warnung, dass wortwörtliche Wiederholungen wahrscheinlich übersehen werden).

Maschinenanforderungen

Wird beim Start geprüft; falls etwas fehlt, auf INSTALL.md verweisen (references/whisper-setup.md nur für Whisper).

brew install whisper-cpp ffmpeg
mkdir -p ~/Models/whisper
curl -L -o ~/Models/whisper/ggml-large-v3-turbo.bin \
  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo.bin

Python 3 mit numpy (sonst nichts). Kein API-Key, kein Konto, nichts verlässt die Maschine nach dem Modell-Download.

Pipeline v1 (Fallback, 8 Stufen)

Ausgeführt durch scripts/derush.py. Jede Stufe schreibt in <clip>_Derush_vN_work/, neben dem Clip, niemals gelöscht (Fortsetzung und Inspektion bleiben möglich).

#SkriptRolle
1derush.py (Einstieg)ffprobe-Metadaten, Versionsnummer
2extract_audio.pyffmpeg zu audio.wav 16 kHz mono
3transcribe.pywhisper.cpp zu transcript.json
4mechanical_cuts.pyWortlisten und Muster der Sprachdatei zu cuts_mechanical.json
5semantische Analyse (Claude)zu cuts_semantic.json (siehe unten)
6merge_cuts.pyZusammenführen, auf Wörter ausrichten, Scores zu cuts_final.json
7build_premiere_xml.pyzu .xml (XMEML / FCP7)
8build_report.pyzu .report.md

Stufe 5: semantische Analyse

Das Skript schreibt prompt_semantic.txt und stoppt. Das ist der normale Weg: Claude, der das Skill ausführt, macht dann Folgendes:

  1. prompt_semantic.txt vollständig lesen;
  2. das Transkript gemäß den Regeln im Prompt analysieren;
  3. das JSON in cuts_semantic.json schreiben (Pfad im Prompt angegeben);
  4. fortsetzen: derush.py <clip> --resume-from=6 --work-dir=<work>.

Wenn cuts_semantic.json bereits existiert, wird diese Stufe übersprungen.

Entscheidungen auf drei Ebenen (die Philosophie des Skills)

Jeder vorgeschlagene Schnitt hat eine Konfidenz zwischen 0 und 1.

  • disable: Die Passage wird aus der Timeline entfernt, nicht deaktiviert. build_spine_clips() erstellt die Sequenz durch Subtraktion: Nur die behaltenen Intervalle bleiben übrig, Ende an Ende, und die Sequenzdauer ist die Summe der behaltenen Intervalle. Das Äquivalent eines bereits angewendeten „Ripple Delete". Schwellenwerte: >= 0,85 für einen mechanischen Schnitt, >= 0,92 für einen semantischen Schnitt (ein LLM überschreitet oft seine Grenzen).
  • flag (0,6 bis 0,85): Kein Schnitt. Die Passage bleibt als aktiver Clip, mit einer roten Sequenzmarkierung („DOUBT (conf X): Grund") an der richtigen Stelle. Der Benutzer entscheidet.
  • ignore (< 0,6): Nichts, um die Timeline nicht zu überfluten.

Diese Semantik niemals umkehren. Deaktivierte, ausgegraute Clips zum manuellen Löschen auszuliefern, verlagert die Arbeit auf den Benutzer, anstatt sie zu entfernen: Das Versprechen ist eine direkt verwendbare Sequenz.

Schnittarten

  • filler: Füllwörter („ähm", „äh"...) und Satz-...

[...für die Übersetzung abgeschnitten]

Individual skills in this repo

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

Verwandte Skills