Spatial Film
Ende-zu-Ende bewährt auf einem 60-Sekunden-Produktfilm (7 Szenen, 5 Worker in einem Durchlauf, jede Naht frame-genau, Check sauber, 1080p60 in 4m19s). Die Vorlage film.json enthält die echten Szenenbalken und das Cue-Blatt dieses Films als funktionierendes Beispiel.
<skill> = der Ordner dieser Fertigkeit (das Verzeichnis, in dem diese SKILL.md liegt). Führe jedes Skript vom Film-Projekt-Root aus.
python unten = der Python-Befehl, der durch den Setup-Check von explainer-kit in ~/.talking-explainer/config.json gespeichert wurde (py -3.12 unter Windows, python3 unter macOS).
Was du brauchst
- Node 20+,
ffmpeg+ffprobeim PATH, Python 3.10+ mitnumpyundPillow. - Die HyperFrames-Fertigkeiten:
npx hyperframes skills update general-video hyperframes-animation media-use(Paket-Builder, Blaupausen + Animationskarte, Musikhelfer). Die CLI selbst ist pro Projekt festgelegt und läuft übernpx. - Playwright zum Vorrendern von Oberflächen:
npm i -D playwrightim Film-Ordner (oderPLAYWRIGHT_PATHsetzen). - Optional, für lizenzierte Musik: ein HeyGen-Konto – führe
npx hyperframes auth logineinmal in deinem Terminal aus. Ohne Konto bringe deinen eigenen Track mit und starte Phase 4 beimusic-analyze.py. - Ein GPU-fähiger Rechner für den finalen Render (er rendert auch auf dem Software-Pfad, etwa 15x langsamer).
So verwendest du diese Fertigkeit, ohne Kontext zu verschwenden
- Lade jeweils NUR EINE Phasenreferenz, wenn die Phase beginnt. Lade niemals alle vorab.
- Skripte sind der bewährte Code. Führe sie aus; generiere ihre Logik niemals inline neu.
- Die Hauptsitzung liest niemals eine ganze Szenendatei (20-60 KB). Beurteile Szenen anhand von Kontaktabzügen; korrigiere mit
grep -nund einem exakten Patch. - Worker erhalten DATEIPFADE, nicht eingefügte Inhalte.
storyboard.html(60 KB+) wird nach Zellen-ID durchsucht, niemals komplett gelesen. - Lies zuerst einen Kontaktabzug; öffne einzelne Snapshot-PNGs nur, um ein Detail zu prüfen.
Phasen (jede endet mit einem Tor – erst weitergehen, wenn es bestanden ist)
| # | Phase | Laden | Tor |
|---|---|---|---|
| 0 | Gerüst: node <skill>/scripts/new-film.mjs <dir> --name <slug> | - | Ordner enthält film.json, frame.md, kit, Vorlagendokumente |
| 1 | Aufnahme, BRIEF, STORYBOARD, Skizzenblatt | references/storyboard.md | Explizites „Los" des Benutzers, aufgezeichnet unter ## Locked |
| 2 | frame.md, kit, vorgerenderte Oberflächen | references/surfaces.md (+ platform-canvases.md nur wenn GHL/n8n/Zapier vorkommen) | kein {{ in frame.md; jedes Capture-PNG angesehen |
| 3 | Test der Szenenvorbereitung (Harness), Pakete, parallele Worker | references/workers.md | jede Szene: Lint 0 Fehler, Kontaktabzug passt zu seinem Block |
| 4 | Musik + SFX (während die Worker bauen) | references/audio.md | Bett bei nativen BPM, Takt 0 auf einem Downbeat; Cues in film.json |
| 5 | Zusammenbauen, Prüfen, Nähte, Rendern, Ausliefern | references/verify-ship.md | Prüfung bestanden, Naht-Check alle BESTANDEN, hardware-gpu Render verifiziert |
Route durch /hyperframes -> /general-video für die Absichts- und Skizzen-Review-Schritte (diese Fertigkeit liefert die Projektform, den Vertrag, die Skripte und Tore; general-video liefert den Paket-Builder und die Worker-Rolle).
Dateien
| Pfad | Was |
|---|---|
template/ | Projekt-Skelett: film.json (Szenenbalken, BPM, bgm, SFX, Cues – die EINE Timing-Quelle), frame.md (Design-Wahrheitsvertrag mit Ausfüllfeldern), BRIEF.md, STORYBOARD.md, assets/kit.css (Basis-Film-Kit), assets/fonts/ (Poppins 500/700 + OFL), references/worker-brief.md, references/scene-starter.html (lint-sauberes Szenen-Skelett), references/snippets.html, package.json (festgelegte hyperframes 0.8.117). |
surfaces/ | Fertige HTML-Neubauten der GHL-, n8n- und Zapier-Canvas + eine lange Marketing-Seite (fiktive Northwind Dental-Daten), platform.css, sprite.svg, jobs.json. |
scripts/new-film.mjs | Ein Projekt aus der Vorlage erstellen. |
scripts/capture-surfaces.cjs | src/captures/*.html -> assets/captures/*.png in 2x rendern (jobs.json). |
scripts/measure-surface.cjs | 1x Boxen von Elementen auf einer Oberfläche, für exakte Annotations-/Zuschneideziele. |
scripts/make-harness.py, scripts/test-scene.mjs | Pro Szene isolierte Testprojekte; eine Szene linten und einen Schnappschuss machen. |
scripts/music-search.mjs, sfx-search.mjs | HeyGen-Katalog über den REST-Helfer von media-use (Windows-sicher). |
scripts/music-analyze.py, music-bars.py | Nur numpy Tempo + Energie pro Takt (kein librosa nötig). |
scripts/bgm-cut.py | Das Bett an Taktlinien zuschneiden, den eigenen Outro des Tracks einfügen, Überblendungen; --b wiederholt, um ein Bett unter einem längeren Film zu loopen. |
scripts/assemble.py | film.json -> index.html (Szenenslots auf dem Taktgitter, bgm, SFX mit Dauern + Spuren). |
scripts/seam-check.py | Pixel-genaue Prüfung jeder Naht (vor / an / nach dem Schnitt) und der Schleife (Frame 0 vs. letzter). |
scripts/render-final.mjs | CLI-Render mit --browser-gpu, in eine Datei geloggt, GPU-Modus + ffprobe verifiziert, dann flash-scan.py. |
scripts/flash-scan.py | Jeder Frame eines Renders: ein Frame, der sich von beiden Nachbarn unterscheidet (ein Element, das für 1/60s angezeigt wird) = ein Fehler. |
scripts/encode-web.mjs | Web-Encoding (H.264 CRF 21, faststart, AAC oder --silent) + Poster-Frame. |
scripts/blink-fit.py, scripts/build-presenter.py | Erzählte Filme: Blinzel-Overlays für Posen (--band = Augenband); das Präsentator-Overlay aus seinem Track, mit Lippen-Sync wenn das Maskottchen mouth-fit.json hat. |
scripts/el-tts.py, el-words.py, el-music.py | Erzählte Filme via ElevenLabs (Schlüssel in Umgebungsvariable EL, niemals auf Platte): Sprachkandidaten aus SCRIPT.md, Scribe-Wort-Zeitsteuerung, ein generiertes Bett. |
scripts/seam-diff.py | Naht-Differenz mit maskierter Präsentator-Box (erzählte Filme). |
scripts/fromto-scan.py | Vor dem Rendern: kennzeichnet fromTo NUR-von-Eigenschaften, die Render-Worker (Szenensuche innerhalb der Szene) niemals anwenden. 0 Treffer vor jedem Render. |
scripts/patch_exact.py | Exakte, CRLF-sichere Suchen/Ersetzen für skriptgesteuerte Szenenkorrekturen (behauptet genau einen Treffer pro Suche). |
scripts/selftest.mjs | Ende-zu-Ende-Beweis, dass die Fertigkeit auf diesem Rechner funktioniert. Muss PASS ausgeben. |
Erzählte Filme (ein Voiceover + ein Bildschirm-Moderator)
Bewährt auf einem erzählten „API vs Webhook"-Erklärvideo (83s, vertikal und quer, geklonte Stimme, Maskottchen-Moderator, 10 Szenen von 5 Workern). Die Musik-Film-Regeln oben gelten weiterhin, außer wo diese sie ersetzen:
- Sprachkandidaten zuerst.
EL=<key> python <skill>/scripts/el-tts.py . eric=<voice_id> michelle=<voice_id>liest die eingerückten Zeilen vonSCRIPT.mdund schreibt eine MP3 pro Stimme nachsrc/audio/voice-candidates/(Schlüssel nur aus Umgebungsvariable, niemals auf Platte). Lass den Benutzer nach Gehör auswählen, transkribiere dann nur die Auswahl. - Die Erzählung ist die Uhr. Wortzeiten:
EL=<key> python <skill>/scripts/el-words.py <voice.mp3> src/timing/voice-words.json(ElevenLabs Scribe – kein lokales Modell, benötigt Schlüssel) oder faster-whisper mitword_timestamps(Sprache gesetzt, VAD an;transcribe.pyvon explainer-kit, kostenlos und lokal). Behalte das Wort-JSON insrc/timing/. Setze infilm.json"bpm": 60, "beats_per_bar": 1, sodass ein „Takt" 1s ist und Szenenlängen einfache Sekunden sind, die in den Satzpausen geschnitten werden. Storyboard-Blöcke geben szenenlokale Wortzeiten; Ankünfte beginnen ~0,1s früher und landen auf dem Wort. Gib einem Titel mindestens ~1s auf dem Bildschirm vor dem nächsten Schnitt (prüfe den Schnitt gegen das LETZTE Wort der Zeile, die er zeigt). film.jsonExtras (assemble.py + make-harness.py lesen sie):"audio": [{id, src, dur, volume}]für die Stimme,"overlays": [{id, track, z}]für eine vollflächige Schicht (der Moderator), die über jeder Szene liegt, sodass sie nie an einer Naht aufpoppt und die Szenen moderatorenfrei bleiben.- Moderator aus Posen-PNGs: ein transparentes PNG pro Pose (
prep-mascot.pyvon explainer-kit trimmt, skaliert und schreibt das Manifest), dannscripts/blink-fit.py <mascot_dir>(optional, benötigt torch; passt das BLINK-Augenband auf jede Pose mittels NCC; Posen unter 0,70 erhalten kein Blinzeln) undscripts/build-presenter.py(schreibt das Overlay aussrc/presenter-track.json: Posen auf Cue-Wörtern, kopfverankert, sodass Wechsel nie springen, Stimmenhüllkurven-Bob, Atem, Blinzeln, FX). Bearbeite seine Ausgabe niemals von Hand. - Audio: loudnorm die Stimme auf -16 LUFS / -1,5 dBTP (eine einfache Verstärkung, begrenzt auf +4,6 dBTP), Sidechain-Duck des Betts darunter offline (~17 dB unter der Stimme), SFX leise (0,1-0,45). Füge den Voice-Key auf oder das Ducken kürzt das Bett auf die Stimmenlänge (überprüfe Warnung „bgm 110,25s vs slot 113s"):
[1:a]apad=whole_dur=<TOTAL>[k];[0:a][k]sidechaincompress=threshold=0.03:ratio=6:attack=25:release=450,atrim=end=<TOTAL>. Kein Katalog-Bett (HeyGen-Suche 500s oder kein Login):EL=<key> python <skill>/scripts/el-music.py .media/candidates/bed.mp3 <ms> "<prompt: instrumental, BPM, sits under a narrator, no drops, ends on a resolved chord>"– ein Track, der bei der Filmlänge von selbst ausklingt, benötigt keine Nahtstelle. - Naht-Check-Rauschen: Der Moderator bewegt sich über jede Naht, daher schlägt
seam-check.pyallein deswegen fehl. Beurteile jedes markierte Paar mitscripts/seam-diff.py a.png b.png out.png x0,y0,x1,y1(maskiert die Moderator-Box) – 0,00% außerhalb davon ist bestanden. - Vertikales (1080x1920) Größen-Gesetz: Der obere Bereich jeder Szene trägt eine echte Überschrift (60-84px), Körpertext >= 40px, Objekte nutzen die volle Breite und die Höhe oberhalb des Moderators. Die erste Welle lieferte ~33px Text in den oberen 45% des Bildes – setze diese Zahlen in frame.md vor dem Versand, nicht danach.
- Kein Loop: Ein erzählter Film endet auf einem gehaltenen Standbild; ignoriere die Loop-Zeile von seam-check.
Harte Regeln (die dafür sorgen, dass es hochwertig und geschmeidig ist)
- Wahrheit aus der Quelle. Produkt-UI wird aus dem eigenen HTML/CSS des Produkts portiert; Drittanbieter-Canvas werden aus den echten Captures des Benutzers neu erstellt, niemals aus dem Gedächtnis. Nur fiktive Daten. Nur Funktionen, die das Produkt wirklich hat.
- Eine Kamera. Perspektive 1866mm (35mm) in jeder Szene; eine Drift-Schicht unter der Kamera-Schicht, sodass niemals etwas still steht; Parallaxe + DOF-Unschärfe auf fernen Blättern. Keine opacity/filter/overflow/clip-path auf einem 3D-Elternelement (es wird flach).
- Scharf bei 1080p+. Skaliere UI mit CSS
zoom(.kit-zoom), niemalstransform: scale(>1); erstelle jedes Stück in seiner nächsten Bildschirmgröße; Captures sind 2x PNGs, die in oder unter nativer Größe angezeigt werden. - 60fps Geschmeidigkeitsgesetz. Nur transform/opacity; Springs für Landungen, expo/power3 für Ankünfte, inOut für Kamerafahrten; kein linear, steps, snap oder rounding; Kamerafahrten überlappen 0,15-0,3s und dauern 0,6s+.
- Deterministisch. Eine pausierte Timeline pro Szene, registriert als letztes auf
window.__timelines[id],fromTomit expliziten Starts, kein random/clock/CSS-Transitionen. - Nähte sind gemeinsame Frames. Jede Naht ist ein exaktes Bild, das beide Nachbarn ~0,1s halten, fixiert durch eine 2D-Platte außerhalb des Rigs. Kein harter Schnitt, kein leerer Frame, kein Ausblenden zu nichts. Letzter Frame = erster Frame.
- Auf dem Raster. Szenen sind ganze/halbe Takte; Klicks, Ticks, Stempel und Wechsel landen auf Beats; Musik in ihrem nativen Tempo, geschnitten an Taktlinien.
- Vertragskorrekturen, nicht Szenenkorrekturen. Root-relative
assets/...Pfade, IDs beginnen nie mit einer Ziffer, IDs und Klassen sind mit der Szenen-ID präfigiert. Eine Regel, die jede Szene brechen würde, wird einmal in frame.md / worker-brief korrigiert. - Verbote. Kein Emoji, Neon-Glühen, Lila-zu-Blau-Verlauf, farbige linke Rahmenkarten, kreisförmige Spinner (Schimmer), Standard-Personen,