Zitate: Quellen → Transkripte → Zitate → Cues und Clips
Tool: agent-citations/citekit.py (stdlib Python plus mlx_whisper und ffmpeg). Es überschreibt niemals Eingaben und weigert sich, eigene Ausgaben ohne --force zu ersetzen.
Batch-Struktur
Ein Ordner pro Thema unter active_edits/<thema>/:
sources/video_sources.txt die URL-Liste des Benutzers
sources/audio/<id>.m4a .info.json von yt-dlp (Schritt 1)
sources/transcripts/<id>.json .md Schritt 2
podcast/<ep>.json .md unsere eigene Episode-Untertitel, importiert (Schritt 2b)
sources/quotes.json Schritt 3, von Ihnen geschrieben
sources/citations/ Ausgaben von Schritt 4
1. Herunterladen (der Benutzer führt es aus)
YouTube blockiert anonymes yt-dlp hier. Geben Sie dem Benutzer diesen Befehl, anstatt ihn selbst auszuführen. Er benötigt Firefox-Cookies und die Clients tv/safari, und hält das Audio klein (Whisper braucht nur 16 kHz Mono):
cd active_edits/<thema>/sources && for id in ID1 ID2; do yt-dlp --cookies-from-browser firefox --extractor-args "youtube:player_client=tv,web_safari,mweb" -f "wa/w" -x --audio-format m4a --postprocessor-args "ExtractAudio:-ac 1 -ar 16000" --write-info-json --write-auto-subs --sub-langs en --sub-format json3 --no-overwrites -o "audio/%(id)s.%(ext)s" "https://youtu.be/$id"; done
Für das Backlog eines Kanals: zuerst auflisten, dann auswählen: yt-dlp --flat-playlist --print "%(id)s %(duration_string)s %(title)s" https://www.youtube.com/@KANAL/videos.
Triage der Titel mit Jev (vibe-classification), falls die Liste lang ist.
2. Transkribieren
citekit.py transcribe sources/audio/<id>.m4a: mlx-whisper large-v3-turbo, Wort-Zeitstempel. Der Initial-Prompt ist der Videotitel und die Beschreibung, wodurch die meisten Namensschreibweisen korrigiert werden. Es läuft etwa 85× Echtzeit auf diesem Mac (ein 15-minütiger Durchlauf dauert ~35 s; das Modell wird einmal heruntergeladen).citekit.py captions sources/audio/<id>.en.json3: YouTube-Autountertitel. Sofort, aber ohne Satzzeichen. Der tv-Client speichert sie oft nicht.- 2b. Eigene Episoden:
citekit.py itt EP.itt --id podcastN --media EP.mp4 --out active_edits/<thema>/podcast --fix 'REGEX=>Rechts'. FCP-Untertitel verstümmeln Namen. Für Episode 1:--fix '\bver ?m+[iu]l+e?\b=>Vermeule' --fix '\bvermil\b=>Vermeule' --fix '\bAsian Vermeule=>Adrian Vermeule'. Episode 1 hat auch Wortebenen-Korrekturen, die inpodcast/podcast1.fixes.jsonprotokolliert sind (Schmidt→Schmitt etc.), die beim erneuten Import erneut abgespielt werden.
Korrigieren Sie Fehltranskriptionen während der Arbeit (nicht nachfragen)
Wenn Ihnen ein eindeutiger Hörfehler auffällt (ein Name, ein verstümmeltes Zitat, ein Stottern, das Whisper verdoppelt hat), korrigieren Sie ihn:
citekit.py fix TRANSKRIPT 'alte Wörter=>neue Wörter' [...] [--near SEKUNDEN]. Es bearbeitet <id>.json/.md direkt
(die neuen Wörter teilen die Zeitsteuerung des alten Spans, Übereinstimmungen können Segmente überschreiten, abschließende Satzzeichen bleiben erhalten),
behält die unbearbeitete Engine-Ausgabe als <id>.raw.json und protokolliert jede Korrektur in <id>.fixes.json. transcribe
und itt spielen dieses Protokoll erneut ab, sodass Korrekturen einen erneuten Durchlauf überstehen. Unsicher? Hören Sie sich die Stelle stattdessen noch einmal an, anstatt zu raten:
ffmpeg -ss T -to T2 -i audio.m4a x.wav && mlx_whisper x.wav --output-format txt. Zuerst korrigieren, dann das korrigierte Wort zitieren:
locate sucht im Transkript.
3. Zitate extrahieren (Ihr Urteilsvermögen)
- Lesen Sie das Transkript unserer Episode, falls vorhanden, und listen Sie die Behauptungen auf, die die Moderatoren über das Thema aufstellen, jeweils mit der Episodenzeit. Diese Momente kann ein Clip untermauern oder widerlegen.
- Suchen Sie für jede Behauptung mit
citekit.py search 'regex' sources/transcripts/nach Kandidaten, lesen Sie dann das.mdum den Treffer herum. Lesen Sie auch ganze Vorträge: Die besten Zeilen sind nicht immer die, die die Moderatoren genannt haben. - Ein gutes Zitat ist kurz (5–25 s gesprochen), in sich abgeschlossen, unmissverständlich die eigene Position des Sprechers (nicht
seine Zusammenfassung eines Gegners) und in einer unteren Drittel-Einblendung zitierbar. Behalten Sie die genauen Wörter des Transkripts bei. Bereinigen Sie sie nicht, sonst kann
locatesie nicht finden. - Schreiben Sie
sources/quotes.json:
{"project": "Ep1 Vermeule Zitate", "fps": 29.97, "episode": "../podcast/podcast1.json",
"quotes": [{"id": "publius-weak-exec", "source": "Bw9M01S8MFI", "approx": 1234,
"text": "exact words from the transcript",
"episode_at": 2575, "episode_context": "Moderatoren über Hamilton und den römischen Diktator",
"why": "seine eigene Aussage der These", "tags": ["executive", "Federalist"],
"citation": {"author": "~Adrian Vermeule", "title": "The Publius Paradox", "date": "5 Jun, 2018",
"publication": "Chorley Lecture, LSE"}}]}
episode (relativ zu quotes.json) ist das Transkript unserer Episode. Damit wird episode_at (ungefähr der
Zeitpunkt, zu dem die Moderatoren den Punkt ansprechen) zu einem Einfügepunkt: Das Ende des Moderatoren-Satzes, der zu diesem Zeitpunkt läuft.
Zitieren Sie ganze Gedanken. Wenn der nächste Satz das Bild oder Argument vervollständigt, schließen Sie ihn ein (ein 5–25 s langer Clip
ist das Ziel, keine harte Obergrenze).
citation verwendet standardmäßig Videotitel, Upload-Datum und Kanal. Setzen Sie den tatsächlichen Ort und das Datum (aus der
Beschreibung) einmal pro Vortrag in ein übergeordnetes "sources": {"<id>": {"citation": {...}}}. Ein eigenes citation
eines Zitats überschreibt dies. Autoren erhalten das ~-Präfix der Sendung, und \n bricht einen langen Titel auf zwei Zeilen um.
Überprüfen Sie alles, was er zitiert (Hamilton, Kafka, die Digesten) mit dem Originaltext. Whisper hört plausible falsche Wörter: Im Publius-Vortrag gab es Kafkas „sacrificial pitchers“ als „pictures“ aus.
4. Cues und Clips
citekit.py cues sources/quotes.json rastet jedes Zitat auf Wort-Zeitstempel ein (unscharf; es warnt, wenn die Übereinstimmungsquote
< 0,8 ist) und schreibt in sources/citations/:
| Datei | Zweck |
|---|---|
citations.md | Übersichtsblatt in Episodenreihenfolge: Einfügezeit (wie aufgezeichnet und nach früheren Einfügungen), die Wörter der Moderatoren direkt vor dem Schnitt, das Zitat, Quell-/Clip-Zeiten, YouTube ?t=-Link |
clips.json | Agenten-Schnitt: Quell-Ein/Aus, aufgepolsterte Ein/Aus (Standard 5 s auf jeder Seite, --pad-before/--pad-after, pro Zitat pad_before/pad_after), insert_at, insert_at_after_earlier_inserts, insert_after |
citation_cues.json | agent-motion/titles_fcpxml.py: Zitation V2 untere Drittel, zeitlich auf die Episode mit eingefügten Clips abgestimmt, die erscheinen, während er zu sprechen beginnt. Nicht platzierte Zitate werden Ende an Ende angeordnet |
download_clips.sh | der Benutzer führt es aus: Video in voller Qualität nur für diese aufgepolsterten Bereiche (--download-sections) |
Dann schneidet citekit.py audio-clips sources/citations/clips.json aufgepolsterte Audio-Vorschauen aus dem lokalen
Audio, um sie nach Gehör zu überprüfen. Um die unteren Drittel in FCP zu platzieren, folgen Sie dem Skill motion-graphics:
python3 agent-motion/titles_fcpxml.py sources/citations/citation_cues.json -o citations.fcpxml.
Hinweise
-
transcribedekodiert selbst in 16-kHz-WAV und verweigert Audio, das deutlich kürzer dekodiert wird als das Video. Ein mit einer anderen-ffortgesetzter yt-dlp-Download fügt zwei Codecs in eine .m4a-Datei zusammen (gesehen 2026-10-18: AAC-LC dann HE-AAC), und ffmpeg verwirft stillschweigend alles nach dem Wechsel. Laden Sie erneut mit--no-continueherunter. Setzen Sie niemals einen Download über Formatänderungen hinweg fort. -
Überprüfen Sie einen Clip nach Gehör oder kostengünstig:
mlx_whisper citations/audio_clips/<id>.m4a --output-format txtsollte das Zitat mit ein paar Sekunden Vor- und Nachlauf zeigen. -
Whisper-Zeitstempel sind auf etwa ±0,3 s auf Wortebene genau. Deshalb gibt es die Clip-Polster. FCP iTT-Untertitel zeitlich nur ganze Zeilen, daher verteilt
ittdie Wörter gleichmäßig über jede Zeile. -
Der Wispr Flow Connector liest nur Meeting Recorder-Transkripte. Er kann keine Datei transkribieren.