Was macht make-video?
Verwandelt eine Idee in eine gerenderte, geprüfte MP4 – nur mit kostenlosen, lokalen Werkzeugen. Ein mit dieser Fähigkeit erstelltes Projekt hat seine eigenen Regeln in AGENTS.md, befolge sie daher (Animationsreinheit, useScale, sec(), Ordnerstruktur).
0. Ein Videoprojekt einrichten (einmalig)
Wenn das aktuelle Verzeichnis keine Datei tools/make-story.sh hat, ist es noch kein Videoprojekt:
-
Überprüfe die Maschine vor allem anderen:
uname -sm(benötigt Darwin arm64),node --version(20+),brew --version,df -h ~(ca. 8 GB frei). Gib bei einem anderen Betriebssystem an, was nicht funktionieren wird (Chatterbox und der Take-Checker laufen auf dem Apple GPU), bevor du fortfährst. Falls Node oder Homebrew fehlt, gib dem Benutzer den einen Installationsbefehl und warte. -
Informiere den Benutzer über das, was heruntergeladen wird, und warte auf sein OK. Starte niemals die Downloads ohne dieses OK. Zeige diese Tabelle (alle kostenlos, von den offiziellen Quellen):
Download Größe Verwendung Zielort npm-Pakete (Remotion usw.) ~500 MB Rendering node_modules/ffmpeg, uv, FluidSynth (Homebrew, nur falls fehlend) ~150 MB Audio-/Videotools Homebrew Python-Pakete (PyTorch, Chatterbox…) ~1,5 GB Stimme, QA .venv/GeneralUser GS Soundfont ~30 MB Musik tools/soundfonts/Chatterbox-Gewichte ~3 GB die Stimme Hugging Face Cache ( ~/.cache/huggingface), von allen Projekten gemeinsam genutztWhisper small.en ~590 MB Untertitel tools/models/Whisper large-v3-turbo (optionaler Take-Checker) ~1,6 GB Wiederholung undeutlicher Zeilen Hugging Face Cache Insgesamt ca. 6 GB und 10-20 Minuten. Biete die schlankere Option an:
SKIP_TAKE_CHECK=1überspringt den Take-Checker (4,4 GB gesamt). Frage, wo das Projekt erstellt werden soll (Standard:~/videos). -
Nach seinem OK: Kopiere den
template/-Ordner, der neben dieser SKILL.md liegt, in das Projekt, einschließlich der Dotfiles (cp -R <skill dir>/template/. <dest>/), danngit init. -
Führe
tools/setup.shim Hintergrund aus und halte den Benutzer auf dem Laufenden: Sage, bei welchem Schritt es ist (es gibt▶-Zeilen aus) und, während des großen Downloads, wie weit es ist (du -shL ~/.cache/huggingface/hub/models--ResembleAI--chatterbox, Ziel ~3 GB). Es ist sicher, es erneut auszuführen: Abgeschlossene Schritte werden übersprungen und unterbrochene Downloads werden fortgesetzt. Wenn ein Download ins Stocken gerät (Größe wächst 5 Minuten lang nicht), stoppe ihn und führe das Setup erneut aus. Wenn es fehlschlägt, lies den Fehler, behebe die Ursache (fehlendes Tool, Speicherplatz, Netzwerk) und führe es erneut aus; arbeite nicht ohne ein fehlendes Modell. -
Beweise, dass es funktioniert:
tools/make-story.sh stories/fridge-drama FridgeDramaerstellt das 33-sekündige Beispiel (drei Gemüse streiten in einem Kühlschrank) in etwa 4 Minuten. Zeige dem Benutzerout/FridgeDrama.mp4und frage ihn dann, was er erstellen möchte.
Die Tools finden die Modelle selbstständig (Chatterbox und den Take-Checker im Hugging Face Cache, Untertitel in tools/models/), sodass nach dem Setup nichts konfiguriert werden muss. Ein zweites Projekt verwendet die zwischengespeicherten Gewichte wieder, daher ist sein Setup viel schneller.
1. Das Briefing festlegen (nur fragen, wenn etwas fehlt)
| Feld | Standard |
|---|---|
| Plattform / Format | Reel/Short: 1080×1920, 30 fps · YouTube: 1920×1080, 30 fps · Feed-Beitrag: 1080×1350 |
| Länge | Reel/Short: 15-45 s · YouTube: 3-10 min |
| Art | Story (Charaktere sprechen, also §3B verwenden) oder Motion-Grafiken (Text, Daten, Diagramme, also §3A verwenden) |
| Thema + einzelne Kernaussage | Das Eine, an das sich der Zuschauer erinnern soll |
| Audio | Stimme (Chatterbox), Musik + SFX (tools/music.py) oder nur Musik |
| Stimme | Chatterbox-eigene Stimme oder ein Klon der eigenen Aufnahme des Benutzers (§3B). Klone niemals jemanden ohne seine Zustimmung. |
2. Das Skript vor jeglichem Code schreiben
Längenbudget: Gesprochenes Englisch in Chatterbox' Tempo liegt bei etwa 2,6 Wörtern/s. Ziellänge ≈ Wörter ÷ 2,6 + Σ Pausen + Outro. Überprüfe es vor der Generierung. (Fridge Drama: 62 Wörter + 6,4 s Pausen + 3 s Outro = 33 s.)
Pacing-Regeln für vertikale Kurzformate:
- Der Hook muss ab Frame 0 sichtbar und hörbar sein. Die ersten 1,5 s entscheiden über die Bindung, und Frame 0 ist oft das Thumbnail – beginne daher nie mit einem leeren oder ausblendenden Frame.
- Jede Zeile ≤ 12 Wörter. Untertitel zeigen ≤ 3 Wörter gleichzeitig an.
- Jede Sekunde bewegt sich etwas.
- Sicherheitszone für 1080×1920: Nichts Wichtiges oberhalb von y=220 oder unterhalb von y=1540 (Plattform-UI) und nichts rechts von x≈940 unterhalb von y≈1000: Die Like-/Kommentar-/Teilen-Buttons verlaufen am rechten Rand (
tools/qa.py --layoutgibt einen Fehler aus). Platziere einen Moderator unten links. - Beende mit einem Höhepunkt oder einer Pointe, gefolgt von einer 2-3-sekündigen Call-to-Action-Karte.
Erklärvideo-Vorlage („Wie es funktioniert“ und Entwickler-Tipp-Reels, 45-60 s, 120-160 Wörter):
- Hook (≤ 3 s): Eine überraschende wahre Tatsache oder ein Ergebnis.
- „So funktioniert es eigentlich“: Ein Satz, der die Erklärung einleitet.
- 2-4 Abschnitte, jeder mit einer Zahl + einem Vergleich („Ein Video sind nur 30 Bilder pro Sekunde, wie ein Daumenkino“).
- „Aber hier ist der Haken“: Die Wendung, der Fehler oder der häufige Fehler.
- Einzeilige Pointe, dann ein klarer Call-to-Action (Speichern, Teilen oder Folgen).
Liste dann jede Tatsachenbehauptung mit einem Quelllink unter dem Skript auf, markiere alles, was du nicht überprüfen kannst, und korrigiere oder entferne es vor der Vertonung. Zeige die Quelle auf dem Bildschirm (klein, unten auf der Karte) an, wenn eine Zahl oder Behauptung erscheint.
Qualitätscheckliste für Shorts/Reels:
- Fortschritt, den man sehen kann. Schritt-für-Schritt-Videos erhalten
<StepCard steps={[{at: 0, title: „Herunterladen“}, …]} />(src/components/StepCard.tsx): eine „SCHRITT 2/4“-Markierung und eine segmentierte Leiste. - Karaoke-Untertitel (optionaler Stil).
<Karaoke words={captions} keywords={[„kostenlos“]} style={{left: 60, right: 140, top: 1180}} />(src/components/Karaoke.tsx): Der gesamte 2–5 Wörter umfassende Block ist auf dem Bildschirm, gesprochene Wörter sind ausgefüllt, kommende sind grau, Schlüsselwörter und betonte Wörter in der Akzentfarbe – so können Zuschauer beim stummgeschalteten Autoplay vorlesen.backgroundsorgt für ein helles Karten-Layout; übergibqa, damit die Layout-Prüfung es erfasst. - Serien-Chip. Ein Episodenmarker oben links („TEIL 2“) macht Beiträge suchtig.
- Zeige den Kontrast. Ein Vorher/Nachher oder „Wir gegen die“ funktioniert besser als eine zweispaltige Karte denn als gesprochener Text.
- Geschichten schlagen Listen. „Versuch 1 gescheitert → Versuch 2 gescheitert → was funktioniert hat“ hält die Aufmerksamkeit besser als eine Liste von Funktionen.
- Pointe vor dem CTA. Ein menschlicher Satz, dann der Call-to-Action.
- Versprich eine „kommentiere SCHLÜSSELWORT und ich DM dir“-Belohnung nur, wenn etwas Reales (ein Leitfaden, ein Prompt, ein Repo) dahintersteckt.
Schreiben für TTS:
- Beginne eine Zeile nicht mit „…“: Chatterbox improvisiert ein Füllwort.
- Beginne eine Zeile nicht mit einer bloßen Zahl als Wort („Zwei. Das Gesicht“ wurde zu „zu dem Gesicht“). Schreibe „Zweitens, …“.
- Schreibe Zahlen und ungewöhnliche Namen so, wie sie ausgesprochen werden („fünf Komma sechs“, „X Z“), und setze den tatsächlichen Text in das
caption-Feld der Zeile. - Runde große Zahlen („über 600“); TTS verhaspelt sich bei „646“ und „87.000“.
- Kurze Wörter in Hooks verschwimmen („Dieses Repo“ wurde als „Die drei“ gehört). Formuliere um, bis der Take-Checker sie richtig hört.
- Lasse nicht mehrere Stimmen dasselbe kurze Wort gleichzeitig rufen; die Mischung verschmiert es.
- Zeichensetzung lenkt den Vortrag: „?“ hebt, „.“ senkt, GROSSSCHREIBUNG betont.
3A. Bewegtgrafik-Video
- Kopiere
src/compositions/_Template→src/compositions/<Name>, mit einer Komponente pro Abschnittstyp (Hook, Punkt, Statistik, Liste, CTA). - Berechne die Dauer aus dem Skript (Summe der Abschnitte − Übergänge), wie von
getSampleIntroDuration. - Registriere es in
src/Root.tsxmit Inline-defaultProps. - Nur Musik: Schreibe eine Timeline-JSON mit
totalMs,outroStartMsundevents, führe danntools/music.pyaus.
3B. Sprachgeschichte (Figuren + Untertitel + Musik)
Erstelle stories/<slug>/script.json (kopiere stories/fridge-drama/script.json):
characters:color,exaggeration(0,3 ruhig → 0,9 dramatisch) und optionalrefVoice: eine saubere 10-30 s WAV-Datei intools/voices/zum Klonen. Ohne diese wird die integrierte Stimme von Chatterbox verwendet. So klonst du die Stimme des Benutzers: Der Benutzer nimmt 60-90 s natürliches Sprechen in einem ruhigen Raum auf, schneidet dann ein sauberes 10-15 s Stück ohne Musik oder Echo heraus (ffmpeg -ss <start> -t 12 -i note.m4a -af highpass=f=80,loudnorm=I=-18 -ar 24000 tools/voices/me.wav).lines:speaker,text,pauseAfter(s), optionalevent+eventAt: „start“zum Markieren von Story-Beats (Tür öffnet sich, verstecken…), auf die sich sowohl Animation als auch Musik beziehen.- Optionale Sprachregie pro Zeile:
emotion(calm|neutral|warm|excited|dramatic|whisper),pace(slow|normal|fast),emphasis(Wörter, die in GROSSBUCHSTABEN gesprochen und in den Untertiteln hervorgehoben werden),pauseBefore(s).„pace“: „slow“mit 0,4 s Pausen macht jedes Wort klar.
Führe dann einen Befehl aus:
tools/make-story.sh stories/<slug> <CompositionId> # Stimme → Untertitel → Musik/SFX → lint → rendern → Master → QA
SKIP_VOICE=1 tools/make-story.sh … # Nur an den visuellen Elementen iterieren
SAMPLE=15 tools/make-story.sh … # Nur die ersten 15 s zur Freigabe rendern, dann anhalten
| Werkzeug | Ausgabe |
|---|---|
tools/voice.py | public/<slug>/lines/*.wav (zwischengespeichert nach Text + Stimmeinstellungen), public/<slug>/voice.wav, stories/<slug>/timeline.json (Zeitsteuerung der Zeilen, Ereignisse, Mundhüllkurven pro Bild). Mit installiertem Take-Checker hört Whisper sich jeden Satz an und wiederholt undeutliche (VOICE_TAKES, Standard 3). |
tools/captions.mjs | public/<slug>/captions.json (Wortzeitsteuerung von Whisper, Schreibweise aus dem Skript), stories/<slug>/captions-report.json (Wortfehlerrate und übereinstimmende Wörter pro Zeile, die von Whisper übersehenen „gefüllten“ Teile, Gesamtübereinstimmungsrate matchRate) |
tools/music.py | public/<slug>/music.wav (MIDI → FluidSynth, an die Schnitte angepasst), public/<slug>/sfx.wav |
tools/qa.py | stories/<slug>/qa/report.md: PASS / FIX / FAIL |
Baue die Komposition aus timeline.json / captions.json (siehe src/compositions/FridgeDrama/data.ts). Steuere die Münder mit mouthOpen(), den Blick zum aktiven Sprecher, Ereignisse über timeline.events.* und die Dauer über timeline.durationInFrames.
Jede Änderung der Zeitsteuerung (Text oder Pausen) benötigt neue Untertitel. Untertitelzeiten sind absolut, andernfalls geraten sie aus dem Takt. make-story.sh führt die Untertitel immer erneut aus.
4. Überprüfen (immer, bevor du behauptest, es sei fertig)
tools/make-story.sh endet mit tools/qa.py, das bei FAIL mit einem Exit-Code ungleich 0 abbricht. Es prüft die Datei, Lautstärke (-14 ±1 LUFS, True Peak ≤ -1), Untertitelgenauigkeit, Schnitte auf den Takt (≤ 120 ms), eingefrorene Abschnitte (≤ 3 s), visuelle Abwechslung (längste gleich aussehende Sequenz ≤ 5 s) und Untertitel, die den Bildschirmtext wiederholen. LAYOUT=<CompId> prüft auch Untertitel auf tote Zonen und das Gesicht (die Komposition benötigt eine qa-Eigenschaft, die Untertitel in #FF00FF und das Gesicht in #00FFFF umrandet). Lese stories/<slug>/qa/report.md und behebe jedes FAIL und FIX.
Überprüfe dann mit eigenen Augen:
npm run lint.- Jede Zeile in
stories/<slug>/captions-report.jsonmit WER > 0,2 ist wahrscheinlich undeutlich: Formuliere neu und generiere erneut (günstig, dank des Caches). Wörter, die Whisper übersehen hat, werden nur über den gesprochenen Teil der Lücke gelegt, wobei längere Wörter mehr Zeit erhalten, und unterfilledaufgelistet: Höre an diesen Stellen. Liegt diematchRateunter 70 %, unterscheiden sich Skript und Audio, also vertone vor dem Weitermachen neu. - Rendere Standbilder an wichtigen Schlüsselpunkten (Hook, jeder Sprecher, jedes Ereignis, Outro), füge sie zu einem Kontaktblatt zusammen und sieh es dir an:
Überprüfe Zeichengröße, Sicherheitszone, Überlagerungen, die Zeichen verdecken, Reste hinter dem Outro, Untertitel-Sync und Textgröße (Chunks ≥ 28 px, Fließtext ≥ 54 px bei 1080 Breite).npx remotion still <Id> out/stills/f<N>.png --frame=<N> --scale=0.4 ffmpeg -i a.png -i b.png … -filter_complex hstack=inputs=K out/stills/contact.png - Ziehe 4-5 Frames aus dem endgültigen MP4 und sieh sie dir an.
- Bitte für alles Wichtige einen frischen Unter-Assistenten, das Kontaktblatt ohne Kontext zu kritisieren. Neue Augen finden Probleme, die der Ersteller übersieht.
5. Ausliefern
Gib dem Benutzer die MP4, einen Titel, eine Bildunterschrift, 3-5 Hashtags und einen Thumbnail-Frame. Poste oder lade niemals etwas ohne ausdrückliche Zustimmung hoch. Erinnere sie daran, YouTubes Label „verändertes oder synthetisches Material“ zu aktivieren, wenn eine geklonte Stimme oder ein KI-Gesicht verwendet wird.
Regeln, die Stunden sparen
- Ein Render gleichzeitig. Mehrere Remotion-Render gleichzeitig haben die Maschine stundenlang überlastet. Die Pipeline übergibt bereits
--timeout=180000 --concurrency=2. - Füge Remotion-Pakete mit
npx remotion add <pkg>hinzu, niemals mit einfachemnpm i, damit die Versionen abgestimmt bleiben. - Lautstärke: Dialog −16 LUFS, Musikbett etwa −24, endgültiger Master −14 (Zwei-Durchlauf, bereits in
make-story.sh). Halte die Stimme mindestens 10 dB über der Musik. - Studio kann Prop-Änderungen nur speichern, wenn
defaultPropsein Inline-Objekt inRoot.tsxist. - Schreibe zsh-Schleifen über Zeilen als
while read -r a b c; do …; done <<EOF, dafor x in „a b c“bricht.
Weitere Lektionen und wie du eigene hinzufügst: reference/lessons.md.
Gemessene Kosten (M1 Max, 64 GB)
| Schritt | Zeit |
|---|---|
| Laden des Chatterbox-Modells | ~20 s pro Durchlauf (übersprungen, wenn jede Zeile zwischengespeichert ist) |
| Spracherzeugung | erste Zeile ~55 s (Aufwärmen), dann etwa 3× Echtzeit |
| Take-Check | ~20-30 s pro Satz, der eine Wiederholung benötigt |
| Untertitel (Whisper small.en, WebGPU) | ~10 s für 11 Zeilen |
| Musik + SFX | 2-5 s |
| Render 1080×1920, 33 s | ~97 s (~3 s pro Sekunde Video) |
| Gesamte Pipeline | ~2 min mit zwischengespeicherter Stimme; ~4 min von Grund auf |
make-video stammt von TheNoumanDev, aus zero-dollar-studio. Es ist die Pipeline hinter dem YouTube-Kanal @0x45.dev.