/dynamic-edit
Ein Talking Head, der sich nie bewegt, ist tot; einer, der sich ohne Grund bewegt, ist schlimmer. Diese Pipeline entscheidet, welcher Effekt an welchem Wort seinen Platz verdient, schreibt das als Plan auf, den der Mensch ablehnen kann, und investiert erst dann Rechenzeit.
Repo-Stammverzeichnis:
THP_HOME=${THP_HOME:-$(cat ~/.config/talking-head-pipeline/root)}
Vor der Planung lesen: $THP_HOME/docs/STYLE_RULES.md (die handwerklichen Regeln), $THP_HOME/docs/LAYOUTS.md (Geometrie und Untertitel-Sicherheitszonen), references/plan-format.md (das Schema), references/qa.md (die Qualitätsprüfungen). 3D: $THP_HOME/docs/3D.md.
Input-Vertrag: Das Filmmaterial ist bereits geschnitten. Keine Stille entfernen, kein Filler-Durchgang hier. Ein Rohmaterial-Take geht zuerst zu /autocut; komme zurück mit dessen clean.mp4 und Arbeitsverzeichnis (für die wörtlichen Wörter).
Überspringe niemals den Planungsschritt. Rotoskopie kostet etwa 12 Minuten pro Minute Filmmaterial und ein vollständiger Render zehn Minuten. Eine falsche Vermutung, die in einem Textplan erkannt wird, kostet nichts.
Arbeitsablauf
1. Projekt einrichten
P=<Projekte-Verzeichnis>/<Slug> # frage, wo der Mensch Videoprojekte aufbewahrt; niemals der Desktop
cp -R "$THP_HOME/template" "$P"
cd "$P"
uv venv --python 3.11 .venv # mediapipe hat keine Räder jenseits von 3.12
uv pip install --python .venv/bin/python "mediapipe==0.10.21" opencv-python backgroundremover numpy pillow
scripts/download_models.sh # MediaPipe-Gesichtserkennung (nicht im Repo enthalten)
(cd remotion && pnpm install) # oder npm install
cp "<autocut Arbeitsverzeichnis>/clean.mp4" remotion/public/raw.mp4
python3 "$THP_HOME/scripts/autocut/verbatim_cut_words.py" "<autocut Arbeitsverzeichnis>" -o remotion/public/words.json
Vertikales Reel aus einem 16:9-Take: scripts/prep_vertical.sh "<autocut Arbeitsverzeichnis>" "$P" anstelle der letzten beiden Zeilen (statischer 9:16-Beschnitt auf dem mittleren Kopf-x, niemals ein nachführender Beschnitt).
2. Inventur, Schnitte, Tracking
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,nb_frames \
-show_entries format=duration -of default=nw=1 remotion/public/raw.mp4
.venv/bin/python scripts/detect_cuts.py remotion/public/raw.mp4 --out remotion/public/cuts.json
.venv/bin/python scripts/track_head.py remotion/public/raw.mp4 --out remotion/public/track.json --cuts remotion/public/cuts.json
- Zoom-Spielraum = Quellbreite / Timeline-Breite (2560 in 1920 = 1,33-fach kostenlos). Darüber hinaus wird hochskaliert.
- Das Seitenverhältnis wird automatisch aus Planbreite/-höhe erkannt (
lib/layouts.ts-Profile). Eine Engine, niemals ein Fork. - Lese
detectionRateintrack.json. Unter ~0,9 sind gesichtsverankerte Bewegungen unzuverlässig; dies mitteilen. - Die Schnitterkennung übersieht allmähliche Änderungen (einen animierten Wechsel zu einer Bildschirmfreigabe). Pro Segment ein Einzelbild auswerten und fehlende Grenzen manuell zu
cuts.jsonhinzufügen. Bildschirmfreigabe-Segmente erhalten keine Punch-Ins, keine darüber gezeichneten Untertitel, keine Karten (captions.silenceauf diese Bereiche setzen).
3. Wörter Korrektur lesen
Durchsuche words.json nach jedem Eigennamen, jeder Marke, jedem Ticker und jeder Person, die das Skript nennt. Whisper-Family-Modelle verhunzen sie und der Satz liest sich trotzdem flüssig, daher wird es bei der Überprüfung nie bemerkt. Korrigiere die Wortdatei (das Zusammenführen von zwei Token zu einem ist in Ordnung), niemals den Render. Zahlen als Ziffern.
4. Den Plan schreiben, dann STOPP
- Lies zuerst das gesamte Transkript. Finde die Beats, die die Erzählung tatsächlich hat: Aufhänger, Behauptung, Zahl, Wendung, Enthüllung, Höhepunkt, der Moment, der besser gezeigt als gesagt wird.
- Wähle pro Beat ein Werkzeug aus Effekte auswählen unten. Viele Beats erhalten nichts.
- Kopiere
scripts/build_plan.example.pynachscripts/build_plan.pyund schreibe die Beats dort mit Wortankern ("Phrase@Sekunden"). Es schreibtremotion/plan.jsonund die Untertitel. Es verweigert Ereignisse ohne Grund, ohne Wortanker für EIN- UND AUSGANG oder zu eng beieinander liegende Punches. - Zeige dem Menschen eine Tabelle, eine Zeile pro Ereignis: Zeit, Effekt, „landet auf X, verlässt nach Y, wegen Z“. Plus: Rotoskopie-Sekunden (und die daraus resultierende Maskierungszeit), jedes Reframing jenseits des Zoom-Spielraums, jede Dehnung über ~12 s ohne Ereignis und die benötigten 3D-Render.
- Warte auf Freigabe. Lese dann
plan.jsonvon der Festplatte; der Mensch könnte es bearbeitet haben.
Wenn der Mensch einen bestimmten Effekt zu einem bestimmten Zeitpunkt genannt hat, ist das der Plan für diesen Beat.
5. Baue nur das, was der Plan braucht, nichts weiter
- Roto-Fenster:
scripts/render_and_qa.shmaskiert sie; oderscripts/matte_frames.pypro Fenster. - 3D-Helden-Typografie / 3D-Assets:
tools/render3d(siehe docs/3D.md). Zuerst Standbilder (--stills), sie ansehen, dann--clip --dir=remotion/public/<Name>. Setze die gleichen Ein-/Aus-Frames in den Shot wie dieat/untildes Planereignisses. - Side-Karten: Arten in
remotion/src/layouts/cards.tsx; füge bei Bedarf eine Art dort hinzu. - Screen-Szenen-Seiten:
remotion/src/screen/pages.tsx. Baue die Benutzeroberfläche im Code für alles nach, in das du hineinzoomst; ein Screenshot wird bei 2x weich. - Vollbild-Szenen:
scenes/fullscreen/registry.ts(depth,clip,stage). - SFX: nachdem der Plan final ist,
scripts/add_sfx.py "$P" sfx_map.json --library <Verzeichnis>.
6. Mit Standbildern prüfen, dann rendern
Standbilder kosten Sekunden; ein Render kostet den Nachmittag:
cd remotion && npx remotion still src/index.ts Edit ../qa/landing.png --frame=<N>
Prüfe jede Helden-Landung (und Landung + 25), jeden Layout-Eintritt, jeden Übergang, jede 3D-Ankunft. Dann:
scripts/render_and_qa.sh "$P" <Name> # maskiert Roto-Fenster, rendert, schreibt QA-Blätter
Renders: --concurrency 4-6, nice den Prozess, und behalte Config.setChromiumOpenGlRenderer('angle') (bereits in remotion.config.ts) oder WebGL-Szenen schlagen kopflos fehl. Liefere als yuv420p bt709 aus; eine yuvj420p-Datei wird in QuickTime leer wiedergegeben.
7. Qualitätssicherung (references/qa.md), dann Sync-Trim
Führe jedes Tor in references/qa.md aus, bevor jemand es sieht. Dann miss und trimme die Audioverzögerung des Renders gegenüber der Quelle (Remotion-Renders laufen einige zehn ms zu spät; gemessen, niemals angenommen):
"$THP_HOME/scripts/master/sync_trim.sh" renders/<Name>.mp4 remotion/public/raw.mp4 renders/<Name>_final.mp4 [--loudnorm -14]
Ziel: |finaler Sync| unter 5 ms. Lautstärkenormalisierung nur, wenn der Mensch sie wünscht (Social-Media-Standard -14 LUFS). Öffne das Finale für den Menschen.
8. Korrekturen nach Auslieferung: Bereich patchen, niemals das Video neu rendern
scripts/patch_render.sh --base renders/vorher.mp4 --replace 0-1049 --render 0-887 --out renders/nachher.mp4
--replace ist der Bereich des alten Renders, der verworfen werden soll, --render der Bereich des aktuellen Plans, der ihn ersetzt (sie unterscheiden sich, wenn die Quelle neu geschnitten wurde). Nur der Patch wird codiert; Kopf und Ende werden an Keyframes stream-copiert; die Bildanzahl wird überprüft. Wenn nach der Planerstellung ein Stolperer aus der Quelle entfernt werden muss, baue den Plan aus Ankern neu (build_plan.py), sodass sich jeder Effekt mit seinem Wort bewegt.
9. Aufräumen, nur wenn der Mensch sagt, dass das Video fertig ist
Vorher fragen. scripts/cleanup.sh löscht Masken-PNGs, Bild-Dumps, QA-Blätter, Entwürfe, die venv und node_modules; es behält den Plan, die Quelle, das Tracking, die Untertitel und den endgültigen Render. Die Neuerstellung einer Maske kostet ~12 Minuten pro Minute Filmmaterial, also führe es niemals unaufgefordert aus.
Effekte auswählen (eine Werkzeugkiste, keine Ablaufliste)
Es gibt keine Formel. Ein Video ohne Heldenwort, ohne Roto, ohne 3D ist ein gültiger Plan. Ein reiner Kamera-Beitrag kann nur aus Punch-Ins und Untertiteln bestehen. Jeder Effekt wird durch etwas im Skript verdient, und jedes Ereignis benennt warum (seine narrative Aufgabe), auf welches Wort (das Wort, auf dem es landet; die Bewegung beginnt davor, sodass es darauf ankommt) und verlässt nach welchem Wort (das Wort, das es danach verlässt: Ende dieses Gedankens, die nächste echte Pause, das Wort vor einem Weichzeichner). Niemals ein fester Halt, niemals „es war eine Weile ruhig“.
- Gesicht zuerst. Die ersten 2-3 s sind das Gesicht des Sprechers, Frame 0 bereits ein lesbares Hook-Bild (kein Einblenden aus Schwarz). Keine Vollbild-Grafik vor ~2,5 s: Autoplay ist stummgeschaltet und eine statistiklastige Eröffnung liest sich wie eine Infografik und wird weg gescrollt.
- Punch-In (das Arbeitstier): satzlange, wenige, zielgerichtet. Es landet, wenn der Schlüsselsatz aufgebaut wird, hält durch ihn hindurch, lässt auf seinem letzten Wort los. Niemals ein Ein-Wort-Punch; niemals durch einen Timer beabstandet. Ungefähr eines pro 30-45 s Talking Head bei Langform; enger bei Kurzform nur, wenn das Skript es verdient. Am verfolgten Gesicht verankert. Zwei verbundene Phrasen: den Teil punchen, der die Geschichte trägt. Verschachtelte Betonung (Halten + eine kleine Betonung auf der Schlüsselphrase) anstelle von drei Punches in einem Satz.
- Side-Layout (16:9): wenn eine Zahl, eine Liste oder ein Vergleich auf dem Bildschirm bleiben soll, während sie erklärt wird. Das Subjekt gleitet zur Seite, eine inhaltsgroße Karte auf der anderen Seite, Karten wechseln bei ihren Wörtern und punchen auf der gesagten Zahl. Die meisten Informations-Bits in Langform wollen dies.
- Screen-Szene (16:9): der „so sieht es aus“-Walkthrough. Ein- oder zweimal pro Video verwenden, nicht bei jeder Erwähnung. Eins-zu-eins mit der echten Benutzeroberfläche, wenn es ein Produkt nachbildet; nur die Daten ändern sich, und die Daten sind echt.
- Offset-Reframe mit Karten: eine leichtere Version von Side, innerhalb des Zoom-Spielraums.
- Roto (hinter dem Subjekt): nur für Opener und Helden-Momente. Standardbudget 15 s pro Video; über 30 s warnen; über 60 s nachfragen. Alles, was dahinter vorbeigeht, muss es wert sein, verdeckt zu werden.
- Heldenwort hinter dem Subjekt: ein Aufhänger, eine harte Wendung, die genannte Idee. Über dem Kopf, jedes Zeichen lesbar (überprüfe ein Standbild bei Landung + 25). Eines pro Video, es sei denn, zwei landen weit voneinander entfernt.
- 3D-Helden-Typografie: eine große Behauptung oder Zahl neben dem Kopf oder quer über der Brust, gleicher Abstand zu jedem Bildschirmrand (mindestens ~90 px bei 1080 Breite), niemals auf dem Gesicht.
- 3D-Asset: ein Logo oder Objekt, das der Sprecher nennt, das sich im leeren Raum neben dem Gesicht dreht, Roto dahinter, wenn es sich überschneidet.
- Vollbild-Szene: nur, wenn Zeigen eindeutig besser ist als Sagen, höchstens zwei, fade+blur rein und raus.
- Untertitel: feste untere Leiste, gleiche Position und gleicher Stil überall (Talking Head, Side, Screen). Betonung = Akzent-Schriftart UND 1,22-fache Größe auf ganzen Phrasen, niemals auf zwei Karten aufgeteilt. Kopfverfolgte Untertitel sind aus, es sei denn, sie werden verlangt.
- SFX: eines pro sichtbarem Ereignis (Übergang, Helden-Landung, harter Punch, Karte, Klick), dezent.
Harte Regeln
- Nichts auf dem Gesicht. Kein Untertitel, keine Karte, kein Chip, kein Logo oder 3D-Objekt über der Gesichtsbox in keinem Frame seines Fensters. Verschiebe es, verkleinere es oder platziere es mit Roto dahinter. Miss anhand von track.json.
- Keine Text-Chips in Boxen über dem Sprecher. Keine einseitigen Akzentlinien auf Karten (oben, links, irgendeine Kante): verwende eine Fülltönung oder einen vollständigen, gleichmäßigen Rand.
- Nur Vollbild-Einblendungen. Blende niemals Container aus, während ein Titel bleibt.
- Übergänge: Fade+Blur (Standard), einfacher Fade oder ein flüssiger Stinger. Niemals ein Zickzack/Zahn-Verschlussvorhang.
- Kein Text, der durch einen Zoom oder den Bildschirmrand beschnitten wird. Gezoomte Benutzeroberfläche blendet oberhalb der Untertitel-Band aus (
World-Kantenfade). Untertitel zoomen nie. - Ein Reframe wird im gleichen Render ausgeliefert wie das, wofür er Platz schafft. Keine Kamerabewegung zu einer leeren Wand.
- Überprüfe jede Zahl auf dem Bildschirm gegen das Gesagte oder einen gespeicherten, bezogenen Fetch. Erfinde niemals eine.
- Objekte und Symbole sind echte Logos oder generierte/bezogene Bilder. Code zeichnet Bewegung, Text, Benutzeroberfläche, Diagramme. Pfeilspitzen sind ein Asset, kein SVG.
- Keine Gedankenstriche auf dem Bildschirm. Keine „Kommentiere unten“ / „Schreib mir eine DM“-Handlungsaufforderungen, es sei denn, der Mensch bittet darum.
- Jede Ebene, die über dem Video gestapelt ist, ist ein eigener
AbsoluteFill(ein statisches Video zeichnet unter jedem absolut positionierten Geschwisterelement, was Grafiken stillschweigend vor die Maske setzt). - Verwende
translate + scale, niemals einen verschobenentransform-origin, für Reframes.
Effektparameter und gemessene Zahlen: references/effects.md.