Communitygithub.com

thativanng/reels-maker

Baue und rendere einen Film, einen Reel oder eine Animation als Code. Eine HTML-Seite zeichnet jeden Frame auf Abruf mit `window.seek(t)`, und ein Headless-Browser rendert jeden Frame in 2x zu einem MP4 mit Ton. Verwende es, wenn jemand ein Video mit Code statt einem Videogenerator haben möchte, z. B. „Mach einen Film / Reel / animierten Erklärfilm / Karrierevideo“, „Rendere das als MP4“, „Mach aus dieser Seite ein Video“ oder die letzten Schritte (Audio-Cues, Lautstärke, farbsicheres Encoding, Telefonvorschau) benötigt.

Was ist reels-maker?

Dieses Skill ermöglicht es, einen kompletten Film oder Reel als Code zu definieren und zu rendern. Die Grundidee ist eine einzelne HTML-Seite, die auf `window.seek(t)` jeden Frame deterministisch zeichnet – ohne Echtzeituhr. Ein Renderer durchläuft dann mit 30 fps alle Frames, macht Screenshots in 2x-Auflösung und leitet sie an ffmpeg weiter. Der Workflow ist strikt: Nach Briefing und Stilfestlegung folgt ein Teststreifen (ca. die ersten 10–30 Sekunden), dann der vollständige Bau, diverse Prüfungen (Kollisionen, Pixelproben, unabhängiger Auditor), das Rendern als stummes MP4, das Hinzufügen von Audio (Cues auf dem gleichen Zeitstrahl) und das finale Muxen auf −14 LUFS mit Limiter. Das Skill ist stilneutral, unterstützt die Formate 9:16, 4:5, 1:1 und 16:9 und liefert neben dem fertigen Video auch ein Cover und eine Telefonvorschau. Es läuft auf Basis von Node.js, Python und einem Headless-Browser und ist für Claude Code, Cursor und Codex optimiert.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/thativanng/reels-maker/tree/HEAD/skills/film-engine

In Ihrer bevorzugten KI fragen

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

Dokumentation

film-engine: Filme aus Code, Frame für Frame

Wo das Kit lebt: Führe jeden Befehl dieses Skills aus dem Ordner reels-maker aus (dem Klon von github.com/thativanng/reels-maker, der template/ und tools/ enthält). Falls das Projekt keinen hat, richte es zuerst gemäß der SETUP.md dieses Repos ein.

Die Idee in einem Absatz

Ein Film ist hier eine HTML-Seite mit einer Regel: window.seek(t) muss genau den Frame für die Zeit t zeichnen, jedes Mal, allein aus t. Nichts im Bild darf eine echte Uhr lesen. Ein Renderer durchläuft dann t mit 30 fps, macht Screenshots jedes Frames in 2x und leitet sie an ffmpeg weiter. Da die Seite deterministisch ist, stimmt ein erneutes Rendern überein (im Durchschnitt auf einen Bruchteil einer Stufe; GPU-Rauschen kann einzelne Pixel um bis zu etwa 60 Stufen verschieben), ein Standbild bei 17,3 s ist der Frame, den das Video zeigen wird, und jede Prüfung (film-audit) kann jeden Moment betrachten, ohne den Film abzuspielen.

