Communitygithub.com

huzaifa-hb/video-edit

Bearbeite echtes Filmmaterial per Dialog – komplett lokal. Transkribiere mit whisper.cpp, wähle Takes aus dem Transkript, erstelle eine JSON-Schnittliste, validiere sie, rendere mit ffmpeg, füge animierte Hyperframes-Untertitel und Overlays hinzu, forme auf 9:16/1:1/16:9 um und prüfe das Ergebnis selbstständig.

Was ist video-edit?

Das Skill `huzaifa-hb/video-edit` ist ein Fork von `browser-use/video-use` und bietet eine vollständig lokale, LLM-gesteuerte Videobearbeitungslösung ohne API-Keys. Es transkribiert mit whisper.cpp (Fillwörter inklusive), erstellt eine gepackte phrasenweise Transkription (`takes_packed.md`), aus der der Benutzer Takes auswählt. Eine JSON-Schnittliste (`edl.json`) wird generiert, durch `validate_edl.py` auf Korrektheit geprüft (z. B. keine Schnitte innerhalb von Wörtern, korrekte Quell-IDs) und dann mit ffmpeg gerendert. Dabei werden Hyperframes-Overlays und -Untertitel als transparente WebM-Layer eingefügt, und das Video kann auf gängige Seitenverhältnisse (9:16, 1:1, 16:9) reframed werden. Das Skill beinhaltet eine Selbstprüfung (Self-Eval) mit visuellen und akustischen Checks, bevor das Ergebnis dem Benutzer präsentiert wird. Es eignet sich besonders für Talking Heads, UGC-Inhalte, Testimonials, Gründer-Videos, Aufzeichnungen von Gesprächen, Interviews oder Tutorials, bei denen unbearbeitetes Filmmaterial geschnitten, getrimmt, mit Untertiteln versehen, umgeformt oder in Werbevarianten umgewandelt werden soll (z. B. „Schneide das zu einer 30-Sekunden-Anzeige“, „Entferne die Ähs“, „Erstelle eine vertikale Version“).

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add huzaifa-hb/video-edit

In Ihrer bevorzugten KI fragen

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

