Video Edit
Fork von browser-use/video-use (MIT): lokales whisper.cpp statt ElevenLabs, ein Validierungs-Gate vor jedem Rendern, Hyperframes-Untertitel statt libass-Subtitles und Canvas-Reframing für soziale Werbevarianten.
Prinzip
- LLM denkt vom rohen Transkript + bei Bedarf visuellen Eindrücken aus. Das einzige abgeleitete Artefakt, das seinen Platz verdient, ist ein gepacktes phrasenweise Transkript (
takes_packed.md). Alles andere – Füllwortmarkierung, Retake-Erkennung, Aufnahme-Klassifikation, Betonungs-Scoring – wird zum Entscheidungszeitpunkt abgeleitet. - Audio ist primär, visuelles folgt. Schnittkandidaten kommen von Sprachgrenzen und Stillelücken. Tauche nur an Entscheidungspunkten in visuelle Details ein.
- Fragen → bestätigen → ausführen → iterieren → speichern. Berühre den Schnitt erst, nachdem der Benutzer die Strategie in einfacher Sprache bestätigt hat.
- Verallgemeinern. Gehe nicht davon aus, um welche Art von Video es sich handelt. Sieh dir das Material an, frage den Benutzer, dann schneide.
- Künstlerische Freiheit ist die Voreinstellung. Jeder spezifische Wert, jedes Preset, jede Schriftart, Farbe, Dauer, Tonhöhenstruktur und Technik in diesem Dokument ist ein ausgearbeitetes Beispiel von einem bewährten Video – kein Muss. Lese sie, um zu verstehen, was möglich ist und warum jedes funktioniert hat. Triff dann deine eigenen Geschmacksentscheidungen, basierend darauf, was das Material tatsächlich ist und was der Benutzer tatsächlich will. Das Einzige, was du TUN MUSST, steht im Abschnitt „Harte Regeln“ unten. Alles andere ist dir überlassen.
- Erfinde frei. Wenn das Material eine hier nicht beschriebene Technik verlangt – Splitscreen, Bild-im-Bild, Lower-Third-Identitätskarten, Reaktionsschnitte, Speed-Rampen, eingefrorene Einzelbilder, Überblendungen, L-Cuts, J-Cuts, Speed-Rampen über Atemzüge hinweg, was auch immer – baue sie ein. Die Helfer sind ffmpeg und PIL. Sie können alles machen, was das Format unterstützt. Warte nicht auf Erlaubnis.
- Überprüfe deine eigene Ausgabe, bevor du sie dem Benutzer zeigst. Wenn du sie nicht ausliefern würdest, zeige sie nicht.
Harte Regeln (Produktionskorrektheit – nicht verhandelbar)
Dies sind die Dinge, bei denen Abweichungen zu stillen Fehlern oder defekter Ausgabe führen. Sie sind nicht Geschmackssache, sondern Korrektheit. Merke sie dir.
- Untertitel werden ZULETZT in der Filterkette angewendet, nach jedem Overlay. Sonst verstecken Overlays die Untertitel. Stiller Fehler.
- Pro-Segment-Extrakt → verlustfreies
-c copyKonkat, kein Single-Pass-Filtergraph. Sonst kodierst du jedes Segment doppelt, wenn Overlays hinzugefügt werden. - 30ms Audio-Fades an jedem Segmentübergang (
afade=t=in:st=0:d=0.03,afade=t=out:st={dur-0.03}:d=0.03). Sonst hörbare Knackser an jedem Schnitt. - Overlays verwenden
setpts=PTS-STARTPTS+T/TB, um Frame 0 des Overlays an den Start seines Fensters zu verschieben. Sonst siehst du die Mitte der Animation während des Overlay-Fensters. - Untertitel verwenden Output-Timeline-Offsets:
output_time = word.start - segment_start + segment_offset, wobei jedes Segment seine volle Länge in Frames dauert (captions.pymacht das). Sonst sind Untertitel nach dem Segment-Konkat verschoben. - Schneide niemals innerhalb eines Wortes. Raste jede Schnittkante auf eine Wortgrenze aus dem Transkript ein.
validate_edl.py --fixmacht das mechanisch. - Polstere jede Schnittkante. Arbeitsfenster: 30–200ms. Wortgrenzen sind bereits an die Audiohülle angedockt, aber das Polstern absorbiert, was übrig ist. Enger für schnelle Schnitte, lockerer für cineastisch.
- Nur wortgenaue ASR. Niemals SRT/Phrasen-Modus (verliert Sub-Sekunden-Lückendaten). Niemals normalisierte Füllwörter (verliert redaktionelles Signal).
transcribe.pyfordert whisper auf, „ähm“/„äh“ zu behalten – entferne den Prompt nicht. - Cache Transkripte pro Quelle. Transkribiere nie neu, es sei denn, die Quelldatei selbst hat sich geändert.
- Parallele Sub-Agenten für mehrere Animationen. Niemals sequentiell. Starte N gleichzeitig mit dem
Agent-Tool; gesamte Wandzeit ≈ langsamste. - Strategiebestätigung vor Ausführung. Berühre den Schnitt erst, nachdem der Benutzer den einfachen Plan genehmigt hat.
- Alle Sitzungsausgaben in
<videos_dir>/edit/. Schreibe niemals innerhalb des Skill-Verzeichnisses. - Validiere vor jedem Rendern.
validate_edl.py <edl> --fix, dann rendere nur bei Exit-Code 0. Es erfasst erfundene Quell-IDs, Zeiten nach Datei-Ende, Schnitte innerhalb von Wörtern, fehlende Overlay-Dateien und Overlays, die den Schnitt überdauern – die Fehlermodi, die LLM-geschriebene Schnittlisten tatsächlich haben. - Untertitel sind eine Hyperframes-Ebene, keine eingebrannten Untertitel. Homebrew’s ffmpeg hat kein libass, daher schlägt
subtitlesin der EDL fehl. Verwendecaptions.py;render.pyüberlagert das captions.webm über allen Overlays. - Quell-IDs sind Dateistämme. In
sourcesmuss der Schlüssel der Dateiname des Videos ohne Erweiterung sein (take_Bfürtake_B.mp4), oder<Stamm>.track<N>wenn mit--audio-track Ntranskribiert – so werden Transkripte gefunden. Der Validator meldet einen Fehler bei Nichtübereinstimmung, wenn Untertitel aktiv sind. - Eine Bildrate pro Rendering. Wenn du
--fpsanrender.pyübergibst, übergib das gleiche--fpsanvalidate_edl.pyundcaptions.py. Bereiche werden auf ganze Frames gerundet, damit Untertitel nie abdriften.
Alles andere in diesem Dokument ist ein ausgearbeitetes Beispiel. Weiche ab, wann immer das Material es erfordert.
Verzeichnisstruktur
Das Skill befindet sich in seinem eigenen Verzeichnis (Helfer + Vorlagen neben dieser Datei). Benutzer-Material liegt, wo der Benutzer es ablegt. Alle Sitzungsausgaben gehen nach <videos_dir>/edit/.
<videos_dir>/
├── <Quelldateien, unberührt>
└── edit/
├── project.md ← Speicher; wird jede Sitzung erweitert
├── takes_packed.md ← phrasenweise Transkripte, primäre Leseansicht des LLM
├── edl.json ← Schnittentscheidungen (edl_9x16.json, edl_1x1.json … für Varianten)
├── transcripts/<name>.json ← gecachte whisper.cpp-Transkripte (worteebene + Stille)
├── captions_<edl_stamm>/ ← Hyperframes-Untertitel-Komposition + captions.webm
├── animations/slot_<id>/ ← Quellen + Rendering + Begründung pro Animation
├── clips_graded/ ← Extraktionen pro Segment mit Grading + Fades
├── downloads/ ← yt-dlp-Ausgaben
├── verify/ ← Debug-Frames / Timeline-PNGs
├── preview.mp4
└── final.mp4
Einrichtung
install.sh / setup.sh installiert alles (Homebrew-Pakete, .venv, whisper-Modell, Hyperframes + Chrome). Bei Kaltstart nur überprüfen – und wenn .venv fehlt oder ein Helfer bei einem Import oder einem fehlenden Tool fehlschlägt, führe <dieses Skill-Verz>/setup.sh aus (es ist idempotent), bevor etwas anderes gemacht wird:
PY=<dieses Skill-Verz>/.venv/bin/pythonexistiert. Führe jeden Helfer mit$PYaus, niemals mit dem systemweiten Python (es fehlen numpy/Pillow/OpenCV).ffmpeg,ffprobe,whisper-cliim PATH und ein ggml whisper-Modell. Standard:~/.claude-video-vision/models/ggml-large-v3-turbo.bin; Überschreibung mitVIDEO_EDIT_WHISPER_MODEL.- Node.js 22+ für Hyperframes. Rufe immer die festgelegte Version auf:
npx --yes [email protected] …. yt-dlpund Manim nur bei erster Verwendung. Dieses Skill enthältskills/manim-video/; lies dessen SKILL.md, wenn du einen Manim-Slot baust.- Keine API-Keys. Nichts verlässt den Rechner außer dem einmaligen npm-Download von Hyperframes.
Helfer befinden sich in helpers/ neben dieser SKILL.md. Löse ihre Pfade relativ zum Verzeichnis auf, das diese Datei enthält.
Helfer
Alle nehmen $PY helpers/<name>.py ….
transcribe.py <video>— lokales whisper.cpp, worteebene, Füllwörter behalten, Wortgrenzen an die Audiohülle angedockt, Stille aufgelistet. Pro Quelle gecacht (wiederholt nur, wenn sich die Datei geändert hat).--language deüberspringt die Erkennung;--audio-track Nfür Mehrspuraufnahmen.transcribe_batch.py <videos_dir>— jedes Video in einem Ordner, eines nach dem anderen (whisper sättigt die GPU bereits).pack_transcripts.py --edit-dir <verz>—transcripts/*.json→takes_packed.md(phrasenweise, Unterbrechung bei Stille ≥ 0.5s; niedrigerer--silence-thresholdvon 0.3 für schnelle Sprecher).timeline_view.py <video> <start> <ende>— Filmstreifen + Wellenform-PNG. Bei Bedarf visueller Detail-Blick. Kein Scan-Tool – verwende es an Entscheidungspunkten, nicht ständig.validate_edl.py <edl.json> [--fix]— das Gate vor jedem Rendern (Harte Regel 13).--fixrastet Kanten auf Wortlücken ein, polstert sie (--pad-in,--pad-out), rundet Bereiche auf ganze Frames, berechnettotal_duration_sneu, behältedl.json.bak. Warnungen zu Kanten mit < 30ms Stille überleben--fix: diese Schnitte liegen, wo Wörter aneinandergrenzen – verschiebe sie zu einer echten Pause.captions.py <edl.json>— Output-Timeline-Wort-Untertitel als Hyperframes-Komposition → transparentescaptions.webm, setzt dencaptions-Schlüssel der EDL. Stil-Flags:--accent,--color,--top,--size,--font,--case,--words,--no-pop.render.py <edl.json> -o <aus>— Extraktion pro Segment (frame-exakt, HDR→SDR, Canvas-Reframing, Grading, Fades) → verlustfreier Konkat → Overlays (PTS-verschoben) → Untertitel → loudnorm.--previewfür Qualitätskontrolle,--draftnur für Schnittprüfungen.reframe.py <edl.json> [--apply]— OpenCV-Gesichtserkennung (YuNet) über jeden Bereich →crop_x/crop_y, die den Sprecher zentriert mit Kopffreiheit auf dem EDL-canvashalten. Führe es nachvalidate_edl.py --fixaus, wenn eincanvasdas Seitenverhältnis ändert. Es markiert Bereiche, in denen sich das Gesicht zu sehrBEWEGTfür einen statischen Zuschnitt (teile sie) und Bereiche mitkein Gesicht(wähle den Zuschnitt selbst)."crop_lock": truebei einem Bereich schützt einen manuellen Zuschnitt.scenes.py <video>— OpenCV-Szenenerkennung plusDUNKEL/UNSCHARF-Flags pro Szene →edit/shots/<Stamm>.json. Verwende es für Filmmaterial, das das Transkript nicht strukturieren kann: B-Roll, Produktaufnahmen, Montagen, Multicam-Exporte, stumme Clips. Szenengrenzen sind saubere visuelle Schnittpunkte; markierte Szenen sind selten in einer Anzeige verwendbar.grade.py <in> -o <aus>— ffmpeg-Filterketten-Grading. Presets +--filter '<raw>'für benutzerdefiniert.
Erstelle für Animationen <edit>/animations/slot_<id>/ mit Bash und starte einen Sub-Agenten über das Agent-Tool.
Der Prozess
-
Inventur.
ffprobeauf jede Quelle.transcribe_batch.pyauf das Verzeichnis. Für Quellen mit wenig oder keinem Sprachanteil (B-Roll, Produktaufnahmen) führe stattdessenscenes.pyaus, um deren Szenen zu erhalten. Lese dieQC:-Zeilen, die es ausgibt (auch unterqcin jedem Transkript): Wörter, die auf ≤20ms gestaucht sind oder innerhalb einer Stille beginnen, haben unzuverlässige Zeiten – überprüfe jeden Schnitt in ihrer Nähe mittimeline_view, bevor du ihn verwendest.- Mehrere Sprecher (Anrufe, Interviews): es gibt keine Sprechermarkierungen. Leide Wechsel aus dem Inhalt ab (Fragen vs. Antworten), bestätige dann jede Phrase, die du behalten willst, mit
timeline_view(bei Videoanrufen zeigt die Kachel des aktiven Sprechers, wer spricht). Wenn der Anruf mit einer Person pro Tonspur aufgenommen wurde, transkribiere jede Spur stattdessen mit--audio-track N.pack_transcripts.py, umtakes_packed.mdzu erstellen. Mustere ein oder zweitimeline_views für einen ersten visuellen Eindruck.
- Mehrere Sprecher (Anrufe, Interviews): es gibt keine Sprechermarkierungen. Leide Wechsel aus dem Inhalt ab (Fragen vs. Antworten), bestätige dann jede Phrase, die du behalten willst, mit
-
Vorab-Suche nach Problemen. Ein Durchgang durch
takes_packed.md, um verbale Ausrutscher, offensichtliche Versprecher oder zu vermeidende Formulierungen zu notieren. Einfache Liste, einfließen lassen in die Editor-Briefing. -
Unterhalten. Beschreibe, was du siehst, in einfacher Sprache. Stelle durch das Material geprägte Fragen. Sammle: Inhaltstyp, Ziellänge/-Seitenverhältnis, ästhetische/wiedererkennbare Richtung, Tempo-Gefühl, unbedingt zu bewahrende Momente, unbedingt zu schneidende Momente, Animations- und Grading-Präferenzen, Untertitel-Bedürfnisse. Verwende keine feste Checkliste – die richtigen Fragen sind jedes Mal anders.
-
Strategie vorschlagen. 4–8 Sätze: Form, Auswahl der Takes, Schnittrichtung, Animationsplan, Grading-Richtung, Untertitel-Stil, Längenschätzung. Auf Bestätigung warten.
-
Ausführen. Erstelle
edl.jsonüber das Editor-Sub-Agent-Briefing. Tauche bei mehrdeutigen Momenten intimeline_viewein. Baue Animationen in parallelen Sub-Agenten. Führevalidate_edl.py --fixaus, bis es mit Exit-Code 0 endet. Danncaptions.py, wenn Untertitel gewünscht wurden (Untertitel werden aus den finalen Bereichen erstellt, also nach jeder Bereichsänderung erneut ausführen). -
Vorschau.
validate_edl.py(ohne--fix) →render.py --preview. -
Selbstbewertung (bevor es dem Benutzer gezeigt wird). Führe
timeline_viewauf dem gerenderten Output (nicht den Quellen) an jeder Schnittgrenze (±1.5s Fenster) aus. Überprüfe jedes Bild auf:- Visuelle Diskontinuität / Aufflackern / Sprung am Schnitt
- Wellenform-Ausschlag an der Grenze (Audio-Pop, der den 30ms Fade passiert hat)
- Untertitel, die hinter einem Overlay versteckt sind (Verstoß gegen Regel 1)
- Overlay falsch ausgerichtet oder zeigt falsche Frames (Verstoß gegen Regel 4)
Stichprobe auch: erste 2s, letzte 2s und 2–3 Mittelpunkte – prüfe Grading-Konsistenz, Untertitel-Lesbarkeit, allgemeine Kohärenz. Führe
ffprobeauf dem Output aus, um zu überprüfen, ob die Dauer der EDL-Erwartung entspricht.Messe das Audio, nimm es nicht an:
ffmpeg -i out.mp4 -af ebur128=peak=true -f null -für integrierte Lautheit und echten Peak, sowie RMS pro Abschnitt (Dialog, nur Musik, Endcard). Eine Endcard, die 15 dB unter dem Dialog liegt, oder Effekte lauter als Sprache, sind ein Fehler. Du kannst nicht zuhören: sag es und berichte die Zahlen.Für alles, was der Benutzer veröffentlichen wird (Launch, Promo, Anzeige), starte auch einen Kritik-Sub-Agenten mit der gerenderten Datei, der EDL und etwaigen Referenzvideos, die der Benutzer gegeben hat. Beauftrage ihn zu kritisieren, nicht zu loben: ein Urteil, bewertete Probleme mit Zeitcodes und Nachweisen (Frames, Pegel), und die 5 Korrekturen, die zuerst durchzuführen sind. Neue Augen entdecken, was der Autor nicht mehr sieht – abgeschnittene Pointe-Lines, 0.5s-Memes, unleserliche 28px-Text in Telefongröße.
Wenn etwas fehlschlägt: korrigieren → neu rendern → neu bewerten. Begrenze auf 3 Selbstbewertungs-Durchgänge – wenn nach 3 Durchgängen noch Probleme bestehen, zeige sie dem Benutzer an, anstatt endlos zu loopen. Zeige die Vorschau erst, wenn die Selbstbewertung bestanden ist.
-
Iterieren + speichern. Feedback in natürlicher Sprache, Neuplanung, Neu-Rendering. Nie neu transkribieren. Finales Rendern bei Bestätigung. An
project.mdanhängen.
Schnitthandwerk (Techniken)
- Audio-zuerst. Schnittkandidaten von Wortgrenzen und Stillelücken.
- Peaks bewahren. Lachen, Pointen, Betonungs-Beats. Verlängere über Pointen hinaus, um Reaktionen einzuschließen – das Lachen IST der Beat.
- Sprecherwechsel profitieren von Luft zwischen den Äußerungen. Übliche Werte: 400–600ms. Weniger für schnelles Tempo, mehr für cineastisch. Geschmacksentscheidung.
- Lachen und Reaktionen sind nicht markiert (whisper gibt keine Audio-Ereignisse aus). Finde sie als sprachfreie, aber laute Abschnitte in den
timeline_view-Wellenformen; verlängere über sie hinaus – das Lachen IST der Beat. - Stillelücken sind Schnittkandidaten. Aber nicht alle. Eine Pause von 0,3s während jemand nachdenkt, ist anders als 0,3s zwischen zwei Takes. Unterscheide Dehnungslaute (verbale Pause) von Schnittlücken (Takes trennen).
- Wenn ein Take beginnt, beginne am Wort. Schneide niemals 100ms vor dem ersten Wort eines neuen Takes. Schneide genau an seinem Anfang oder lasse einen Atemzug davor. Schneide niemals innerhalb eines Wortes (Harte Regel 6).
- Jeder Schnitt ist ein ästhetisches Signal. Ein schneller Schnitt an einem Betonungs-Schlag sagt: „Das ist der Moment.“ Ein langsamer Schnitt mitten in einer Stille sagt: „Denk darüber nach.“ Die Schnittgeschwindigkeit IST die emotionale Botschaft.
- B-Roll und Produktaufnahmen bekommen keine Untertitel, es sei denn, der Benutzer wünscht etwas anderes. Stelle stattdessen separat gerenderte Abschnitte über den primären Schnitt.
- Für Werbevarianten („schneide dies in eine 30s Anzeige“): Leite die Zielgruppe (Zuschauertyp, Aufmerksamkeitsspanne, Ausspielkontext – Instagram vs. YouTube Pre-Roll vs. Kino vs. LinkedIn) ab, dann schneide für diesen Kontext.
Editor Sub-Agent Briefing
Dies ist die Einbettung für den Agenten, der die EDL erstellt. Verwende diesen Prompt, wenn du eine EDL-Ausgabe benötigst:
Du erstellst eine EDL (Edit Decision List, v3) als JSON. Arbeite von:
- `<videos_dir>/edit/takes_packed.md` – phrasenweise Transkripte, die primäre Leseansicht
- `<videos_dir>/edit/project.md` – Benutzervorgaben und Sitzungsspeicher
- `timeline_view.py` Ausgaben, falls zutreffend
### Ausgabeformat: gültiges EDL JSON Schema
Erstelle `edl.json` (oder `edl_9x16.json` für Varianten) im folgenden Schema:
#### Top-Level
- `"edl_version": 3`
- `"videos_dir": "<absoluter Pfad zu videos_dir>"` – muss mit der Projektvorgabe übereinstimmen
- `"sources": {}` – Quellobjekte, indiziert nach Dateistamm
- `"segments": []` – schnittbezogene Objekte
- `"overlays": []` – Objekte für Overlay-Animationen
- `"canvas": {"width": <px>, "height": <px>}` – Ausgabe-Abmessungen. Standard: 1920x1080, außer der Benutzer wünscht etwas anderes. Für soziale Varianten passe `canvas` an (9:16 → 1080x1920, 1:1 → 1080x1080).
- `"fps": <xx>` – standardmäßig 30, oder passe an die Quelle an
- `"total_duration_s": <float>` – muss mit der Summe der Segment-Dauern übereinstimmen
- `"captions": {}` – wird von `captions.py` gesetzt, nicht durch den Editor. Lass dieses Feld leer.
- `"loudnorm": {"input_i": <float>, "input_lra": <float>, "input_tp": <float>, "input_thresh": <float>}` – vom vorherigen Rendern. Lasse dies für den ersten Durchgang weg und setze es bei erneuten Rendern aus der vorherigen Ausgabe.
#### Quellen
```json
"sources": {
"<Dateistamm>": {
"path": "<absoluter Pfad zur Videodatei>",
"duration_s": <float>,
"fps": <float>,
"width": <int>,
"height": <int>
}
}
Alle im Projekt verwendeten Quellen müssen hier aufgeführt sein.
Segmente
Jedes Segment extrahiert einen zusammenhängenden Teil einer Quelle:
{
"source_id": "<Dateistamm oder Dateistamm.trackN>",
"source_start_s": <float>,
"source_end_s": <float>,
"in_point_s": <float>,
"out_point_s": <float>,
"duration_s": <float>,
"grade": "<Preset>",
"crop_x": <int>,
"crop_y": <int>
}
source_start_s/source_end_s: absolute Start-/Endzeiten der extrahierten Auswahl in der Quelle.in_point_s/out_point_s: Timeline-Positionen der extrahierten Auswahl im finalen Video. Differenz =duration_s.grade: optional. Eines von:"none","bright","warm","cool","high","soft","vintage","bw","cinematic1","cinematic2","log". Passe für Produktmaterial an: lebendige Sättigung, kontrollierte Lichter.crop_x/crop_y: Pixel-Offset für Zentrierung. Lassen für Standardzentrierung (Rahmen auf, wenn das Quell-Seitenverhältnis vom Ausgabe-Canvas abweicht).reframe.py --applysetzt diese.
Overlays
Nur für benutzerdefinierte Animationen. Für einfache Untertitel nicht verwenden. Jedes Overlay bezieht sich auf einen Slot-Ordner in <edit>/animations/slot_<id>/:
{
"slot_id": 1,
"segment_index": 2,
"start_s": 3.5,
"end_s": 7.2,
"src": "animations/slot_1/animation.webm"
}
Schnittregeln (nicht verhandelbar)
- Wortgrenzen sind deine Schnittkanten. Schneide keinen Frame vor oder nach einer Wortgrenze. Wenn das Transkript sagt, dass ein Wort bei 14.27s endet, ist 14.27s deine Kante.
validate_edl.py --fixwird dich korrigieren, aber verlasse dich nicht darauf; setze es gleich richtig. - Polstere jede Kante. Polstere 50ms vor dem Schnitt auf der rechten Seite des vorhergehenden Segments und 50ms nach dem Schnitt auf der linken Seite des nächsten Segments. Dies absorbiert verbleibende Sub-Frame-Lücken.
- Keine Lücke zwischen Segmenten.
segments[N].out_point_smuss gleichsegments[N+1].in_point_ssein. Keine Überlappungen, keine Lücken. Die Timeline ist lückenlos. - Berechne
total_duration_sgenau. Laufzeit = letztes Segmentout_point_s. - Jeder Schnitt braucht eine Rechtfertigung, basierend auf dem Inhalt des Transkripts. In deinem Begründungsblock (siehe unten) erkläre, warum jeder Keep/Cut/Reword dem Projekt dient.
- Behandle das Transkript als letzten Stand. Wenn die Audionutzung anderes sagt als der visuelle Kontext, hat das Audio Vorrang. Verwende
timeline_view(sofern verfügbar), um deine Entscheidungen zu bestätigen. - Passe den Stil der EDL an. Langsam, poetisch, filmisch → längere Abstände zwischen dichten Segmenten, weichere Übergänge. Schnell, energiegeladen, zeitgesteuert → kürzere Abstände, präzise Timing-Schnitte an Wortgrenzen. Spontan, unterhaltsam → Schnitte lachen, Rededrang bewahren.
Gib alle Überlegungen in einem <thinking>-Block aus, dann die gültige JSON-EDL.
## Grading-Presets
| Preset | Filter | Wirkung | Annahmen über das Material |
|--------|--------|---------|----------------------------|
| `none` | `null` | Roh. Nur für Log-Material oder wenn der Benutzer manuell korrigiert. | Spezifischer Workflow benötigt unbearbeitet. |
| `bright` | `eq=brightness=0.06:contrast=1.1,colorbalance=rs=0.05:gs=0.02:bs=-0.02,unsharp=5:5:0.8` | Weich, luftig, sauber. Geringer Kontrast, leichte Sättigung. | Talking Heads in gutem Licht, Lifestyle-/Wellness-Inhalte. |
| `warm` | `colorbalance=rh=0.15:gh=-0.04:bh=-0.10,eq=saturation=1.15` | Goldener, einladender Look. Verstärkt Hauttöne. | Sonnenlicht-Setups, Interviews, warme Marken (Kaffee, Bildung, persönlich). |
| `cool` | `colorbalance=rh=-0.05:gh=0.02:bh=0.12,eq=saturation=0.9` | Technisch, steril. Unterdrückt Hauttöne. | Tech-Produkte, klinische Inhalte, B-Roll mit kühlem Licht. |
| `high` | `eq=contrast=1.3:brightness=0.02:saturation=1.4` | Lebhaft, knallig. Maximiert visuellen Punch. | Produkt-Demos, Gaming, Social-Clips, die in einem Feed hervorstechen müssen. |
| `soft` | `eq=contrast=0.85:brightness=0.04,unsharp=7:7:0.5` | Weicher, verträumter Look. Reduziert Details, glättet die Haut. | Nahaufnahmen von Gesichtern, romantische/warme Inhalte, Beauty. |
| `vintage` | `colorchannelmixer=rr=0.8:rg=0.2:rb=0.0:gr=0.1:gg=0.7:gb=0.2:br=0.1:bg=0.2:bb=0.7,colorbalance=rh=-0.05:gh=-0.02:bh=0.10` | Warme Highlights, gedämpfte Mitten, verblasste Lichter. 16mm-Feeling. | Narrative, Reisevlogs, ästhetische/lifestyle Clips. |
| `bw` | `colorchannelmixer=rr=0.3:rg=0.6:rb=0.1:gr=0.3:gg=0.6:gb=0.1:br=0.3:bg=0.6:bb=0.1,eq=contrast=1.2` | Hochkontrast-Schwarzweiß. | Künstlerische Abschnitte, Interviews mit starkem Gesichtsausdruck. |
| `cinematic1` | `eq=contrast=1.15:saturation=0.85,curves=red='0/0 0.15/0.10 0.75/0.85 1/1':green='0/0 0.10/0.10 0.80/0.85 1/1':blue='0/0 0.25/0.20 0.65/0.75 1/1'` | Sanfte S-Kurve, gedämpfte Sättigung, getönte Lichter. | Allgemeiner Film-Look für Dialog/Talking Heads. |
| `cinematic2` | `eq=contrast=1.25:saturation=0.70,curves=red='0/0 0.20/0.15 0.70/0.80 1/1':green='0/0 0.10/0.15 0.75/0.80 1/1':blue='0/0 0.25/0.25 0.55/0.65 1/1',colorbalance=rh=0.10:gh=-0.02:bh=-0.08` | Stärkere S-Kurve, wärmere Schatten, tiefes Schwarz. | Emotional intensives Interviewmaterial, starke Beleuchtung. |
| `log` | `null` (# tags hinzugefügt zum Auslösen von False Color / RAW-Look) | Verarbeitungs-Passthrough, bei dem der Benutzer in DaVinci/Resolve korrigiert. | Workflow erfordert Log-Material. |
## Untertitel-Stil-Presets
Übergeben als `--accent <number>` an `captions.py`. Niedrigere Zahlen = höheres energetisches Niveau.
- **0 – Standard (kein Akzent):** weiße Farbe (#FFFFFF), 42px Schriftgröße, unten zentriert. Keine Animation. Sauber, konservativ.
- **1 – Minimal:** weiße Farbe (#FFFFFF), Werbung, reaktionsschnell. 0dp XY, skaliert zwischen 46–64px Schriftgröße. Eine zufriedenstellende Mischung.
- **2 – Bold:** Farbe (#F9FAFB), 48px Schriftgröße, gebrochenes Weiß, fetter Stil, 0dp XY. Minimal und dennoch wirkungsvoll.
- **3 – Mood:** Farbe (#6366F1), 48px Schriftgröße, helles monochromes Blau, in Blöcken anstatt in Wörtern animiert. Für stimmungsvolle, ästhetische Clips.
- **4 – Tight:** Farbe (#FFFFFF), 56px Schriftgröße, 8dp XY, keine Pause, keine leeren Untertitel oder Bindestriche. Für schnelle, enge Bearbeitungen.
- **5 – Warm:** Farbe (#FDE047), 46px Schriftgröße, Gelb mit 0dp XY. Warme, einladende Untertitel, die die Aufmerksamkeit auf sich ziehen.
- **6 – Dual:** Farbe (#00F0FF), 42px Schriftgröße, Hellblau, hervorstechend. Um einen unterhaltsamen, verspielten Ton zu zeigen.
- **7 – Vorlesungsmodus:** Farbe (#FFFFFF), unten zentriert, 2er-Paket, keine Untertitel während Stille. Für Fokus-Lerner oder Referenzen, die Stille erfordern.
- **8 – News:** Farbe (#FFFFFF), 44px Schriftgröße, unten links ausgerichtet. Für Sprecher, die sich in der Aufnahme nicht bewegen.
- **9 – Spooky:** Farbe (#E879F9), 42px Schriftgröße, Magenta-Pop mit 0dp XY. Für stimmungsvolle, gruselige Inhalte.
- **10 – Wort-für-Wort:** Farbe (#FFFFFF), 46px Schriftgröße, 0dp XY, Wort-für-Wort-Stiloutput: Ein Wort nach dem anderen erscheint. Intimer, persönlicher.
- **11 – Kreativ (einfach):** Farbe (#000000), 48px Schriftgröße, unten zentriert. Schwarze Schrift auf hellem Hintergrund. Eine moderne künstlerische Wahl.
Wenn der Benutzer ein bestimmtes Stil-Preset nicht angibt, wähle selbst eines aus, das zur Videostimmung und zum Projekttyp passt.
## Animations-Slots
Jeder Slot ist ein unabhängiger Unterordner `<edit>/animations/slot_<id>/`, der von einem separaten Sub-Agenten erstellt wird. Der Sub-Agent erhält:
- `slot_<id>/brief.md` – was zu bauen ist und wo es in die Timeline passt
- Den Referenz-Frame und das Audio-Sample des Quellabschnitts (von `timeline_view`)
- Die Projekt-Markdown-Datei
Der Sub-Agent gibt zurück:
- `slot_<id>/reasoning.md` – warum diese Animation funktioniert
- `slot_<id>/source/` – Quelldateien (Manim-Skripte, PIL-Befehle, ffmpeg-Filter)
- `slot_<id>/animation.webm` – das gerenderte Overlay (mit Alpha, falls erforderlich)
**Ausgabepflicht:** Das Overlay muss die Quelle der EDL-Overlay-Liste sein (`animations/slot_<id>/animation.webm`).
Starte Sub-Agenten mit dem `Agent`-Tool. Warte, bis alle parallelen Sub-Agenten abgeschlossen sind, bevor du fortfährst.
## Fehlerbehebung
### Installationsfehler
- **Homebrew schlägt fehl:** `brew doctor`, dann führe das Setup erneut aus.
- **whisper-cli nicht gefunden:** Installiere mit `brew install whisper-cpp`.
- **Python venv fehlt:** Lösche `.venv` und führe `setup.sh` erneut aus.
- **Kernel-Erweiterungen:** ffmpeg/whisper benötigen Rosetta 2 oder native ARM-Binärdateien. Führe `arch -arm64 brew …` auf Apple Silicon aus.
### Laufzeitfehler
- **„Overlay-Datei nicht gefunden“:** Der Slot-Ordner existiert, aber `animation.webm` fehlt. Starte den Sub-Agenten für diesen Slot neu.
- **„Quell-ID nicht gefunden“:** `sources`-Schlüssel in der EDL entspricht keinem Dateistamm / keiner Track-Version. Korrigiere `sources` oder die `source_id` des Segments.
- **„Schnitt innerhalb von Wort“:** Führe `validate_edl.py --fix` aus. Wenn es hartnäckig bleibt, liegt die Wortgrenze im Transkript möglicherweise innerhalb einer tatsächlichen Stille – überprüfe mit `timeline_view`.
- **„Audio-Pop“:** Der 30ms-Fade wurde nicht angewendet. Überprüfe, ob `render.py` die neueste Version ist. Erhöhe auf 50ms, wenn das Problem weiterhin besteht.
- **„Untertitel verschoben“:** Bildrate-Inkonsistenz zwischen `render.py`, `validate_edl.py` und `captions.py`. Übergib an alle das gleiche `--fps`.
- **„Zu viele Durchgänge“:** Die Selbstbewertung hat Probleme nach 3 Versuchen nicht gelöst. Markiere dem Benutzer die verbleibenden Probleme und frage nach Anleitung.
## Lizenz
MIT (geerbt vom ursprünglichen Projekt).