Communitygithub.com

白底简笔吐槽短视频系列

Produisez une série de courts métrages humoristiques chinois au style « dessin au trait noir sur fond blanc, grosse tête » (白底简笔吐槽短视频). Le processus couvre le choix du sujet, l'écriture du script, le dessin des scènes, le doublage, le rendu, la création d'une couverture au format 3:4, et la rédaction des contenus de publication pour WeChat Channels (视频号) : titres, description, hashtags et commentaire épinglé.

Qu'est-ce que 白底简笔吐槽短视频系列 ?

Cette compétence spécialisée permet de générer automatiquement des vidéos courtes humoristiques au style graphique unique « doodle chinois » (trait noir, fond blanc, personnages à grosse tête). Elle couvre l'intégralité de la chaîne de production : de l'écriture du script à la publication en passant par le storyboard, le doublage TTS, le rendu vidéo et la création de la couverture. Conçue pour l'outil Claude Code, elle exploite Python (Pillow, NumPy) et ffmpeg pour produire des vidéos 9:16 verticales (1080×1440, 30fps) avec un sous-titrage précis, une piste audio basée sur MiniMax TTS, et des métadonnées optimisées pour WeChat Channels. L'utilisateur peut lancer une ou plusieurs épisodes d'une série en une seule commande, en garantissant une cohérence stylistique parfaite entre chaque épisode et sa couverture. La compétence inclut des validations automatiques (chevauchements, sous-titres, durée, qualité audio) pour assurer un résultat professionnel sans intervention manuelle.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/inhai-wiki/doodle-comedy-series/tree/HEAD

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Série de courts métrages humoristiques au style doodle (fond blanc, trait noir)

Une vidéo = un script + un storyboard + une piste audio + une couverture + un ensemble de contenus pour publication. Tout est dessiné avec le même ensemble de primitives graphiques et la même police, garantissant une cohérence de style entre chaque épisode de la série et une parfaite correspondance entre la couverture et la vidéo elle-même.

Engagements de production

Chaque épisode doit livrer ces 5 groupes de fichiers, aucun ne peut manquer :

ProductionFichierSpécifications
Vidéo finale avec sous-titresout/<titre>_doodle_avec_sous-titres.mp41080×1440, 30fps, H.264+AAC, environ 68s
Vidéo finale sans sous-titresout/<titre>_doodle_sans_sous-titres.mp4Identique ci-dessus, couche de sous-titres supprimée
Fichier de sous-titresout/<titre>.srtChaque ligne ≤ 16 caractères, intervalles de temps croissants sans chevauchement
Couverture 3:4out/<titre>_couverture.png1080×1440, mêmes traits et police que la vidéo
Contenus pour WeChat Channelsproject_*/publish.md + publish.json3 variantes de titre, 1 version de description, 5–8 hashtags, 1 commentaire épinglé

Ajoutez également out/<titre>_apercu.png (bande de 4 images clés) pour permettre à l'utilisateur de visualiser un épisode d'un coup d'œil.

Environnement

Python 3.10+, Pillow, NumPy, ffmpeg/ffprobe. Créez d'abord un environnement virtuel, ne modifiez pas le Python système :

python3 -m venv .venv && .venv/bin/pip install -r "$skill_dir/scripts/requirements.txt"

Sur macOS, ffmpeg n'est souvent pas dans le PATH par défaut. Exportez d'abord export PATH="/opt/homebrew/bin:$PATH". Le doublage utilise mcode-tools (MiniMax TTS/ASR). Assurez-vous que la compétence mcode-tools-master est dans le PATH.

Si python3 renvoie You have not agreed to the Xcode license agreements (code de sortie 69), cela signifie que le Python système n'est pas correctement installé. Utilisez un autre interpréteur pour créer l'environnement, par exemple /opt/homebrew/bin/python3.13 -m venv .venv. Ne touchez pas à la licence Xcode.

Processus

1. Définir le sujet et le positionnement de la série

