Communitygithub.com

TheNoumanDev/make-video

Erstellt ein fertiges Social-Video (YouTube Short, Instagram Reel oder YouTube-Langform) für 0 € mit Remotion und lokalen KI-Tools – von einer einzeiligen Idee bis zur geprüften MP4.

Was ist make-video?

Diese Fähigkeit verwandelt eine einfache Idee in ein vollständig gerendertes MP4-Video – ohne Cloud-API-Kosten, nur mit lokalen, freien Werkzeugen. Sie unterstützt die Erstellung von YouTube Shorts, Instagram Reels und YouTube-Langform-Videos und deckt Skripterstellung, Sprachsynthese (mit Chatterbox, optional inklusive Klonen der eigenen Stimme), Wort-synchrone Untertitel (Whisper), Musik und Soundeffekte (FluidSynth), Rendering und eine automatische Qualitätssicherung ab. Der gesamte Workflow läuft lokal auf macOS mit Apple Silicon; es sind keine API-Schlüssel oder Guthaben erforderlich. Entwickler und KI-Agenten-Nutzer können damit eine vollständige Videoproduktionspipeline von der Ideenfindung bis zur Auslieferung automatisieren, wobei das System die Einhaltung von Best Practices für Kurzformate, visuelle Sicherheitszonen und Audiopegel prüft.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/TheNoumanDev/zero-dollar-studio/tree/main/plugins/make-video/skills/make-video

In Ihrer bevorzugten KI fragen

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

Dokumentation

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:

  1. Ü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.

  2. 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):

    DownloadGrößeVerwendungZielort
    npm-Pakete (Remotion usw.)~500 MBRenderingnode_modules/
    ffmpeg, uv, FluidSynth (Homebrew, nur falls fehlend)~150 MBAudio-/VideotoolsHomebrew
    Python-Pakete (PyTorch, Chatterbox…)~1,5 GBStimme, QA.venv/
    GeneralUser GS Soundfont~30 MBMusiktools/soundfonts/
    Chatterbox-Gewichte~3 GBdie StimmeHugging Face Cache (~/.cache/huggingface), von allen Projekten gemeinsam genutzt
    Whisper small.en~590 MBUntertiteltools/models/
    Whisper large-v3-turbo (optionaler Take-Checker)~1,6 GBWiederholung undeutlicher ZeilenHugging 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).

  3. 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>/), dann git init.

  4. Führe tools/setup.sh im 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.

  5. Beweise, dass es funktioniert: tools/make-story.sh stories/fridge-drama FridgeDrama erstellt das 33-sekündige Beispiel (drei Gemüse streiten in einem Kühlschrank) in etwa 4 Minuten. Zeige dem Benutzer out/FridgeDrama.mp4 und 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)

FeldStandard
Plattform / FormatReel/Short: 1080×1920, 30 fps · YouTube: 1920×1080, 30 fps · Feed-Beitrag: 1080×1350
LängeReel/Short: 15-45 s · YouTube: 3-10 min
ArtStory (Charaktere sprechen, also §3B verwenden) oder Motion-Grafiken (Text, Daten, Diagramme, also §3A verwenden)
Thema + einzelne KernaussageDas Eine, an das sich der Zuschauer erinnern soll
AudioStimme (Chatterbox), Musik + SFX (tools/music.py) oder nur Musik
StimmeChatterbox-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 --layout gibt 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):

  1. Hook (≤ 3 s): Eine überraschende wahre Tatsache oder ein Ergebnis.
  2. „So funktioniert es eigentlich“: Ein Satz, der die Erklärung einleitet.
  3. 2-4 Abschnitte, jeder mit einer Zahl + einem Vergleich („Ein Video sind nur 30 Bilder pro Sekunde, wie ein Daumenkino“).
  4. „Aber hier ist der Haken“: Die Wendung, der Fehler oder der häufige Fehler.
  5. 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. background sorgt für ein helles Karten-Layout; übergib qa, 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

  1. Kopiere src/compositions/_Template → src/compositions/<Name>, mit einer Komponente pro Abschnittstyp (Hook, Punkt, Statistik, Liste, CTA).
  2. Berechne die Dauer aus dem Skript (Summe der Abschnitte − Übergänge), wie von getSampleIntroDuration.
  3. Registriere es in src/Root.tsx mit Inline-defaultProps.
  4. Nur Musik: Schreibe eine Timeline-JSON mit totalMs, outroStartMs und events, führe dann tools/music.py aus.

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 optional refVoice: eine saubere 10-30 s WAV-Datei in tools/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), optional event + 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
WerkzeugAusgabe
tools/voice.pypublic/<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.mjspublic/<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.pypublic/<slug>/music.wav (MIDI → FluidSynth, an die Schnitte angepasst), public/<slug>/sfx.wav
tools/qa.pystories/<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:

  1. npm run lint.
  2. Jede Zeile in stories/<slug>/captions-report.json mit 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 unter filled aufgelistet: Höre an diesen Stellen. Liegt die matchRate unter 70 %, unterscheiden sich Skript und Audio, also vertone vor dem Weitermachen neu.
  3. Rendere Standbilder an wichtigen Schlüsselpunkten (Hook, jeder Sprecher, jedes Ereignis, Outro), füge sie zu einem Kontaktblatt zusammen und sieh es dir an:
    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
    
    Ü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).
  4. Ziehe 4-5 Frames aus dem endgültigen MP4 und sieh sie dir an.
  5. 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 einfachem npm 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 defaultProps ein Inline-Objekt in Root.tsx ist.
  • Schreibe zsh-Schleifen über Zeilen als while read -r a b c; do …; done <<EOF, da for x in „a b c“ bricht.

Weitere Lektionen und wie du eigene hinzufügst: reference/lessons.md.

Gemessene Kosten (M1 Max, 64 GB)

SchrittZeit
Laden des Chatterbox-Modells~20 s pro Durchlauf (übersprungen, wenn jede Zeile zwischengespeichert ist)
Spracherzeugungerste 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 + SFX2-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.

Verwandte Skills