Der Weg (keine Station überspringen)

  1. Briefing und Look zuerst. reel-intake endet mit einem unterschriebenen Briefing und Storyboard (Format, Länge, Ton, was nie erscheint); reel-style endet mit einem ausgewählten Look. Öffne die Build-Schritte dieses Skills nicht ohne beides.
  2. Storyboard. reel-intake schreibt es (Zeit · Text auf dem Bildschirm · Ton und Untertitel · Begründung; references/brief.md), und die Person unterzeichnet es, bevor du baust. Ein Stil mit einem Banner fügt eine Banner-Spalte hinzu.
  3. Teststreifen. Baue etwa die ersten 10 s im gewählten Look (ein Walk-Stil-Film braucht vielleicht 15–30 s, um ein Kapitel zu zeigen), erstelle Standbilder, bekomme ein Ja. Ein vollständiger Build mit einem nicht unterschriebenen Look ist verschwendete Arbeit.
  4. Baue den vollständigen Film (das Style-Pack sagt, wie Szenen gebaut werden).
  5. Tore (film-audit): die Kollisionsprüfung bei 40 fps, die Pixelproben, dann ein unabhängiger Auditor. Nichts geht zur Person vorher.
  6. Render: node tools/render.mjs --page reels/<name>/page.html --out reels/<name>/out/film-silent.mp4 (2x Frames, mit lanczos herunterskaliert, keine Farb-Tags).
  7. Audio: python3 template/audio.py out/film.wav (eine Cue-Liste auf dem gleichen Takt wie der Film).
  8. Fertigstellung: zsh tools/mux.sh out/film-silent.mp4 out/film.wav out/film.mp4. Das ergibt −14 LUFS, einen Limiter, eine ungetaggte H.264-Datei und eine Telefonvorschau in derselben Form wie der Film (kurze Seite 720 px).
  9. Cover: node tools/cover.mjs --page reels/<name>/page.html --out reels/<name>/out/cover.jpg. Eine Seite mit einem Cover-Modus (der Starter ?cover, aus config cover) zeichnet das entworfene Standbild; jede andere Seite gibt den Frame bei T=. Es wird in der eigenen Form des Films gespeichert und unter 2 MB gehalten, plus der mittlere 3:4-Zuschnitt für einen 9:16-Film (das Instagram-Grid, gemeldet). LinkedIn akzeptiert ein Cover nur zum Zeitpunkt des Postens: danach kann nur noch der Text eines Beitrags bearbeitet werden (LinkedIn Hilfe, „Geteilten Beitrag bearbeiten“, https://www.linkedin.com/help/linkedin/answer/a522811). Die Thumbnail-Spezifikation, JPG oder PNG in der Form des Videos und maximal 2 MB, stammt aus LinkedIn-Hilfe, zitiert von einer Suchzusammenfassung; die Seite selbst würde nicht laden, also behandle sie als unbestätigt.
  10. Sende zuerst die Telefonvorschau, dann die vollständige Datei und das Cover.

Der Seitenvertrag

  • window.seek(T): zeichnet Frame T. Es ist der einzige Ort, der irgendetwas animiert.
  • window.ready: ein Promise, das nach Schriftarten, Texturen und dem ersten Frame erfüllt wird.
  • window.DUR: die Länge des Films in Sekunden.
  • window.FILM = { w, h, format, safe }: die Framegröße und die freizuhaltende Zone in Pixeln. Jedes Werkzeug dimensioniert sein Fenster daraus, also besitzt die Seite ihr Format.
  • Optional: window.cover() zeichnet das Cover anstelle eines Frames, und FILM.coverAt benennt den Moment, auf dem es sitzt (tools/cover.mjs verwendet beides; ohne sie nimmt es den Frame bei T=).
  • window.collide(T) und window._dbg: Hooks für film-audit (siehe dieses Skill).
  • Die Tools bedienen den Kit-Ordner über http selbst (ES-Module laden nicht von file://). Um eine Seite live im Browser zu betrachten, npm run serve ausführen und http://127.0.0.1:8765/template/starter.html öffnen.

Formate, der Starter und andere Sprachen

  • template/formats.json enthält die vier Größen (9:16 1080×1920 · 4:5 1080×1350 · 1:1 1080×1080 · 16:9 1920×1080), die Plattform→Format-Zuordnung und die freizuhaltende Zone jeder Plattform mit ihrer Quelle. Die Formatzeile des Briefings wählt daraus.
  • Jeder Reel lebt in seinem eigenen Ordner, reels/<name>/ (gitignored): sein Briefing, Storyboard, page.html (eine Kopie des Starters oder von film.html), seine reel.json oder career.json und sein out/. Seiten laden Schriftarten und formats.json aus dem Kit-Stamm, also funktioniert eine Kopie von dort. Weise die Tools darauf hin: PAGE=reels/<name>/page.html.
  • template/starter.html + template/reel.json ist das Grundgerüst für jeden Look außer dem Voxel-Walk. Seine Wörter und Zeitangaben leben in der Konfiguration, es dimensioniert sich selbst über ?fmt= oder die Konfiguration und hält jedes Wort innerhalb der freizuhaltenden Zone der Plattform. ?guides zeigt die abgedeckten Zonen in Rot an, nur zur Überprüfung; niemals damit rendern. Es ist ein Grundgerüst, kein Look: reel-style schreibt seine Tokens und sein Layout neu.
  • template/film.html (die Voxel-Vorlage) ist nur 4:5, und sie verzichtet auf freizuhaltende Zonen (safe ist 0): Ihr Banner und Untertitel sitzen absichtlich nahe den Rändern, also besteht die safe-Prüfung dort immer und das Auge des Auditors ist die Kontrolle. Ihre Kameras sind auf 4:5 abgestimmt; ein anderes Verhältnis bedeutet, sie neu abzustimmen und jedes Tor erneut durchzulaufen.
  • Chinesisch, Japanisch, Koreanisch: Der Starter lädt Noto Sans TC von Google Fonts zur Renderzeit (nur die Zeichen, die die Konfiguration verwendet) und setzt CJK-Schrift auf etwa 0,72× der lateinischen Größe (ihre Zeichen sind volle em breit). Schreibe \n, wo eine Zeile umbrechen soll: Chinesisch bricht zwischen beliebigen Zeichen, also braucht eine lange Zeile einen von dir gewählten Umbruch. template/reel.zh.json ist ein ausgearbeitetes Beispiel. Jede andere Schrift braucht ihre eigene Schriftart im Stack.

Takt und Timing

  • Ein Film-Takt steuert die Szenen, die Kamera, das Banner, die Untertitel und den Ton. Wenn du später einen Beat einfügst, ohne alles andere neu zu takten, verwende eine Neuzuordnung: Der Szenen-Takt pausiert an der Einfügestelle, während die Overlays den echten Takt behalten:
    const INS = [[24.0, 5.0, 'detail']];   // bei Szenenzeit 24.0 einen 5 s langen eingefügten Beat abspielen
    function remap(T) { let sh = 0; for (const [a, len, id] of INS) { if (T < a + sh) return { t: T - sh, ins: null }; if (T < a + sh + len) return { t: a, ins: id, u: T - sh - a, len }; sh += len; } return { t: T - sh, ins: null }; }
    
    Das Audio-Skript braucht dieselbe Tabelle: Schreibe ein RT(t), das die eingefügten Längen zu einer Szenenzeit addiert, und platziere jeden Cue bei RT(t), sonst driftet jeder Cue nach dem Einfügen. (Die Vorlage hat keine Einfügungen, also braucht ihre audio.py keine.)
  • Easing: eio für Kamerabewegungen, eo für Dinge, die ankommen, trap (Trapezgeschwindigkeit) für Gehen und Fahren, damit ein Beweger nicht an den Enden „einschnappt“.
  • Kamera-Keyframes sind absolut A(pos, target) oder folgen F(offset, targetOffset) vom Bodenpunkt des Helden aus. Mische zwischen Keyframes mit eio. Halte auf einem wichtigen Beat; ein Shot, der sich ständig bewegt, wirkt nervös.

Die Overlays (im DOM, über der Leinwand)

  • Banner: Jahr, dann Firma, dann die Rollen-Pille, plus eine Zeitleiste, deren Punkt über dem aktuellen Jahr atmet. Das Banner ändert sich, wenn die neue Szene AUF DEM BILDSCHIRM ist (ihr Set ist erschienen, das Outfit hat sich geändert, der Held ist angekommen), nie, wenn der Code beginnt, sie zu bauen. Überprüfe dies auf einem Frame-Blatt bei ±1 s um jede Änderung.
  • Untertitel: eine Zeile Geschichte pro Beat, mit der Schlüsselphrase in fettem Akzent. Verwende text-wrap: balance. Gib einem Leser etwa 3 Wörter pro Sekunde und blende einen Untertitel aus, bevor eine schnelle Kamerabewegung das Subjekt dahinter freigibt.
  • Eine Sprechblase, die einer Figur folgt: Projiziere den Kopfpunkt und halte die Blase ≥24 px innerhalb des Frames.
  • Die Endkarte: Name, ein Slogan, worin sie gut sind, ein Zitat. Die Szene wird dahinter unscharf.

Audio

  • Cues werden auf dem Film-Takt geschrieben, neben dem Moment, zu dem sie gehören (Schritte pro Gehbein, ein Glockenton, wenn ein Ding erscheint, ein dumpfer Schlag, wenn es landet).
  • Keine Wisch-Sounds bei Übergängen; sie wirken billig. Verwende Glockentöne, Ticks und weiche Einschläge.
  • Das Standard-Bett in template/audio.py wird aus Sinuswellen erzeugt, also ist es überall kostenlos nutzbar. Wenn jemand einen KI-generierten Track mitbringt, überprüfe seine Lizenz: Die Gewichte einiger Modelle erlauben nur nicht-kommerzielle Nutzung.
  • Lautstärke: Two-Pass-Loudnorm auf −14 LUFS (messen, dann linear anwenden), dann ein Limiter. Ein Durchlauf überschießt.

Render-Fakten, die uns Tage gekostet haben (mehr in references/gotchas.md)

  • In 2x rendern und herunterskalieren. EffectComposer entfernt das Canvas-Anti-Aliasing, also hat ein 1x-Render überall gezackte Kanten.
  • Keine Farb-Tags auf dem MP4. Eine JPEG-Pipe taggt es als Vollbereich, und einige Player verschieben dann die Farben. setparams=...=unknown im Filter.
  • Zwei Gesichter in einer Ebene flackern (Z-Fighting). Gib dem vorderen einen Tiefenoffset.
  • Schriftarten müssen geladen werden (document.fonts.load), bevor Canvas-Text gezeichnet wird, sonst fällt es lautlos zurück.
  • GPU an im Headless-Chromium (--use-angle=metal auf macOS). Ohne sie ist ein Render etwa 10x langsamer.

Arbeiten ohne Aufforderung bei jedem Schritt

Die Person hat den Erlaubnisregeln des Kits einmal zugestimmt (SETUP.md Schritt 4); bleibe innerhalb dieser, sonst werden sie immer wieder gefragt:

  • Schreibe und ändere Dateien mit den Schreib- und Bearbeitungswerkzeugen: Seiten, reel.json, Briefing, Storyboard, AUDIT.md. Erzeuge sie nicht mit einem Python- oder Shell-Skript, einem Heredoc oder sed -i; jedes davon ist eine Genehmigungsaufforderung.
  • Messe mit den Werkzeugen des Kits (Stills, Probe, Sheet, Collide, Render, Cover), nicht mit einmaligen python3 -c-Schnipseln.
  • Kein mkdir, Schleifen oder Ketten nötig: Jedes Werkzeug erstellt seinen eigenen Ausgabeordner und nimmt eine Liste von Zeiten in einem Aufruf entgegen (stills.mjs … 1,5,6,12).
  • Eigene Skripte eines Reels (sein Tonskript, ein Helfer) leben in reels/<name>/ und laufen als python3 reels/<name>/audio.py oder node reels/<name>/x.mjs, was die Regeln abdecken.

Befehle

Führe jedes Werkzeug als einen einfachen Befehl aus (Flags, kein führendes VAR=…, keine Schleifen, keine &&-Ketten). Dann decken die Erlaubnisregeln der Person (node tools/*) es ab und sie werden nicht gebeten, jeden Schritt zu genehmigen. Die Umgebungsvariablen funktionieren weiterhin für Skripte.

npm run doctor                                  # prüft diesen Rechner zuerst
npm run demo                                    # der 12-Sekunden-Beweis: out/demo/
node tools/stills.mjs "2,8.5,15"                # 2x Standbilder → out/stills (die Voxel-Vorlage)
node tools/stills.mjs --page template/starter.html --format 16:9 1.6        # der Starter mit einem anderen Verhältnis
node tools/stills.mjs --page template/starter.html --cfg reel.zh.json 1.6   # eine andere Konfiguration (hier: Chinesisch)
node tools/stills.mjs --dsf 1 --out out/chk 2,8.5                           # schnelle 1x-Frames für ein Blatt
python3 tools/sheet.py out/chk/sheet.jpg 6 300 out/chk/t*.jpg
node tools/render.mjs --page reels/<name>/page.html --out reels/<name>/out/film-silent.mp4
python3 template/audio.py out/film.wav
zsh tools/mux.sh out/film-silent.mp4 out/film.wav out/film.mp4

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

thativanng/reels-maker

The gates every code-rendered film passes before anyone sees it. A 40 fps collision pass (no mover touches a solid or another mover), pixel probes (nothing sits over or behind a face, a head, a subtitle or the frame edge), then an independent auditor (a fresh agent) who reads frame sheets at ≥2 fps and signs off. The builder never signs off their own film. Use it before sending ANY render, after every fix round, and whenever someone says "check the film", "audit this", "is it ready", or "why does this frame look wrong".

thativanng/reels-maker

The interview before any video is built. It reads what the person already gave (source text, CV, links, brand files), then asks the rest in a few short rounds of numbered questions with a recommended answer marked, always including the format (platform, reel or video, ratio, layout, length, sound). It ends in a one-screen brief that splits "you said" from "I assumed", plus a storyboard, and builds nothing until the person says yes. Use it whenever someone asks for a reel, a video, an explainer, a career film, an animation or a "make a video about X", before film-engine or any style pack, and again when a request changes its purpose, platform or audience mid-way.

thativanng/reels-maker

Picks the look of a reel or film before it is built. It shows three genuinely different looks as stills of the same opening frame with the same words, so the person judges the look and not the content. It keeps a log of every look ever shown, so no look comes back unless asked for, and it locks one look on purpose for a series. Use it after reel-intake's brief is signed and before any test strip, whenever someone says "what should it look like", "give me options", "make it look different from last time", "it looks cheap", or starts a new reel or a new series.

thativanng/reels-maker

The voxel career-film style. A blocky 3D version of the person walks, without ever vanishing, through one scene per role. Their outfit changes as they walk, each scene rises out of the floor ahead of them, and a dark banner tracks year, company and role. Use it when someone wants their career, a journey or a "how I got here" told as a short 3D film for LinkedIn or a portfolio, says "make my career film", "turn my CV into a video", "voxel film", or wants a new chapter added to an existing one. It runs on film-engine (render, audio, finish) and must pass film-audit before anything is sent.

Verwandte Skills