Épisode unique : donnez une direction humoristique. Plusieurs épisodes : attribuez d'abord à chaque épisode une veine humoristique exclusive. Ne déclinez pas le même type de blague.

  • Courant d'autodérision absurde (le narrateur devient de plus en plus délirant)
  • Rebondissement dialogué (deux personnages avancent, la dernière phrase renverse la situation)
  • Courant d'observation froide (humour distancié, ironie sobre)
  • Courant de situation absurde (prendre une prémisse ridicule au sérieux)

Dans une même série, au moins deux veines humoristiques différentes doivent se succéder. Le langage visuel peut être partagé, mais le rythme narratif ne doit pas être identique.

2. Écrire le script

Lisez [references/writing-style.md]. Critères stricts :

  • Une phrase par plan, environ 40–45 phrases, 480–520 caractères, durée ≈ 68s (nombre de caractères ÷ 7.4 ≈ secondes).
  • Chaque gag doit se concrétiser par une action visible ou un changement d'accessoire. Il ne peut pas reposer uniquement sur les sous-titres.
  • La fin doit inverser la relation entre les personnages et laisser une phrase qui peut être citée seule en capture d'écran.
  • Écrivez au format JSON : {"title": ..., "target_seconds": 68, "segments": [{"scene": ..., "text": ..., "red": [...]}]} scene est l'identifiant de l'image, red sont les mots à marquer en rouge (doivent apparaître textuellement dans text).

3. Découper le storyboard

"$python_bin" "$skill_dir/scripts/build_segments.py" --story story.json --out project_ep2

Les sous-titres sont coupés selon la ponctuation en lignes de ≤ 16 caractères ; le moteur de rendu ne peut pas afficher plus de 17 caractères. Choisissez des points de coupe proches de 10 caractères, évitez de couper les mots (ex. « 大型预付 » ne doit pas être coupé en « 大型预 » et « 预付 ») ; les phrases courtes entre guillemets ne sont pas divisées, aucune ligne ne doit commencer par ». Le script vérifie que les mots rouges sont bien dans les sous-titres, que la découpe ne perd pas de caractères, qu'il n'y a pas de sous-titres vides (uniquement de la ponctuation), et affiche une estimation de durée : nombre de caractères ÷ 7.4 ≈ secondes. Un écart de ±10 % par rapport à la cible génère un avertissement — ajoutez ou supprimez des phrases selon l'indication, n'essayez pas de compenser en modifiant le débit de parole.

4. Dessiner le storyboard

