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)
- 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. - 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.
- Das
.xmlimportieren (Datei > Importieren). EineDerush_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:
| Schritt | Tool | Rolle |
|---|---|---|
| 1 | extract_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 |
| 2 | extract_audio.py + transcribe.py | Whisper = ZWEITMEINUNG (Text überprüfen, nie die Grenzen) |
| 2b | calibrate_premiere_times.py | Premiere-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" |
| 3 | Claude im Kontext | semantische Analyse: Wiederholungen, Fehlstarts und Stolperer erkennen durch Vergleich von Premiere-Transkript mit dem Skript und mit Whisper. Regeln unten |
| 4 | silence_cuts.py | Stille >= 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") |
| 5 | apply_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 |
| 6 | build_premiere_xml.py | XMEML. 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 |
| 6b | Der Schnitt, erneut transkribiert | End-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 |
| 7 | qc_repeat_scan.py | deterministische 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) |
| 7b | montage_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) |
| 8 | report_v2.py | Report: 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, niemalsdisable. 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.pydie 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 intakes.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 atrimder beiden behaltenen Stücke, dannhear.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:
- 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.
- Wortdauern können die folgende Stille verschlucken: Die Stille existiert dann nicht mehr zwischen Wörtern und wird nicht geschnitten.
silence_cuts.pybringt 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).
| # | Skript | Rolle |
|---|---|---|
| 1 | derush.py (Einstieg) | ffprobe-Metadaten, Versionsnummer |
| 2 | extract_audio.py | ffmpeg zu audio.wav 16 kHz mono |
| 3 | transcribe.py | whisper.cpp zu transcript.json |
| 4 | mechanical_cuts.py | Wortlisten und Muster der Sprachdatei zu cuts_mechanical.json |
| 5 | semantische Analyse (Claude) | zu cuts_semantic.json (siehe unten) |
| 6 | merge_cuts.py | Zusammenführen, auf Wörter ausrichten, Scores zu cuts_final.json |
| 7 | build_premiere_xml.py | zu .xml (XMEML / FCP7) |
| 8 | build_report.py | zu .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:
prompt_semantic.txtvollständig lesen;- das Transkript gemäß den Regeln im Prompt analysieren;
- das JSON in
cuts_semantic.jsonschreiben (Pfad im Prompt angegeben); - 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]