Dokumentation

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

  1. 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.
  2. Audio ist primär, visuelles folgt. Schnittkandidaten kommen von Sprachgrenzen und Stillelücken. Tauche nur an Entscheidungspunkten in visuelle Details ein.
  3. Fragen → bestätigen → ausführen → iterieren → speichern. Berühre den Schnitt erst, nachdem der Benutzer die Strategie in einfacher Sprache bestätigt hat.
  4. Verallgemeinern. Gehe nicht davon aus, um welche Art von Video es sich handelt. Sieh dir das Material an, frage den Benutzer, dann schneide.
  5. 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.
  6. 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.
  7. Ü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.

  1. Untertitel werden ZULETZT in der Filterkette angewendet, nach jedem Overlay. Sonst verstecken Overlays die Untertitel. Stiller Fehler.
  2. Pro-Segment-Extrakt → verlustfreies -c copy Konkat, kein Single-Pass-Filtergraph. Sonst kodierst du jedes Segment doppelt, wenn Overlays hinzugefügt werden.
  3. 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.
  4. 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.
  5. Untertitel verwenden Output-Timeline-Offsets: output_time = word.start - segment_start + segment_offset, wobei jedes Segment seine volle Länge in Frames dauert (captions.py macht das). Sonst sind Untertitel nach dem Segment-Konkat verschoben.
  6. Schneide niemals innerhalb eines Wortes. Raste jede Schnittkante auf eine Wortgrenze aus dem Transkript ein. validate_edl.py --fix macht das mechanisch.
  7. 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.
  8. Nur wortgenaue ASR. Niemals SRT/Phrasen-Modus (verliert Sub-Sekunden-Lückendaten). Niemals normalisierte Füllwörter (verliert redaktionelles Signal). transcribe.py fordert whisper auf, „ähm“/„äh“ zu behalten – entferne den Prompt nicht.
  9. Cache Transkripte pro Quelle. Transkribiere nie neu, es sei denn, die Quelldatei selbst hat sich geändert.
  10. Parallele Sub-Agenten für mehrere Animationen. Niemals sequentiell. Starte N gleichzeitig mit dem Agent-Tool; gesamte Wandzeit ≈ langsamste.
  11. Strategiebestätigung vor Ausführung. Berühre den Schnitt erst, nachdem der Benutzer den einfachen Plan genehmigt hat.
  12. Alle Sitzungsausgaben in <videos_dir>/edit/. Schreibe niemals innerhalb des Skill-Verzeichnisses.
  13. 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.
  14. Untertitel sind eine Hyperframes-Ebene, keine eingebrannten Untertitel. Homebrew’s ffmpeg hat kein libass, daher schlägt subtitles in der EDL fehl. Verwende captions.py; render.py überlagert das captions.webm über allen Overlays.
  15. Quell-IDs sind Dateistämme. In sources muss der Schlüssel der Dateiname des Videos ohne Erweiterung sein (take_B für take_B.mp4), oder <Stamm>.track<N> wenn mit --audio-track N transkribiert – so werden Transkripte gefunden. Der Validator meldet einen Fehler bei Nichtübereinstimmung, wenn Untertitel aktiv sind.
  16. Eine Bildrate pro Rendering. Wenn du --fps an render.py übergibst, übergib das gleiche --fps an validate_edl.py und captions.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/python existiert. Führe jeden Helfer mit $PY aus, niemals mit dem systemweiten Python (es fehlen numpy/Pillow/OpenCV).
  • ffmpeg, ffprobe, whisper-cli im PATH und ein ggml whisper-Modell. Standard: ~/.claude-video-vision/models/ggml-large-v3-turbo.bin; Überschreibung mit VIDEO_EDIT_WHISPER_MODEL.
  • Node.js 22+ für Hyperframes. Rufe immer die festgelegte Version auf: npx --yes [email protected] ….
  • yt-dlp und Manim nur bei erster Verwendung. Dieses Skill enthält skills/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 N fü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-threshold von 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). --fix rastet Kanten auf Wortlücken ein, polstert sie (--pad-in, --pad-out), rundet Bereiche auf ganze Frames, berechnet total_duration_s neu, behält edl.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 → transparentes captions.webm, setzt den captions-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. --preview für Qualitätskontrolle, --draft nur 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-canvas halten. Führe es nach validate_edl.py --fix aus, wenn ein canvas das Seitenverhältnis ändert. Es markiert Bereiche, in denen sich das Gesicht zu sehr BEWEGT für einen statischen Zuschnitt (teile sie) und Bereiche mit kein Gesicht (wähle den Zuschnitt selbst). "crop_lock": true bei einem Bereich schützt einen manuellen Zuschnitt.
  • scenes.py <video> — OpenCV-Szenenerkennung plus DUNKEL / 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

  1. Inventur. ffprobe auf jede Quelle. transcribe_batch.py auf das Verzeichnis. Für Quellen mit wenig oder keinem Sprachanteil (B-Roll, Produktaufnahmen) führe stattdessen scenes.py aus, um deren Szenen zu erhalten. Lese die QC:-Zeilen, die es ausgibt (auch unter qc in 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 mit timeline_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, um takes_packed.md zu erstellen. Mustere ein oder zwei timeline_views für einen ersten visuellen Eindruck.
  2. 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.

  3. 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.

  4. Strategie vorschlagen. 4–8 Sätze: Form, Auswahl der Takes, Schnittrichtung, Animationsplan, Grading-Richtung, Untertitel-Stil, Längenschätzung. Auf Bestätigung warten.

  5. Ausführen. Erstelle edl.json über das Editor-Sub-Agent-Briefing. Tauche bei mehrdeutigen Momenten in timeline_view ein. Baue Animationen in parallelen Sub-Agenten. Führe validate_edl.py --fix aus, bis es mit Exit-Code 0 endet. Dann captions.py, wenn Untertitel gewünscht wurden (Untertitel werden aus den finalen Bereichen erstellt, also nach jeder Bereichsänderung erneut ausführen).

  6. Vorschau. validate_edl.py (ohne --fix) → render.py --preview.

  7. Selbstbewertung (bevor es dem Benutzer gezeigt wird). Führe timeline_view auf 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 ffprobe auf 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.

  8. Iterieren + speichern. Feedback in natürlicher Sprache, Neuplanung, Neu-Rendering. Nie neu transkribieren. Finales Rendern bei Bestätigung. An project.md anhä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 --apply setzt 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)

  1. 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 --fix wird dich korrigieren, aber verlasse dich nicht darauf; setze es gleich richtig.
  2. 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.
  3. Keine Lücke zwischen Segmenten. segments[N].out_point_s muss gleich segments[N+1].in_point_s sein. Keine Überlappungen, keine Lücken. Die Timeline ist lückenlos.
  4. Berechne total_duration_s genau. Laufzeit = letztes Segment out_point_s.
  5. 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.
  6. 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.
  7. 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).

Verwandte Skills