Serie für Comedy-Kurzfilme mit weißem Hintergrund und Strichzeichnungen (白底简笔吐槽)
Ein Video = ein Drehbuch + ein Storyboard + eine Tonspur + ein Cover + Veröffentlichungsmaterial. Alles wird mit den gleichen Zeichenprimitiven und Schriftarten erstellt, sodass in der gesamten Serie ein einheitlicher Stil herrscht und Cover und Video nahtlos zusammenpassen.
Lieferumfang
Jede Episode muss diese 5 Dateien liefern, keine davon darf fehlen:
| Ausgabe | Datei | Spezifikation |
|---|---|---|
| Video mit Untertiteln | out/<Titel>_简笔吐槽_字幕版.mp4 | 1080×1440, 30fps, H.264+AAC, ca. 68s |
| Video ohne Untertitel | out/<Titel>_简笔吐槽_无字幕版.mp4 | Wie oben, aber ohne Untertitel-Ebene |
| Untertiteldatei | out/<Titel>.srt | Einzelne Zeile ≤16 Zeichen, Zeitangaben aufsteigend und nicht überlappend |
| 3:4-Cover | out/<Titel>_封面.png | 1080×1440, gleiche Linien und Schriftart wie das Video |
| WeChat-Kanäle-Material | project_*/publish.md + publish.json | 3 Titelvarianten, 1 Beschreibung, 5–8 Hashtags, 1 gepinnter Kommentar |
Zusätzlich: out/<Titel>_预览.png (Vier-Bild-Schlüsselszene-Streifen), damit der Benutzer eine ganze Episode auf einen Blick sehen kann.
Umgebung
Python 3.10+, Pillow, NumPy, ffmpeg/ffprobe. Zuerst eine virtuelle Umgebung erstellen, das systemweite Python nicht anfassen:
python3 -m venv .venv && .venv/bin/pip install -r "$skill_dir/scripts/requirements.txt"
Unter macOS ist ffmpeg oft nicht im Standard-PATH. Zuerst export PATH="/opt/homebrew/bin:$PATH".
Die Sprachausgabe verwendet mcode-tools (MiniMax TTS/ASR) – die Fähigkeit mcode-tools-master muss im PATH sein.
Wenn python3 mit You have not agreed to the Xcode license agreements (Exit-Code 69) fehlschlägt,
ist das systemweite Python nicht richtig installiert. Verwenden Sie einen anderen funktionierenden Interpreter,
um die Umgebung zu erstellen, z.B.
/opt/homebrew/bin/python3.13 -m venv .venv – ändern Sie nicht die Xcode-Lizenzvereinbarung.
Arbeitsablauf
1. Themenauswahl und Serienpositionierung
Einzelne Episode: Ein grober Anhaltspunkt für die Art des Humors genügt. Mehrere Episoden: Jede Episode bekommt einen sich gegenseitig ausschließenden Humor-Stil – nicht die gleiche Pointe in neuem Gewand.
- Selbstironisch-absurd (der Sprecher übertrifft sich selbst immer weiter)
- Dialog-Wendung (zwei Personen unterhalten sich, die letzte Zeile dreht den Spieß um)
- Kalte Beobachtung (Beobachter-Humor, trocken und distanziert)
- Absurde Prämisse (eine lächerliche Annahme wird ernst genommen)
In derselben Serie sollten mindestens zwei verschiedene Humor-Stile nebeneinander vorkommen. Die visuelle Sprache kann geteilt werden, aber der Erzählrhythmus sollte nicht gleich sein.
2. Drehbuch schreiben
Lesen Sie [references/writing-style.md]. Harte Vorgaben:
- Eine Zeile pro Einstellung, ca. 40–45 Zeilen, 480–520 Zeichen, Ziel ca. 68s (Zeichen ÷ 7,4 ≈ Sekunden).
- Jeder Gag muss eine sichtbare Handlung oder Requisitenänderung enthalten, er darf nicht nur durch Untertitel vermittelt werden.
- Das Ende muss die Rollenbeziehung umkehren und eine Zeile enthalten, die man als Screenshot teilen kann.
- Als JSON schreiben:
{"title": ..., "target_seconds": 68, "segments": [{"scene": ..., "text": ..., "red": [...]}]}sceneist die Bild-ID,redenthält die Wörter, die rot markiert werden sollen (müssen im Originaltext intextvorkommen).
3. Storyboard erstellen
"$python_bin" "$skill_dir/scripts/build_segments.py" --story story.json --out project_ep2
Die Untertitel werden an Satzzeichen in Zeilen ≤16 Zeichen geteilt; der Renderer kann keine Zeilen über 17 Zeichen verarbeiten. Teilungspunkte sollten nahe an 10 Zeichen liegen,
und Wörter dürfen nicht auseinandergerissen werden („großer Vorauszahlungsbetrag“ darf nicht in „großer Voraus“ und „zahlungsbetrag“ geteilt werden); kurze Sätze in Anführungszeichen werden als Ganzes nicht geteilt,
es werden keine Zeilen erzeugt, die mit 」 beginnen. Das Skript prüft, ob die roten Wörter im Untertitel vorkommen, ob bei der Teilung keine Zeichen verloren gehen und ob keine leeren Untertitel (nur Satzzeichen) entstehen.
Es gibt auch eine geschätzte Dauer aus: Zeichen ÷ 7,4 ≈ Sekunden. Eine Abweichung von ±10 % vom Ziel führt zu einer Warnung – Sätze nach Anleitung hinzufügen oder entfernen, nicht die Sprechgeschwindigkeit anpassen.
4. Storyboard zeichnen
Schreiben Sie in project_ep2/scenes.py die Funktionen scene_<id>(c, t, d) und definieren Sie am Ende der Datei das Wörterbuch SCENES neu (nur die IDs dieser Episode). Die Zeichenprimitiven finden Sie in scripts/render/doodles.py.
person(c,x,y,s,expr,boss,pose,t,arms,legs): Kopfmitte bei (x,y), Körper bis y+307*s,expristdead/sad/happy/angry/shocked/sleep,poseiststand/shrug/point/phone/pockets/walk.woman(c,x,y,s,expr,t): Mutter-Figur (Haarknoten + Rock).speech(c,x,y,w,h,tail,size): Sprechblase;c.text((x,y),'Text',size)ist der zentrierte Ankerpunkt.c.curveakzeptiert nur 4 Kontrollpunkte;c.textunterstützt keine Konturen oder mehrzeiligen Text.
Nach Änderungen zwei Qualitätstore durchlaufen:
"$python_bin" "$skill_dir/scripts/check_overlap.py" project_ep2/scenes.py # Statisches Layout-Audit
"$python_bin" "$skill_dir/scripts/check_project.py" project_ep2 # Kontakttabelle-Prüfung
check_overlap.py findet Text, der Personen überlappt, Text, der sich gegenseitig überlappt, und Elemente außerhalb des Sicherheitsbereichs. Es erkennt zwei Fälle von „scheinbar überlappend, aber nicht wirklich“: sich gegenseitig ausschließende Texte in if/else-Blöcken und weiße Hintergrundblöcke, die alte Elemente überdecken.
Die gemeldeten Probleme sind daher fast immer echte Fehler – Wenn der Exit-Code nicht 0 ist, zuerst reparieren, nicht direkt rendern.
check_project.py prüft zuerst die Untertitel und dann die Kontakttabelle: Die zusammengesetzten Untertitel müssen mit dem Dialog identisch sein (Satzzeichen dürfen nachbearbeitet sein, aber keine zusätzlichen, fehlenden oder geänderten Wörter). Es darf keine leeren Untertitel geben. Bei Fehlern wird sofort abgebrochen, um keine Renderzeit zu verschwenden.
Für Überlappungen, die absichtlich bleiben sollen (z.B. ein Anstecker auf einer Person), registrieren Sie sie explizit in scenes.py:
OVERLAP_ALLOW = {"three_years", "me_too"}
Die Kontakttabelle muss Szene für Szene überprüft werden: Passt das Bild zu dieser Dialogzeile? Sind die Requisiten klar erkennbar?
5. Sprachausgabe (Voiceover)
"$python_bin" "$skill_dir/scripts/build_voice.py" --project project_ep2 --speed 1.5 --gap 0.10
Satzweise Synthese ist der Kern dieses Workflows: Jeder Satz wird einzeln per TTS synthetisiert, Stille am Anfang und Ende wird entfernt, dann werden die Sätze mit einem festen Abstand aneinandergereiht.
Daher sind die Start- und Endzeiten jedes Satzes bekannt, asr.json wird direkt aus diesen Zeiten konstruiert – Untertitel-Ausrichtung ohne Fehler, keine wortgenaue ASR erforderlich.
- Standardstimme:
lengdan_xiongzhang(gleichgültiger älterer Mitschüler). Der Benutzer kann eine andere angeben. - TTS hat kurzfristige Ratenbegrenzungen (HTTP 429). Das Skript wiederholt alle 10 Sekunden – ein fester Abstand ist effektiver als exponentielle Verzögerung.
- Eine Episode (ca. 40–45 Sätze) dauert insgesamt etwa 15 Minuten und läuft im Hintergrund.
- Nach der Synthese mit
scripts/tts.py asr --file project_ep2/voice.wavstichprobenartig prüfen. - Bei ähnlich klingenden Erkennungsfehlern („手続き/手続き時“) nur die Wörter im ASR-Ergebnis korrigieren, nicht das Drehbuch ändern oder neu aufnehmen.
6. Timeline, Rendering und Abnahme
"$python_bin" "$skill_dir/scripts/deliver.py" project_ep2 <Titel> --target 68
"$python_bin" "$skill_dir/scripts/verify.py" project_ep2
deliver.py berechnet atempo basierend auf der Zieldauer (Geschwindigkeit = Original-Audio / (Ziel - Nachlauf)),
erzeugt Timeline, Untertitel, mischt den Ton, rendert Versionen mit und ohne Untertitel und archiviert die fertigen Videos und die SRT-Datei in out/.
verify.py prüft: Codierungsparameter, vollständige Dekodierung des Videos, Untertitel-Timing und -Länge, ASR-Rückwärtsvergleich.
Die Abnahme gilt erst als bestanden, wenn alle Prüfungen grün sind; bei Dekodierungsfehlern oder Problemen mit dem Untertitel-Timing muss korrigiert und neu gerendert werden.
7. Cover
Das Cover wird nicht mit KI-Bildgenerierung erstellt, sondern mit denselben Zeichenprimitiven und Schriftarten wie das Video – null Stilabweichung.
Schreiben Sie in project_ep2/cover.py die Funktion illustration(c) (die Zeichenprimitiven sind bereits in den Namensraum injiziert).
Definieren Sie in project_ep2/cover.json die Textzeilen:
{"lines": [
{"text": "相亲现场", "size": 146, "y": 170, "red": []},
{"text": "我妈给我报了七个", "size": 96, "y": 312, "red": ["七个"]},
{"text": "见家长见姥姥", "size": 64, "y": 1196, "red": []},
{"text": "八十七了也不催生", "size": 64, "y": 1280, "red": ["催生"]}
]}
"$python_bin" "$skill_dir/scripts/make_cover.py" project_ep2
Layout-Regeln finden Sie in [references/cover-design.md]. Das Cover muss vor der Auslieferung noch einmal einzeln angesehen werden.
8. Veröffentlichungsmaterial für WeChat Channels (视频号)
Zuerst die Materialien extrahieren, dann den Text schreiben:
"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2
Das Skript gibt das vollständige Drehbuch, die roten Wörter, häufige Wörter und die letzten drei Sätze aus. Schreiben Sie darauf basierend:
- 3 Titelvarianten mit Emoji-Hooks, jede ≤22 Zeichen (bevorzugt, harte Obergrenze 100 Zeichen).
- 1 endgültige Beschreibung, 2–3 Zeilen, die erste Zeile ist der Hook. Hashtags werden mit
#Hashtaginline in den Text eingefügt. - 5–8 Hashtags, die alle in der Beschreibung vorkommen müssen (das Skript prüft dies).
- 1 gepinnter Kommentar, zur Ergänzung oder selbstironischen Anmerkung.
Nach dem Schreiben:
"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2 \
--titles "Titel Eins" "Titel Zwei" "Titel Drei" \
--desc "Beschreibungstext #Hashtag1 #Hashtag2" \
--tags "Hashtag1" "Hashtag2" \
--comment "Gepinnter Kommentar"
Details zu den Regeln finden Sie in [references/publish-channels.md]. Ausgabe: publish.md / publish.json.
Harte Einschränkungen
- Leinwand: 1080×1440 (3:4), 30fps, reinweißer Hintergrund, Kontur 4–6px schwarze Linie, großer runder Kopf, dünner Körper.
- Hauptmotiv konzentriert auf y=400–1050, oberer Rand frei; Untertitelstreifen ab y=1084, Schriftgröße mindestens 54.
- Untertitel in „Xingkai“ (行楷), weiße Schrift mit weichem dunklen Schatten, Schlüsselwörter am Point rot markiert.
- Untertitelzeile maximal 16 Zeichen – der Renderer kann längere nicht darstellen.
- Der Haupttext wird nicht in das Bild eingebrannt, die Untertitel werden als separate Ebene gerendert.
- Das Cover muss dieselbe Schriftart und Linienführung wie das Video verwenden – kein Stilwechsel erlaubt.
- Vorhandene fertige Videos bleiben erhalten; Drehbuchänderungen verwenden ein neues Projektverzeichnis, bereits ausgelieferte Episoden werden nicht überschrieben.
Fehlerbehandlung
- TTS erhält ständig 429: Das Skript wiederholt 40 Mal mit festem Abstand. Wenn es immer noch fehlschlägt, die Geschwindigkeit auf 1.4 reduzieren oder in Batches ausführen (
--limit N) – der Cache überspringt bereits synthetisierte Sätze. prepare.pymeldet ASR-Inkonsistenz:asr.jsonund Drehbuch stimmen nicht überein – meist, weil das Drehbuch geändert, aber die Sprachausgabe nicht neu erstellt wurde.build_voice.pyneu ausführen, nicht mit--allow-asr-mismatchübergehen.render.pymeldet zu lange Untertitel: Ein Untertitel überschreitet 16 Zeichen. Die Teilungsregeln inbuild_segments.pyanpassen.check_overlap.pyExit-Code nicht 0: Die Koordinaten Szene für Szene korrigieren, bis der Exit-Code 0 ist.- Hören Sie nicht mit der Hörprüfung, bevor die Sprachausgabe vollständig durchgelaufen ist. Betrachten Sie das Video nicht komplett, bevor Sie es nicht vollständig gesehen haben. Halten Sie sich nur tatsächlich durchgeführte Überprüfungen im Auslieferungsprotokoll fest.
Referenzen
- references/writing-style.md — Drehbuch-Schreibweise und Gag-Design
- references/series-plan.md — Serien-Themenauswahl und Differenzierung
- references/cover-design.md — Cover-Layout-Regeln
- references/publish-channels.md — WeChat Channels Veröffentlichungsregeln
Hinweise für Windows (win32)
Entsprechende Vorgehensweise unter Windows:
- Virtuelle Umgebung:
py -3 -m venv .venv, danach.venv\Scripts\python.exeanstelle von$python_binverwenden. - Abhängigkeiten:
.venv\Scripts\pip.exe install -r "<skill_dir>\scripts\requirements.txt". - ffmpeg/ffprobe direkt in den PATH installieren (
winget install Gyan.FFmpeg), kein/opt/homebrew/binnötig; aber die ffmpeg-Pfade inscripts/deliver.py,scripts/make_preview.pyundscripts/verify.pysind als absolute macOS-Pfade hartcodiert – ändern Sie sie zuffmpeg/ffprobe, um plattformübergreifend zu funktionieren. scripts/build_voice.pybenötigtmcode-toolsim PATH sowiecurl; Windows 10 1803+ hat curl bereits integriert, falls nicht, kannInvoke-WebRequest -OutFile <pfad> <url>verwendet werden.- Pfadtrennzeichen: Alle Skripte verwenden
pathlib; bei der Parameterübergabe Pfade einfach in Anführungszeichen setzen.