Dans project_ep2/scenes.py, écrivez les fonctions scene_<id>(c, t, d) et redéfinissez le dictionnaire SCENES à la fin du fichier (contenant uniquement les identifiants de l'épisode). Les primitives graphiques sont dans scripts/render/doodles.py.

  • person(c,x,y,s,expr,boss,pose,t,arms,legs) : centre de la tête à (x,y), corps jusqu'à y+307*s, expr prend dead/sad/happy/angry/shocked/sleep, pose prend stand/shrug/point/phone/pockets/walk.
  • woman(c,x,y,s,expr,t) : silhouette maternelle (chignon + robe).
  • speech(c,x,y,w,h,tail,size) : bulle ; c.text((x,y),'texte',size) est ancré au centre.
  • c.curve n'accepte que 4 points de contrôle ; c.text ne supporte ni contour ni multi-lignes.

Après modifications, passez par deux vérifications :

"$python_bin" "$skill_dir/scripts/check_overlap.py" project_ep2/scenes.py   # Audit de disposition statique
"$python_bin" "$skill_dir/scripts/check_project.py" project_ep2             # Vérification du tableau de contact

check_overlap.py détecte le texte qui chevauche les personnages, les textes qui se chevauchent entre eux, et les éléments qui dépassent de la zone de sécurité. Il reconnaît déjà deux cas où « ça se chevauche mais ce n'est pas un problème » : les remplacements de texte mutuellement exclusifs dans les blocs if/else, et les blocs de couleur blanche qui couvrent d'anciens éléments. Les problèmes signalés sont donc de vrais problèmes — si le code de sortie est non nul, corrigez d'abord, ne lancez pas le rendu directement.

check_project.py vérifie d'abord les sous-titres, puis produit le tableau de contact : les sous-titres assemblés doivent correspondre exactement au texte du script (la ponctuation peut être ajustée manuellement, mais il ne doit pas y avoir de caractères supplémentaires, manquants ou de mots différents). Aucun sous-titre vide n'est autorisé ; en cas d'échec, le script s'arrête immédiatement sans gaspiller de temps sur le rendu du tableau.

Si vous devez conserver un chevauchement (ex. un badge sur un personnage), déclarez-le explicitement dans scenes.py :

OVERLAP_ALLOW = {"three_years", "me_too"}

Le tableau de contact doit être examiné plan par plan : l'image correspond-elle à la phrase ? Les accessoires sont-ils clairement dessinés ?

5. Doublage

"$python_bin" "$skill_dir/scripts/build_voice.py" --project project_ep2 --speed 1.5 --gap 0.10

La synthèse phrase par phrase est la clé de ce processus : chaque phrase est synthétisée individuellement par TTS, le silence de début et de fin est supprimé, puis toutes les phrases sont concaténées avec un intervalle fixe. Ainsi, les temps de début et de fin de chaque phrase sont connus, et le fichier asr.json est construit directement à partir de ces temps. L'alignement des sous-titres est parfait, aucune ASR au niveau du mot n'est nécessaire.

  • Voix par défaut : lengdan_xiongzhang (camarade senior froid). Si l'utilisateur en spécifie une autre, utilisez-la.
  • Le TTS a une limitation de débit à court terme (HTTP 429). Le script réessaie avec un intervalle fixe de 10 secondes — un intervalle fixe est beaucoup plus efficace qu'un backoff exponentiel.
  • Un épisode compte environ 40–45 phrases. Le processus complet prend environ 15 minutes et s'exécute en arrière-plan.
  • Après la synthèse, effectuez une vérification avec scripts/tts.py asr --file project_ep2/voice.wav.
  • En cas d'erreur de reconnaissance proche (ex. « 办事 / 办事时 »), modifiez uniquement les caractères dans le résultat ASR, ne changez pas le script et ne réenregistrez pas.

6. Timeline, rendu et validation

"$python_bin" "$skill_dir/scripts/deliver.py" project_ep2 <titre> --target 68
"$python_bin" "$skill_dir/scripts/verify.py" project_ep2

deliver.py calcule l'atempo en fonction de la durée cible (vitesse = piste originale / (cible - silence final)), génère la timeline, les sous-titres, le mixage audio, effectue le rendu des versions avec et sans sous-titres, et archive la vidéo finale et le fichier SRT dans out/.

verify.py vérifie : les paramètres de codec, le décodage complet de la vidéo, la synchronisation et la longueur des sous-titres, la réécoute ASR. La validation n'est terminée que lorsque tout est vert ; en cas d'échec de décodage ou de problème de synchronisation des sous-titres, corrigez et refaites le rendu.

7. Couverture

La couverture n'utilise pas d'IA générative d'images. Elle est redessinée avec le même ensemble de primitives graphiques et la même police que la vidéo, garantissant une cohérence de style parfaite.

Dans project_ep2/cover.py, écrivez la fonction illustration(c) (les primitives graphiques sont déjà injectées dans l'espace de noms). Dans project_ep2/cover.json, écrivez les lignes de texte :

{"lines": [
  {"text": "À la rencontre arrangée", "size": 146, "y": 170, "red": []},
  {"text": "Ma mère m'en a inscrit sept", "size": 96, "y": 312, "red": ["sept"]},
  {"text": "Rencontrer la famille, voir grand-mère", "size": 64, "y": 1196, "red": []},
  {"text": "À 87 ans, elle ne me presse pas pour des enfants", "size": 64, "y": 1280, "red": ["des enfants"]}
]}
"$python_bin" "$skill_dir/scripts/make_cover.py" project_ep2

Les règles de mise en page sont dans [references/cover-design.md]. La couverture doit être vérifiée visuellement avant livraison.

8. Contenus pour publication WeChat Channels

D'abord, rassemblez les éléments du script, puis rédigez les textes :

"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2

Le script affiche le script complet, les mots rouges, les mots fréquents et les trois dernières phrases. Utilisez ces informations pour rédiger :

  • 3 variantes de titre, avec un accroche emoji. Idéalement ≤ 22 caractères chacune (peut être dépassé, limite stricte de 100 caractères).
  • 1 version de description finale, 2–3 lignes. La première ligne est une accroche. Les hashtags (#sujet) sont intégrés dans le texte principal.
  • 5 à 8 hashtags. Ils doivent tous apparaître dans la description (le script vérifiera).
  • 1 commentaire épinglé, qui apporte un complément d'information ou une auto-dérision.

Ensuite, exécutez :

"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2 \
  --titles "Titre un" "Titre deux" "Titre trois" \
  --desc "Texte de la description #sujet1 #sujet2" \
  --tags "sujet1" "sujet2" \
  --comment "Commentaire épinglé"

Les détails des règles sont dans [references/publish-channels.md]. Les fichiers produits sont publish.md et publish.json.

Contraintes strictes

  • Toile : 1080×1440 (3:4), 30fps, fond blanc pur, contour noir de 4–6px, grosse tête ronde et corps fin.
  • Sujet principal centré sur y=400–1050, espace blanc en haut ; les sous-titres commencent à y=1084, taille de police minimale 54.
  • Police des sous-titres : Xingkai (cursive). Texte blanc avec ombre portée foncée et douce. Mots-clés des gags en rouge.
  • Sous-titres : une ligne ≤ 16 caractères. Le moteur de rendu ne peut pas afficher de lignes plus longues.
  • Ne pas graver le texte dans l'image. Les sous-titres sont rendus sur une couche séparée.
  • La couverture doit utiliser la même police et les mêmes traits que la vidéo. Changement de style interdit.
  • Conservez les vidéos finales déjà livrées. Pour les modifications, utilisez un nouveau répertoire de projet, ne remplacez pas les épisodes déjà livrés.

Gestion des échecs

  • TTS renvoie constamment 429 : le script réessaie avec un intervalle fixe 40 fois. Si cela échoue encore, réduisez la vitesse à 1.4 et relancez, ou exécutez par lots (--limit N pour reprendre, le cache ignore les phrases déjà synthétisées).
  • prepare.py signale une incohérence ASR : cela signifie que asr.json ne correspond pas au script. Cela se produit généralement après une modification du script sans refaire le doublage. Relancez build_voice.py. N'utilisez pas --allow-asr-mismatch pour passer outre.
  • render.py signale un sous-titre trop long : une légende dépasse 16 caractères. Retournez dans build_segments.py pour modifier les règles de découpe.
  • check_overlap.py retourne un code non nul : corrigez les coordonnées plan par plan selon les identifiants signalés, jusqu'à ce que le code de sortie soit 0.
  • N'affirmez pas que l'audition est réussie sans avoir écouté la piste en entier ; ne dites pas avoir visionné une vidéo en entier sans l'avoir fait. Les enregistrements de livraison doivent uniquement mentionner les vérifications réellement effectuées.

Références

Notes pour Windows (win32)

Opérations équivalentes sous Windows :

  • Environnement virtuel : py -3 -m venv .venv, puis utilisez .venv\Scripts\python.exe à la place de $python_bin.
  • Dépendances : .venv\Scripts\pip.exe install -r "<skill_dir>\scripts\requirements.txt".
  • ffmpeg/ffprobe : installez-les directement dans le PATH (winget install Gyan.FFmpeg). Pas besoin d'ajouter /opt/homebrew/bin ; cependant, les chemins ffmpeg dans scripts/deliver.py, scripts/make_preview.py, scripts/verify.py sont codés en dur pour macOS. Remplacez-les par ffmpeg / ffprobe pour une compatibilité multiplateforme.
  • scripts/build_voice.py dépend de mcode-tools dans le PATH et de curl ; Windows 10 1803+ intègre curl. S'il manque, utilisez Invoke-WebRequest -OutFile <chemin> <url> à la place.
  • Séparateurs de chemins : tous les scripts utilisent pathlib pour la gestion. Lors du passage de paramètres, entourez les chemins de guillemets.

Skills associés