subtitles: Premiere-Pro-Untertitel reparieren
Einmalige Einrichtung: siehe INSTALL.md im Kit-Stammverzeichnis. Mit dem Plugin lautet die Einrichtungszeile
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-Stammverzeichnis aus. Skripte befinden sich im scripts/-Ordner dieser Fähigkeit. Diese Fähigkeit verweist auf die andere als ../rough-cut/....
Was die Fähigkeit tut
Premiere erzeugt ein automatisches Transkript (ein .json-Export), das oft voller Tippfehler ist, vor allem bei Eigennamen (der Name eines Fotografen wird in zwei nicht zusammenhängende Wörter umgewandelt). whisper.cpp transkribiert viel besser. Diese Fähigkeit transkribiert das Video erneut lokal und erstellt dann ein .json im exakten Premiere-Format (direkt wieder importierbar): Namen werden mit Hilfe eines Referenzskripts korrigiert, Satzzeichen und Großschreibung wiederhergestellt, Werkstitel in Anführungszeichen gesetzt. Schließlich werden die Zeitangaben durch Forced Alignment auf das Audio ausgerichtet (whispers Zeitstempel driften).
- JA: lokale Transkription, Namenskorrektur, Satzzeichen und Groß-/Kleinschreibung, Anführungszeichen um Titel, Zeitangaben-Ausrichtung auf das Audio (Forced Alignment), ein Format identisch mit Premiere, bereit zum erneuten Import.
- NEIN: Schneiden oder Grobschnitt des Videos (das ist
rough-cut), Übersetzen, Neusynchronisieren einer bereits korrekten Untertiteldatei,.srt/.vtt-Untertitel (das Format hier ist Premiere-eigenes JSON).
Erwartete Eingaben
- Das exportierte Video aus Premiere (
.mp4/.mov): es enthält das zu transkribierende Audio. - Das Untertitel-
.jsonaus Premiere exportiert: es gibt das Zielformat (Schlüssel,speaker-UUID, Sprache) zum Klonen vor. - Das Referenzskript des Videos, in jeder lesbaren Form (Klartext, Markdown, ein Google Doc, eine Notion-Seite, ein eingefügter Text): die Autorität für die Schreibweise von Eigennamen (Personen, Werke, Orte, Marken). Wenn es keins gibt, fragen Sie danach, oder korrigieren Sie nur die offensichtlichen Tippfehler und behalten Sie whispers Schreibweise für unsichere Namen bei.
Sprache
Typografie (Abstände um Satzzeichen), akzentuierte Buchstaben, Zeichensätze, Anführungszeichen und Rechtschreibnormalisierungen leben in languages/<code>.json (fr und en sind eingebaut), niemals im Code. Die Sprache wird durch --lang <code> ausgewählt, falls nicht, durch die Sprache des Premiere-JSON, falls nicht, durch die im whisper-Transkript aufgezeichnete Sprache, sonst en. Wie die Dateien funktionieren und wie man eine Sprache hinzufügt: ../rough-cut/references/languages.md (gleicher Mechanismus; diese Fähigkeit hat ihren eigenen languages/-Ordner).
Anforderungen (einmal pro Maschine)
whisper-cli + ffmpeg + das Modell ~/Models/whisper/ggml-large-v3-turbo.bin. Siehe ../rough-cut/references/whisper-setup.md (gemeinsame Einrichtung). Überprüfen: which whisper-cli ffmpeg && ls ~/Models/whisper/.
Forced Alignment (Ausrichtung der Zeitangaben auf das Audio, Schritt 6b):
pip3 install --break-system-packages ctc-forced-aligner torch torchaudio unidecode
Ein ONNX-Modell von etwa 1,2 GB wird beim ersten Start heruntergeladen (Cache ~/ctc_forced_aligner/). Überprüfen: python3 -c "import ctc_forced_aligner".
Arbeitsablauf
Die
scripts/...-Befehle unten gehen davon aus, dass Sie im Fähigkeitsordner sind. Das Arbeitsverzeichnis kann zwischen zwei Shell-Aufrufen zurückgesetzt werden: entwedercdeinmal in den Fähigkeitsordner oder jedes Skript mit seinem absoluten Pfad versehen. Arbeitsdateien (Audio, Transkript, Korrekturen) kommen in einen temporären Ordner außerhalb jedes synchronisierten Ordners.
1. Das Video und das Eingabeformat analysieren
Zuerst: das Original sichern. Premiere kann das eingegebene .json bei einem erneuten Export ÜBERSCHREIBEN, und es ist die einzige Wahrheit zur Überprüfung der Zeitangaben in Schritt 7:
cp "<Reel.json>" /tmp/subs_original_premiere.json
ffprobe -v error -show_entries format=duration:stream=codec_type,r_frame_rate \
-of default=noprint_wrappers=1 "<video>"
Notieren Sie die Dauer (das letzte Wort muss hineinfallen) und die fps. Überprüfen Sie dann das eingegebene Premiere-JSON, um das Format zu bestätigen:
python3 scripts/inspect_format.py "<Reel.json>"
Es gibt die Schlüssel (oben/Segment/Wort), die speaker-UUID, die Sprache, die Anzahl der Segmente und den aktuellen Text Segment für Segment (= die Liste der zu korrigierenden Tippfehler) aus. Das erwartete Format ist in references/premiere-format.md dokumentiert: lesen Sie es, wenn die Inspektion ungewöhnliche Schlüssel zeigt.
2. Lokal transkribieren (whisper.cpp)
python3 scripts/extract_audio.py "<video>" /tmp/subs_audio.wav
python3 scripts/transcribe.py /tmp/subs_audio.wav /tmp/subs_transcript.json --model large-v3-turbo --language <code>
Etwa 8 s für 3 Min auf Apple Silicon. Das Transkript hat Segmente mit text (mit Satzzeichen, Groß-/Kleinschreibung) und zeitgestempelten words.
2b. Wenn whisper NICHT interpunktiert hat (kontinuierliche Lieferung): erneut interpunktieren
Bei schnellen Monologen gibt whisper manchmal einen Strom ohne Satzzeichen und ohne Großbuchstaben zurück (Segmente brechen mitten im Satz ab, kein ./,). Klarer Hinweis: build_subs.py meldet eos: 0. Ohne Satzzeichen sind die Untertitel unlesbar. Kurze Überprüfung: python3 scripts/words_of.py /tmp/subs_transcript.json 0 1 2 --plain.
Wenn ja, interpunktieren Sie selbst (es ist eine LLM-Aufgabe, nicht whispers): schreiben Sie den text jedes Segments mit Satzzeichen und Satzanfängen in Großbuchstaben neu, behalten Sie whispers Wörter wörtlich bei: fügen Sie NUR Satzzeichen und Groß-/Kleinschreibung hinzu; lexikalische Korrekturen (Namen, Akronyme) bleiben in corrections.json. Satzzeichen IMMER am Wort befestigt (so?, nicht so ?): ein durch ein Leerzeichen abgetrenntes Zeichen wird zu einem isolierten Token, das die Ausrichtung still fallen lässt (114 ?/! gingen einmal auf einmal verloren). build_subs.py setzt die sprachspezifischen Abstände (für Französisch ein geschütztes Leerzeichen) selbst zurück. Speichern Sie das Ergebnis in einem JSON {index: "interpunktierter text"}, dann:
python3 scripts/repunctuate.py --transcript /tmp/subs_transcript.json --punct /tmp/punct.json --output /tmp/subs_transcript_punct.json
Das Skript lehnt ab, wenn Sie ein Wort hinzugefügt, entfernt oder geändert haben (es zeigt den Unterschied): das hält die Wort-zu-Zeitangaben-Ausrichtung intakt. Achten Sie auf den Fluss über Segmente hinweg: Ein Segment, das einen Satz fortsetzt, beginnt klein, eines, das einen Satz eröffnet, beginnt mit einem Großbuchstaben. Verwenden Sie dieses interpunktierte Transkript für den Rest (--transcript in Schritt 6).
Löschen Sie auch jede Halluzination am Ende des Clips: In der finalen Stille erfindet whisper oft eine Zeile wie einen Untertitel-Credit oder "Vielen Dank fürs Zuschauen" (die typischen Zeilen jeder Sprache sind unter whisper_hallucinations in languages/<code>.json aufgelistet). Löschen Sie es mit einer seq_rule N auf 0. Eine weitere Halluzination: aufeinanderfolgende Segmente mit identischem Text, deren Wörter eine nahezu Null-Dauer haben (start==end), über eine Stille erfundene Wiederholungen ("hier gehen wir" x3). Erkennung: Segmente i und i+1 mit identischem Text und Wörtern der Dauer 0. Behebung: Löschen Sie sie aus dem Transkript vor dem Bau (del segs[i:j]).
3. Das whisper-Transkript und das Referenzskript lesen
Drucken Sie das Transkript Segment für Segment (text) und vergleichen Sie es mit dem eingegebenen Premiere-Text (Schritt 1). whisper korrigiert bereits viel, behält aber Tippfehler bei Namen. Lesen Sie das Referenzskript, um die kanonische Schreibweise von Eigennamen und der darin zitierten Werkstitel zu erhalten.
4. corrections.json erstellen (der intelligente Kern)
Hier wird die Qualität entschieden. Erstellen Sie eine Korrekturendatei, indem Sie das, was whisper gehört hat, mit den Namen des Skripts vergleichen. Untersuchen Sie die wortweise Aufteilung der betroffenen Segmente, um genaue Regeln zu schreiben:
python3 scripts/words_of.py /tmp/subs_transcript.json 2 9 38 # indizierte Token der zu untersuchenden Segmente
Die Ausgabe indiziert jedes Wort (9:Smyth 10:Jones): das ermöglicht es Ihnen, genaue Regeln zu schreiben, ohne die Tokenisierung erraten zu müssen (wie viele Token ein Name einnimmt, Bindestriche beibehalten usw.).
Format von corrections.json (alle Schlüssel optional):
{
"quote_char": "\"",
"normalize_cotes": true,
"seq_rules": [
[["jon","smyth"], ["John","Smith"]],
[["train","park"], ["Trent","Parke"]],
[["arthus","bertrand"], ["Arthus-Bertrand"]]
],
"word_rules": {"macdum": "Magnum", "scholler": "Schoeller"},
"titles": [
{"match": ["the","decisive","moment"], "canonical": ["The","Decisive","Moment"]},
{"match": ["errance"], "canonical": ["Errance"], "sep_comma": true}
]
}
seq_rules: Mehrwortnamen oder 1 zu N / N zu 1. Der Abgleich erfolgt auf den Wörtern in Kleinbuchstaben, ohne Satzzeichen. Verwenden Sie es für jeden Namen, der 2 oder mehr whisper-Wörter umfasst, oder wenn sich die Anzahl der Wörter ändert. Groß-/Kleinschreibung: die Zielwörter werden WÖRTLICH verwendet: Schreiben Sie die endgültige Groß-/Kleinschreibung, die Sie wünschen, einschließlich der Position im Satz (["Heute","sind",...], wenn das Wort den Satz eröffnet, nicht["heute",...]). Gleiche Länge Quelle/Ziel: Satzzeichen (interne Kommas) und Zeitangaben werden indexbasiert beibehalten; unterschiedliche Längen: Zeitangaben werden neu verteilt und nur die Satzzeichen des ersten/letzten Wortes überleben (die internen Kommas ersetzter Wörter gehen verloren: lesen Sie diese Segmente in Schritt 7 erneut). Löschen: Ein leeres Ziel[["uh"], []]entfernt das Wort (heben Sie es sich für echte isolierte Geräusche auf, die whisper verdoppelt hat; korrigieren Sie ein schlecht transkribiertes Wort, anstatt es zu löschen, sonst verlieren Sie einen Teil eines Satzes).word_rules: Ein Einwortname, Groß-/Kleinschreibung erzwungen (Kleinschlüssel zu exaktem Wert).titles: Zitierte Werke (Bücher, Serien, betitelte Fotografien) erhalten automatische Anführungszeichen (öffnend beim ersten Wort, schließend beim letzten) plus einencanonicalfür die korrekte Groß-/Kleinschreibung des Titels.sep_comma: truefügt ein Komma nach dem Titel hinzu (nützlich, wenn mehrere Titel aufeinander folgen). Setzen Sie Werke in Anführungszeichen, nicht Personennamen oder Marken.normalize_cotes: Wendet die Rechtschreibnormalisierungen der Sprachdatei an (normalize_words), für Varianten, die whisper inkonsistent schreibt. Aus, es sei denn, Sie setzen es.french_typography: Der Schalter für die typografischen Abstände der Sprache (der Name ist historisch; er gilt für jede verwendete Sprache). Standard aus der Sprachdatei: für Französisch ein geschütztes Leerzeichen (U+00A0) vor den doppelten Satzzeichen und dem schließenden Anführungszeichen und nach dem öffnenden Anführungszeichen; für Englisch keins. Setzen Sie es nur auffalse, wenn Sie befestigte Satzzeichen wünschen. Wenn Sie in Schritt 2b erneut interpunktieren, MÜSSEN die Satzzeichen befestigt sein (Flop:);build_subs.pysetzt die Abstände selbst zurück.
5. Unsicherheiten MIT dem Benutzer klären (niemals erfinden)
whisper produziert manchmal ein mehrdeutiges oder unverständliches Nicht-Name-Wort. Raten Sie nicht stillschweigend. Listen Sie diese Punkte mit ihrem Zeitcode auf und fragen Sie den Benutzer, was wirklich gesagt wird, und bieten Sie eine Hypothese an, wenn der Kontext oder das Skript eine nahelegt. Unterscheiden Sie:
- Direkt korrigieren: Eigennamen, die durch das Skript bestätigt wurden; offensichtliche und sichere Tippfehler.
- Zuerst fragen: Mehrdeutige Nicht-Name-Wörter oder jede Korrektur, die die Bedeutung ändert (z. B. whisper "wer fühlt" gegen das Skript "ohne": eine Bedeutungs-Umkehrung, melden Sie es, auch wenn das Skript es klärt).
Schreiben Sie den gesprochenen Stil (Slang, Füllphrasen, Wiederholungen) nicht um: Untertitel müssen dem Audio folgen.
Was in die Datei schreiben, während Sie auf die Antwort warten (Sie müssen die Generierung nicht blockieren): Erstellen Sie eine erste Version, die alle sicheren Korrekturen plus Ihre beste Hypothese für die häufigen mehrdeutigen Wörter anwendet (und melden Sie sie), aber behalten Sie whispers rohe Schreibweise für einen unsicheren NAMEN bei, der nicht im Skript vorkommt: Erfinden Sie niemals einen Eigennamen. Liefern Sie diese Version mit der Liste der zu validierenden Punkte (Zeitcodes) und generieren Sie dann neu nach der Antwort, indem Sie corrections.json aktualisieren. Das ist der normale Ablauf: generieren, mit den Fragen präsentieren, verfeinern.
6. Die korrigierte Datei erstellen
python3 scripts/build_subs.py \
--transcript /tmp/subs_transcript.json \
--original "<Reel.json>" \
--corrections /tmp/corrections.json \
--output "<folder>/<name>_corrige.json" [--lang <code>]
Das Skript klont das Format des Originals (sprecher-UUID, Sprache, sortierte Schlüssel, minimiertes UTF-8), setzt Satzzeichen und Groß-/Kleinschreibung zurück, wendet die Korrekturen an, fügt die Anführungszeichen hinzu, berechnet eos neu und gibt einen Validierungsbericht aus.
Schreiben Sie <name>_corrige.json NEBEN das Original, überschreiben Sie niemals den Original-Export (es ist die Quelle des Benutzers). Das Suffix _corrige ist ein Dateiname, auf den sich die Skripte verlassen: behalten Sie es.
6a. Die 2 wiederkehrenden Fallen von build_subs.py überprüfen (jedes Mal)
Zwei in vielen Videos gesehene Fehler, die nach JEDEM Build zu überprüfen sind:
- Dezimalzahlen verdoppelt. whisper teilt
6.6in 2 Token auf (6+.6; ebenso1,33oder4 AMin4+AM); die Wiedereinfügung von Satzzeichen verdoppelt sie in der Ausgabe (1.4 .4,6.6. .6), undseq_rulespassen schlecht (die Normalisierung entfernt kein internes./,). Erkennung: Grep in der endgültigen Ausgabe nach den Mustern\d[.,]?\s+[.,]\d. Behebung: Operation am Transkript VOR dem Build: führen Sie die 2 Token zu einem zusammen ({'text':'1.4','start':a.start,'end':b.end,...}; whisper-Wort-Schema =text/start/end/confidence, NICHTduration), dann neu bauen. - Isoliertes Satzende-Satzzeichen weggefallen. Ein
?/!/:imtextdes whisper-Segments, aber ohne eigenes Wort-Token, verschwindet (How did we do it ?verliert sein?). Erkennung: Vergleichen Siecount('?')(und!,:) zwischen dem whisper-Text und der Ausgabe. Behebung: Bearbeiten Sie das Ausgabe-JSON nachträglich: hängen Sie?(mit dem sprachspezifischen Abstand) an das vorherige Token an.
Wenn Falle 1 erkannt wird, korrigieren Sie das Transkript und bauen Sie neu (Schritt 6). Wenn Falle 2, patchen Sie die Ausgabe direkt.
6b. Die Zeitangaben auf das Audio ausrichten: Forced Alignment (IMMER)
whispers Wortzeitangaben DRIFTEN (gemessen bis zu 7 s zu früh, nichtlinear) bei schnellen, mehrfach aufgenommenen Monologen: whisper quetscht die Stille zwischen den Aufnahmen zusammen, sodass die Stimme NACH dem Untertitel ankommt. Typische Beschwerde: "Wenn das 'Ah' erscheint, höre ich schon den nächsten Satz". DTW (-dtw) ändert nichts (gleiche Offsets), und eine Zeitverzerrung auf spärlichen Ankern verzerrt die bereits richtigen Zonen. Der whisper-Text ist gut, nur seine Zeitangaben sind falsch. Forced Alignment korrigiert das:
python3 scripts/align.py --transcript /tmp/subs_transcript.json --audio /tmp/subs_audio.wav --output /tmp/transcript_aligned.json
Überprüfen Sie das Ergebnis, indem Sie mindestens ein Segment in der Mitte und eines am Ende mit dem Original vergleichen (start/end des Segments gegenüber /tmp/subs_original_premiere.json). Das alignierte Transkript sollte näher an den tatsächlichen Audio-Offsets sein. Wenn es noch driften sollte, führen Sie align.py erneut mit einem anderen Modell aus (--model <name>).