Cartoon-Kurzfilm: Idee → Skript → Sprachaufnahme → fertiges MP4
Der Look: flache 2D-Bohnenkopf-Cartoon-Figuren (in Canvas gezeichnete „Karten“ mit plummen Umrissen) in einer bunten 3D-Welt mit schwarzen Tuschelinien, gemalten Texturen, Tiefenschärfe und gleitenden Kameras. Die Ausgabe ist 1080x1920, 30 fps, genau so lang wie die Sprachaufnahme. Die Stimme des Nutzers bleibt unverändert. Der Musikteppich und die Soundeffekte werden synthetisiert und liegen bei 50 % des Stimmenpegels. Bewährt mit „Der Soldat, der nie ging“ (19,7 s, 8 Einstellungen).
Regeln
- Geschichten, Figuren und Einstellungen sind immer originell. Erstelle niemals die Videobilder eines anderen Schöpfers eins zu eins nach. Biete stattdessen einen originellen Ansatz zur gleichen Idee an.
- Keine echten, namentlich genannten lebenden Personen als Figuren und keine Markenmaskottchen oder Logos.
- Keine Untertitel, es sei denn, der Nutzer wünscht sie. Diegetischer Text (eine geritzte Nachricht, ein Schild) ist in Ordnung und muss richtig lesbar sein (nicht gespiegelt).
- Bearbeite oder verschiebe die Sprachaufnahme niemals zeitlich. Das Bild wird darauf abgestimmt, und jede visuelle Reaktion erfolgt 0-3 Bilder vor ihrem Wort.
- Audio-Pegel: Der Musikteppich liegt bei 50 % des Stimmenpegels (−6 dB, gegated RMS). Soundeffekte liegen bei 50 % oder etwas weniger, mit Spitzenwerten, die so begrenzt sind, dass kein Treffer über die Erzählung hinausragt. Mische immer mit
mix.py, niemals von Hand. Verwende kein Ducking oder Kompression, das dieses Verhältnis ändern würde; nur eine lineare Verstärkung plus ein Peak-Limiter wird auf den gesamten Mix angewendet. - Halte den Nutzer mit einer Aufgabenliste auf dem Laufenden. Sende vor dem langen Rendern ein Kontaktblatt mit Standbildern.
Stufe 1: Aufnahme (immer zuerst)
Wenn bereits eine Audiodatei angehängt ist, springe direkt zu Stufe 4. Wenn auch ein Skript angegeben wurde, verwende es für das Timing. Andernfalls stelle eine AskUserQuestion (oder einfachen Text, falls dieses Tool fehlt): „Wo fängst du an?“
- Sprachaufnahme fertig: Bitte den Nutzer, sie hochzuladen, sowie den Skripttext, falls vorhanden (das Skript macht das Timing exakt). Gehe zu Stufe 4, wenn sie ankommt.
- Ich habe ein Skript, brauche die Sprachaufnahme: Straffe das Skript ggf. gemäß Stufe 3, gib es mit Aufnahmetipps zurück, bitte um den Upload und gehe dann zu Stufe 4.
- Brauche Videoideen und ein Skript: Gehe zu Stufe 2. Frage auch nach der Ziellänge, falls der Nutzer sie nicht genannt hat. Die Standardlänge beträgt 20-30 s; 45-60 s sind erlaubt.
Stufe 2: 10 Videoideen
Gib genau 10 Ideen in einer Antwort, nummeriert, und bitte den Nutzer, mit einer Zahl zu antworten (oder „mehr“). Jede Idee erhält:
- Titel (5-8 Wörter, neugierig machend, z. B. „Der Soldat, der nie ging“).
- Aufhänger-Satz: der erste gesprochene Satz, ein Paradoxon als Tatsache formuliert („Ein Mann verkaufte den Eiffelturm. Zweimal.“).
- Die Wendung in einem Satz (das ironische Ende, das das Video abschließt).
- Warum es sich gut animieren lässt: die 2-3 großen visuellen Momente (ein Einsturz, eine Enthüllung, eine Verfolgungsjagd).
- Wahr oder Legende: sage klar, ob es sich um dokumentierte Geschichte, eine umstrittene Darstellung oder Folklore handelt.
Was eine Idee „perfekt“ für dieses Format macht:
- Eine überraschende Geschichte mit einer physischen Ursache und Wirkung, die du zeigen kannst.
- Eine klare Jedermann-Figur, eskalierende Einsätze und eine Wendung im letzten Satz.
- Ein Schauplatz, der aus einfachen 3D-Formen plus Cartoon-Karten aufgebaut werden kann (Städte, Brücken, Schiffe, Burgen, Wüsten, Labore, Paläste).
- Mische die 10 Ideen über Epochen und Themen hinweg: Antike, Mittelalter, 1800er, Neuzeit, Wissenschaft, Tiere, Erfindungen, Katastrophen, seltsame Gesetze, glückliche Zufälle.
- Für alles, das als wahr präsentiert wird, überprüfe die Schlüsselfakten vor dem Angebot mit einer Websuche. Präsentiere keine viralen Legenden als Tatsache. Wenn der Nutzer es trotzdem will, rahme es als „Legende besagt“ ein.
- Keine echten lebenden Personen als Zielscheibe eines Witzes, nichts Grafisches und nichts Politisches.
Stufe 3: Skript (nach der Auswahl)
Schreibe nur die Erzählung (keine Regieanweisungen im gesprochenen Text), mit etwa 3,7 Wörtern/s: 20 s ≈ 75 Wörter, 30 s ≈ 110, 60 s ≈ 220. Formel:
- Aufhänger (Satz 1, keine Einleitung): die absurde Tatsache.
- Schauplatz in 1-2 Zeilen: wann, wo, wer, ein konkretes Detail.
- Steigerung, 2-4 Schritte, jeder größer. Andere zweifeln oder spotten. Verwende einen Übertreibungswitz.
- Geheimnis oder Wendepunkt: „Doch als...“ / „Siehst du,“ führt den eigentlichen Mechanismus ein, oft mit einer Alltagsanalogie.
- Wendung / Auflösung: kurz, ironisch und die letzten Worte des Videos. Verwende einfaches gesprochenes Deutsch, Zusammenziehungen, Sätze mit etwa 8-15 Wörtern und Zahlen als Wörter geschrieben. Beschreibe niemals, was der Zuschauer bereits sieht.
Antworte dann mit:
- Dem Skript in einem kopierbaren Block mit der Wortanzahl und der geschätzten Länge.
- Einem Absatz mit dem visuellen Plan (die Einstellungen, die du animieren wirst).
- Aufnahmetipps: eine ruhige, warme Erzählerstimme; ElevenLabs funktioniert gut (eine tiefe Erzählerstimme, Geschwindigkeit etwa 1,05-1,1, Stabilität etwa 45-55 %). Mp3 oder wav ist in Ordnung. Lasse natürliche Pausen an Satzenden. Exportiere ohne Musik.
- Der Aufforderung: „Lade die Sprachaufnahme hoch, wenn sie fertig ist, und ich mache das vollständige Video.“ Behalte den endgültigen Skripttext. Er steuert das Timing in Stufe 4, sodass keine Spracherkennung nötig ist. Wenn der Nutzer eine geänderte Version aufgenommen hat, bitte um den endgültigen Text.
Stufe 4: Video erstellen (nachdem die Sprachaufnahme hochgeladen wurde)
Alles von hier an ohne Unterbrechung erledigen. Nur fragen, wenn das Timing nicht aufgelöst werden kann.
4.0 Das Kit holen
Das Code-Kit befindet sich innerhalb dieses Skill-Ordners unter kit/ (Engine, Werkzeuge, Arbeitsbeispiel, dazu gebündeltes three.js r160 und die toon.ts Pen-Bibliothek von github.com/mromidev/claude-animated-shorts, beide MIT). Finde den Ordner mit find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/null und behandle sein kit/ als schreibgeschützt.
Führe dann bash <skill>/kit/tools/setup.sh ~/shorts/<slug> aus. Das kopiert die Engine und Werkzeuge in das Projekt, installiert das gebündelte three.js, entfernt die Typen aus toon.ts mit Node 22 module.stripTypeScriptTypes und verlinkt Playwright. Es wird keine Netzwerkverbindung benötigt. Wenn die gebündelten Dateien fehlen, fällt es auf npm oder einen Git-Clone zurück.
- Voraussetzungen: Node 22.6+, Python 3 mit numpy + Pillow, ffmpeg und Playwright mit Chromium (
npm i -g playwright && npx playwright install chromiumfalls nicht vorhanden). - Wenn Paketregistrierungen blockiert sind, funktioniert Git über GitHub normalerweise. Deaktiviere niemals TLS oder umgehe den Proxy.
- Chromium: Verwende den vorinstallierten Playwright-Browser mit
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklist. Das ergibt CPU-WebGL mit etwa 3-10 s pro Bild.
4.1 Timing
Führe python3 timing.py voice.mp3 script.txt --out work aus.
- Mit installiertem Whisper oder Faster-Whisper werden Wort-Zeitstempel verwendet.
- Andernfalls gleicht es Skriptphrasen (an Satzzeichen getrennt) mit stimmaktivitätsdetektierten Sprachsegmenten ab, mit einem DP, der Silben der Dauer zuordnet und Satzenden innerhalb eines Segments und lange Lücken innerhalb einer Phrase bestraft.
- Ohne ASR und ohne Skript frage nach dem Skript. Claude kann kein Audio hören.
- Überprüfe
work/phrases.json: Pausen sollten an Satzenden liegen. Gesamtbilder = round(duration × 30).
4.2 Einstellungsplan (work/PLAN.md vor dem Code)
Erstelle eine Zeile pro Einstellung: Bilder, Wörter, Schauplatz, Licht, Kamerabewegung, Figuren/Posen/Ausdrücke, Effekte und SFX-Hinweis.
- Bild 0 ist bereits das Aufhängerbefehl.
- Normalerweise eine Einstellung pro Phrase. Füge winzige Phrasen in die nächste Einstellung ein.
- Illustriere jeden Satz wörtlich. Requisiten tragen die Witze.
- Variiere die Einstellungsgrößen: Aufhänger MCU → weit aufdecken → Zweiershot → Detailaufnahme des Schlüsselobjekts → Reaktions-CU → Umgebungsbewegung für das Ende.
- Verwende Licht für Spannungsbögen: Tag für Normal, Gold für Niedergang oder Drama, Nachtblau für Erklärungen. Ein Zeitsprung erhält einen 6-Bilder-weißen Blitz.
- Der Wendungszeile erhält einen Sting (Musik stoppt, tiefer Schlag, Push-In mit Rolle). Der physische Höhepunkt der letzten Einstellung trifft das letzte Wort.
4.3 Welt (web/main.js)
Behalte die Engine-Abschnitte: Toon-Materialien, Tuschekontakt, add/tbox, Himmel, Lichter, Karten, Renderziele/Nachbearbeitung, applyLight, drawActors, swapForNd, renderFrame. Ersetze die Beispielwelt zwischen // ---------- Welt ---------- und // ---------- Karten ----------, sowie die Story-Teile von worldState().
- Baue aus Primitiven mit bemalten Canvas-Texturen (
paint.js: Planken, Balken, morsches Holz, Stein, Moos/Efeu, Gras, Erde, Putz, Dachziegel, Marmor, Banner, geritzter Text). Schreibe neue Maler im gleichen flachen Stil mit dunklen Nähten. - Verwende
tboxfür konstante Texeldichte, einen 2-Stufen-Toon-Verlauf und Nebel = Horizontfarbe. - Hintergrund: Hügel (halbvergrabene Kugeln), Berge (Kegel + Schneekappen), Zypressen/Kiefern, ferne Häuser, bemalte Wolken-Billboards.
- Bauteile (Einstürze, Fälle, Türen) sind um 0..1 Fortschritt von
worldAt(f)gedrehte Gruppen mit angetriebenen und gestaffelten Teilen. - Gekrümmter diegetischer Text verwendet planare UVs. Überprüfe, dass er nicht gespiegelt ist.
4.4 Besetzung (web/roman.js → web/toon.js)
romanFront(p, outfitKey, opts)zeichnet auf eine 600x1000 Design-Leinwand mit Sohlen bei y=975. Die Karte ist 2,25 m hoch, also ist 1 Einheit = 0,00225 m.- Füge Outfits zu
OUTFITShinzu (Tunika/Umhang/Rüstung/Helm/Haar/Kappe/Bart/Schürze/Kleid/Toga) und neue Kopfbedeckungen und Requisiten im gleichen Stil. - Armhaltungen: hängen, Speer, zeigen, hoch, winken, Hüfte, Bauch, Schläfe (+wirbeln), heben, reichen (+heben), Wange, Schild, überkreuzt, Daumen.
- Ausdrücke: der toon.ts FACE-Satz plus Schnarchen, stur, zusammenkneifen. Erweitere FACE für mehr.
- Baue nach Änderungen mit
cat web/toonbase.js web/roman.js > web/toon.jsneu. Rendere ein Figurentestblatt, bevor du neue Designs verwendest. - Billboards drehen sich nur um die Gierachse, erhalten einen Kontaktblob und einen Alpha-getesteten Schatten und werden niemals vom Weltdurchgang getuscht.
- Baue Kartenschlüssel aus auf
q()gerundeten Werten (damit die Leinwand nur bei sichtbaren Änderungen neu gezeichnet wird). - Ein losgelöster Teil (z. B. ein angehobener Helm) ist eine eigene Karte, ausgerichtet mit
headCenter(seed): y = DECK + (partY − hc) × 0,00225.
4.5 Motion: geschmeidig und lebendig (web/motion.js)
- Kameras:
camFromKeys(keys, f, {kicks}). Verwende geschmeidigere Schrittgleiten (18-45 f),easeOutfür Enthüllungen und Peitschen undpathüber Zwischenpunkte (Catmull-Rom) für geschwungene Bewegungen. Jedes Halten kriecht, und nichts ist 4+ Bilder statisch. Verwende 3-5° Rollen bei Dramen und 7-Bilder-Wackelschüttler bei Einschlägen. - Kontinuität: Bevorzuge kontinuierliche Bewegungen (Herauszoomen aus einer Nahaufnahme in die Weite, Fokus ziehen, Kranfahrt durch das Deck, Hineinzoomen in ein Objekt). Harte Schnitte nur bei Orts- oder Zeitsprüngen, mit einem Blitz.
- Figuren frieren niemals ein: Wende
idle(f, seed)auf jede Karte an,blinkAtblinzelt, und Kopfnicken bei betonten Wörtern. - Aktionen: Antizipation →
back-Überschwinger →spring-Einpendeln. Ein Stampfen ist ein 2-Bilder-Dipp + Staubwolke + Tritt. Lachen ist ein abwechselndes Neigen + Wippen. - Sekundäre Bewegung: Bannerwellen, Blätter/Staub/Tropfen/Zzz-Effektkarten, fließendes Wasser. Es bewegt sich immer etwas.
- Gänge:
walk()gibt Distanz + Schrittphase. Füße aufgesetzt, Wippe 3-7 %. - Objektiv: Tiefenschärfe bei Nahaufnahmen und Halbnahaufnahmen (cInf 8-14 px), Fokus auf die Augen. Weite Aufnahmen sind scharf. Fokuswechsel dauern ~14 f.
4.6 Look-Check (vor dem vollständigen Rendern)
Rendere Standbilder in der Mitte jeder Einstellung plus die Übergänge und Schlüsselaktionen: node render.mjs stills/a "5,40,..." dann python3 sheet.py stills/a stills/sheet_a.jpg. Betrachte das Blatt und behebe diese Fallstricke:
- Schmaler vertikaler Rahmen: horizontale Halbbreite = d·tan(hfov/2), mit hfov = 2·atan(tan(vfov/2)·0,5625). Bei 4 m und fov 40 sind das ±0,8 m, also staffele Figuren in der Tiefe.
- Geländer oder Pfosten vor Gesichtern (Kamera innerhalb des Geländers oder ~2,5 m hoch). Kamerapfad durch Häuser, Dächer oder Büsche. Vordergrund-Requisiten unter ~2 m Entfernung. Der Held hinter einer Säule versteckt.
- Gespiegelter Text. Ein losgelöster Kartenteil mit falschem Offset.
- Extrude-Materialgruppen: 0 = Kappen, 1 = Seiten+Oberseite.
- Fehlende Tusche: Debugge die kantenbetonte Ausgabe. Tuscheradius ~2,5 px bei 1080. Der Himmel zählt als ferne Tiefe, nicht als Karte. Sende das Blatt an den Nutzer mit einer einzeiligen Einstellungszusammenfassung und starte dann das vollständige Rendern.
4.7 Sound (audio.py → Stems → mix.py)
Schreibe die Cue-Tabelle für die Geschichte um; die Synthesizer bleiben erhalten. audio.py schreibt nur Stems (music.wav, sfx.wav).
- Musik: eine kurze marschähnliche Schleife (Kick/ Snare, gezupfter Bass, Blechbläserpad). Sie stoppt an der Wendungszeile, dann setzt ein tiefer Dröhnklang ein.
- SFX zu Ereignissen (in Frames/30): Whooshes bei großen Bewegungen, Thunk bei Stampfern, Grollen+Krach bei Einstürzen, Schaben bei Metall, Ting bei Enthüllungen, Sting bei der Wendung, Knarzen, Schnappen, Platschen, Schnarchen, Blätter, Wasseratmosphäre.
- Mische mit
python3 mix.py voice.mp3 music.wav sfx.wav. Das setzt die Musik auf genau 50 % des gegateden RMS der Stimme (−6 dB) und die SFX auf 50 % mit Spitzenwerten, die auf das 0,7-fache des Stimmspitzenwerts begrenzt sind. Es gibt die gemessenen Pegel aus: Bestätige, dass die Musik −6,0 dB gegenüber der Stimme anzeigt und die SFX darunter oder gleich sind. - Stelle das Bild-Timing fest, bevor du Sound erstellst. Jede Timing-Änderung bedeutet, dass audio.py und mix.py erneut ausgeführt werden müssen.
4.8 Rendern + Abschließen
- Führe
node render.mjs frames "0-<N-1>"mit Bashrun_in_backgroundaus, überwacht von einer Monitor-Schleife, die den Fortschritt meldet und Fehler oder Prozessende abfängt.RESUME=1setzt nach einer Unterbrechung fort. Führe nicht gleichzeitig schwere Python-Sachen auf kleinen Maschinen aus. - Führe
bash finish.sh "Titel"aus. Es wendet eine lineare Verstärkung auf etwa −14 LUFS plus einen −1 dBFS Peak-Limiter an, kodiert H.264 CRF 17 + AAC, führt Einfrier-/ Schwarz- und Lautstärke-QA durch und schreibtout/qa_sheet.jpg. Betrachte das Blatt. Eingefrorene Abschnitte ≥0,4 s oder schwarze Bilder erfordern eine Korrektur. - Liefere das MP4 mit SendUserFile und ein paar Zeilen, was jede Einstellung zeigt. Biete Untertitel, Anpassungen oder die nächste Idee aus der Liste an.
Engine-Fallstricke (im Kit behalten; behalte sie, wenn du es neu aufbaust)
#include <fog_vertex>/<fog_fragment>müssen in eigenen Zeilen stehen.- Der letzte Durchgang schreibt
linearToOutputTexel(...)(Renderziele sind linear HalfFloat). - Der Normalen-+Tiefendurchgang tauscht Materialien pro Mesh aus: Welt → Normalen-/Tiefe, Karten → Alpha-getestete Maske (rgb 0, a = Tiefe), Blobs/Wolken/Himmel ausgeblendet, Wasser → flache Normale. Nebel und Schatten sind währenddessen ausgeschaltet.
- Tusche wird nur auf der nahen Seite von Tiefensprüngen angebracht. Risse stammen von der Normalen-Punktprodukt. Kartennachbarn werden übersprungen. Tusche verblasst bei ~140-520 m.
- Tiefenschärfe: 48 Abtastungen mit einem per-Sample CoC-Test (kein Vordergrundüberlauf).
- Die Sonne kommt von Azimut/ Elevation pro Lichtvoreinstellung. Die Schattenkamera ist auf die Aktion jeder Einstellung zentriert.
Architektur (Referenz zum Bearbeiten des Kits)
web/index.htmllädtmain.js(ES-Modul) über einen lokalen HTTP-Server.main.js: Renderer, Toon-Materialien, Welt, Karten (1200x2000 CanvasTexture-Ebenen, Ursprung an Sohlen), gibt Farbe (RT samples 4) → Normalen/Tiefe → Tusche+Grading (Sättigung, Gain/Lift) -> Tonzuordnung -> Ausgabe aus.- Kamera- und Karten-
updatewerden inrenderFrameaufgerufen. timing.pyverwendet eine DP, die Silben auf Dauer abbildet, mit Lücken- und Überlappungsstrafen.paint.jserzeugt Texturen als flächige Canvas-Bilder, die vonmainalsdata:-URI geladen werden.audio.pyerzeugt Musik- und SFX-Stems aus einer Cue-Tabelle mit einfachen Synthesizern (Oszillatoren, Rauschen, Hüllkurven) und schreibt WAV-Dateien.mix.pymischt die Stems auf die Zielpegel, schreibt die gemessenen Pegel und gibt eine Mischung aus.render.mjsstartet Chromium über Playwright, ruftrenderFramefür jede Bildnummer auf und speichert PNG-Dateien. Unterstützt Auflösung für eingeschränkte Umgebungen.finish.shfasst PNGs zu einem Video mit ffmpeg zusammen, wendet eine lineare Verstärkung + Limiter an, kodiert und führt QA durch.she.pyerstellt ein Kontaktblatt aus einer Liste von Bildern.- Das Kit verwendet keine externen Assets. Texturen, Schriftarten und Umgebungen werden prozedural generiert oder aus dem Kit geladen.
Lizenz und Hinweise
Dieses Skill wird unter der MIT-Lizenz bereitgestellt. Es gebündelt three.js (MIT) und die toon.ts Pen-Bibliothek (MIT). Die ausgegebenen Videodateien unterliegen keiner Einschränkung.
Fehlerbehebung
- „Setup schlägt fehl“: Stelle sicher, dass Node 22.6+ und Python 3 mit den oben genannten Paketen installiert sind. Führe
setup.sherneut aus; es überspringt bereits erledigte Schritte. - „Chromium startet nicht“: Installiere Playwright und Chromium mit
npm i -g playwright && npx playwright install chromium. Verwende die Software-Rendering-Flags aus Abschnitt 4.0. - „Tusche fehlt“: Überprüfe die Normale-Tiefe-Pass-Ausgabe. Stelle sicher, dass die Karten-Materialien den Alpha-Test-Pass durchlassen.
- „Timing stimmt nicht“: Prüfe
work/phrases.jsonund die Audiodauer. Führetiming.pymit dem exakten Skripttext neu aus. - „Karten werden nicht angezeigt“: Überprüfe die Konsole auf Fehler im Browser. Stelle sicher, dass die Kartenschlüssel geändert werden, wenn sich Designs ändern.