Générateur de vidéos courtes TikTok / Douyin
Vous (l'agent) faites le travail créatif — script, découpage en scènes, mots-clés de recherche, choix de style et révision qualité. Les scripts dans scripts/ font le travail mécanique — TTS avec timestamps mot par mot, recherche et téléchargement d'assets, rendu des sous-titres, composition ffmpeg, normalisation du volume sonore.
Tout fonctionne avec ffmpeg seul (pas besoin de libass/drawtext) et un environnement Python virtuel. Fonctionne sans aucune clé API ; les variables d'environnement PEXELS_API_KEY / PIXABAY_API_KEY débloquent de vraies séquences vidéo libres de droits (meilleur résultat) lorsqu'elles sont présentes.
Workflow
0. Configuration unique (à sauter si .venv/ et assets/fonts/ existent)
bash scripts/setup.sh
1. VÉRIFIEZ D'ABORD LES FAITS, puis rédigez le script + storyboard
Vos connaissances internes peuvent être obsolètes ou erronées — ne mettez jamais d'affirmation non vérifiée dans une vidéo. Avant d'écrire le texte d'une scène, utilisez votre outil de recherche web pour vérifier toute affirmation concrète : nombres, statistiques, records, prix, dates, classements, et toute déclaration du type "premier / plus grand / seul / le plus rapide" — ainsi que tout sujet sensible au temps (actualités, produits, versions, "今年/最新"), quel que soit votre niveau de confiance. Règles :
- Une affirmation n'entre dans le script que si une source la mentionne — adaptez votre formulation à la source, pas l'inverse.
- Impossible de vérifier ? Remplacez-la par une affirmation vérifiable, ou supprimez-la. Un chiffre erroné dans une vidéo publiée est pire qu'un accroche plus faible.
- Enregistrez les URL que vous avez utilisées dans le champ
"sources": [...]du storyboard — elles sont reprises dansreview/report.txtpour que l'utilisateur puisse auditer la vidéo. - Si vous n'avez vraiment pas accès au web, contentez-vous de faits de base bien établis, évitez les chiffres précis, et prévenez l'utilisateur que la vidéo n'est pas vérifiée.
Lisez references/writing-guide.md pour les formules de script (types d'accroche, rythme, structure des scènes). Créez ensuite projects/<slug>/storyboard.json :
{
"title": "深海里最诡异的5种生物",
"lang": "zh",
"aspect": "9:16",
"voice": "zh-CN-YunjianNeural",
"rate": "+10%",
"caption_style": "karaoke",
"bgm": {"mood": "mystery", "gain_db": -16},
"hook": {"text": "深海禁区", "seconds": 2.3},
"scenes": [
{
"text": "你知道吗?在阳光永远照不到的深海,藏着比科幻电影更诡异的生物。",
"keywords": ["deep sea NOAA ocean exploration", "submarine dark ocean"],
"providers": ["openverse", "wikimedia"],
"badge": null,
"effect": "kb_in"
},
{
"text": "第一名,鮟鱇鱼……",
"keywords": ["humpback anglerfish", "anglerfish museum"],
"badge": "第1名"
}
]
}
Référence des champs :
| champ | valeurs | notes |
|---|---|---|
lang | zh | en | définit le groupement des légendes + la voix par défaut |
aspect | 9:16 (défaut) | 16:9 | 1:1 | |
voice | n'importe quelle voix edge-tts | zh : zh-CN-YunjianNeural(voix masculine charismatique) zh-CN-XiaoxiaoNeural(voix féminine) zh-CN-YunxiNeural(voix masculine enjouée) ; en : en-US-ChristopherNeural en-US-AriaNeural en-US-GuyNeural |
rate | ex. +10% | rythme marketing : zh +8%+15%, en +5%+10% |
caption_style | karaoke | pop | none | karaoke = surlignage mot par mot (recommandé) |
bgm | {"mood": ...} | {"query": "mots de style"} | {"file": "chemin.mp3"} | {"mood":"none"} | Par défaut, utilisez une mood : la table organisée (upbeat funny inspiring chill tech mystery epic sad horror) reprend les grands classiques MacLeod utilisés par d'innombrables chaînes 营销号 — éprouvés, sûrs, variés par projet. Utilisez query uniquement quand aucune mood ne correspond au style du contenu (ou si l'utilisateur nomme un genre) : cela recherche de la musique libre (balises de style ccMixter + Openverse/Jamendo ; ND/NC exclus) et chaque candidat est filtré par le détecteur de rythme — pas de groove entre 75 et 175 BPM, pas de sélection. Mots de style qui correspondent à des balises : trap/phonk, hip hop, lofi/chill, edm/dance, epic/cinematic, quirky. Vous pouvez définir les deux — la query est essayée en premier, la mood est le fallback. file = votre propre piste |
bgm.vibe | "spedup" | "slowed" | non défini | Son signature Douyin : spedup ≈ 1,25× avec hauteur augmentée (traitement courant pour les vidéos de type "top/liste"), slowed = ralenti + réverb (ambiance/émotion). Appliqué à toute source de bgm, y compris file ; la grille de rythme est ré-analysée après traitement pour que le calage reste précis |
beat_sync | true (défaut) | false | la BGM est analysée en rythme et chaque scène/coupe se cale sur la grille de rythme (卡点) quand celle-ci est fiable ; la VO n'est jamais tronquée, seuls les espaces de respiration sont ajustés |
hook | {"text","seconds"} | grande carte titre au début, ≤ 8 caractères/mots |
sticky_title | {"text": ...} | barre de sujet persistante optionnelle en haut ; désactivée par défaut — ne l'ajoutez que si l'utilisateur le demande |
sfx | true (défaut) | false | son de souffle (whoosh) lors des transitions de scène |
scene keywords | liste de mots-clés concrets, en anglais | chaque entrée = un plan (visuel) ; la vidéo passe à un nouveau visuel toutes les ~3s, donc donnez 2 à 3 mots-clés pour les scènes de plus de ~4s (des plans supplémentaires sont ajoutés automatiquement en cyclant vos mots-clés si vous en donnez moins) |
scene badge | ex. "第1名" / "TOP 1" | grande étiquette imprimée affichée au début de la scène — à utiliser pour les listes |
scene providers | liste | Images sans clé : openverse wikimedia nasa ; vidéo réelle sans clé : wikimedia_video (clips Commons, transcodage serveur) nasa_video (images spatiales/scientifiques domaine public) archive_video (films historiques Prelinger domaine public) ; avec clés : pexels_video pexels_photo pixabay_video |
scene effect | auto kb_in kb_out pan_left pan_right static | mouvement Ken Burns du premier plan ; les plans suivants défilent automatiquement |
scene emphasis | liste de sous-chaînes | mots surlignés en permanence (style pop) |
scene media | chemin de fichier | ignorer la recherche, utiliser votre propre fichier (par exemple un fichier que vous avez téléchargé vous-même) |
Règles générales (seuil de publication) : total 45–75s, 6–9 scènes, une idée par scène, 2–3 plans par scène. Texte de scène 20–45 caractères chinois / 14–30 mots anglais. Tout ce qui est en dessous de ~40s ou avec des scènes à plan unique donnera une impression de vide — ne publiez pas.
2. Exécutez le pipeline
.venv/bin/python scripts/pipeline.py projects/<slug>
Ou étape par étape : tts.py → assets.py → bgm.py → compose.py → check.py.
3. RÉVISION — c'est ce qui fait la différence (obligatoire)
La recherche d'images gratuites est imparfaite. Consultez toujours ces deux fichiers avec votre outil d'image et jugez-les comme un éditeur humain :
-
projects/<slug>/media/assets_sheet.jpg— après l'étape des assets. Les plans sont étiquetés01a 01b 02a …. Pour tout plan qui ne correspond pas clairement à la narration, récupérez-le à nouveau :.venv/bin/python scripts/assets.py projects/<slug> --scene 3 --shot 2 --keywords "meilleurs noms anglais concrets"(La récupération met automatiquement en liste noire l'asset rejeté. Répétez jusqu'à ce que toutes les scènes correspondent. Vous pouvez aussi télécharger une image vous-même avec vos propres outils et définir
mediade la scène sur ce fichier.)Le pipeline vérifie également le texte du titre source de chaque plan par rapport à sa requête et imprime des indicateurs
[!] HORS-SUJET. Si vous avez visuellement confirmé qu'un plan signalé est en fait correct (par exemple une photo parfaite mais sans titre), définissez"approved": truesur ce plan dansmedia/manifest.jsonpour le valider — votre œil prime sur la vérification textuelle. N'approuvez jamais en aveugle. -
projects/<slug>/review/contact_sheet.jpg— après compose+check. Vérifiez : légendes lisibles et synchronisées, absence d'images erronées/laides, accroche visible. Corrigez les problèmes (éditez le storyboard → relancez compose, c'est rapide) jusqu'à ce que la vidéo ressemble à ce qu'un éditeur 营销号 publierait réellement.
review/report.txt contient les vérifications de durée/volume sonore et un bloc d'attribution prêt à coller (sources CC-BY + crédit musical) — fournissez-le toujours à l'utilisateur avec final.mp4.
Conseils de recherche d'assets (levier de qualité le plus important)
- Les mots-clés doivent être en anglais, de 1 à 4 mots, noms concrets visibles ("humpback anglerfish", "scuba diver silhouette"), jamais des concepts abstraits ("mystery", "success").
wikimediaest le meilleur pour les animaux/sciences/histoire/lieux ;openverse(Flickr etc.) pour le style de vie/paysages/ambiance ;nasapour l'espace ; les clés débloquentpexels_video/pixabay_videopour des séquences réelles — privilégiez-les quand elles sont disponibles.- Ajoutez un mot de contexte pour lever l'ambiguïté : "NOAA", "museum", "aquarium", "macro".
- Si une scène échoue systématiquement, changez le concept visuel, pas seulement les mots (par exemple pour "5% exploré" montrez un plongeur en silhouette, pas des "statistiques").
- Les recherches
wikimedia_videoacceptent les termes négatifs — les requêtes météo/espace de Commons sont noyées dans les boucles satellites, écrivez donc par exemple"tempête éclair -CIRA -satellite -JPSS". Les mots non anglais débloquent des séquences supplémentaires ("Blitz Gewitter", "tormenta rayos"). Préférez les sujets nommés ("Fagradalsfjall lave drone") aux noms génériques, et examinez toujours les vignettes vidéo dans le planche : méfiez-vous des légendes incrustées, des filigranes, des tutoriels et des promotions CGI.
Dépannage
- Erreurs réseau
edge-tts: il réessaie 4 fois ; relanceztts.pysi cela échoue encore. - Échec du téléchargement de la BGM : relancez
bgm.py(réessais + cache), ou utilisez--mood none, ou déposez un mp3 dansassets/bgm/et définissezbgm.file. - Le style de la BGM ne convient pas : affinez la requête (
bgm.py <dir> --query "..."puis recomposez avec--skip-tts --skip-assets). Pour un son véritablement tendance du moment, livrez avecmood: none(ou gain faible) et dites à l'utilisateur d'ajouter le morceau viral de la bibliothèque musicale sous licence intégrée à l'application TikTok/Douyin au moment du téléchargement — c'est à la fois légal et favorisé par l'algorithme. Le calage temporel restera correct car le rythme des scènes est inchangé. check.pyimprime une ligne "les coupes tombent sur le rythme" — si la synchronisation sur le rythme a été ignorée (faible confiance dans la grille, par exemple musique ambiante sans rythme), choisissez un morceau plus stable (--query "trap beat"etc.) et recomposez.- Une source qui produit une erreur ou est vide n'est pas un problème — d'autres la couvrent ; vérifiez les logs par scène.
- Recomposition après modification du storyboard : rapide (
--skip-tts --skip-assetsvia pipeline.py, ou exécutez compose.py directement). Changer le texte d'une scène nécessite de relancertts.py. - Les émojis dans les légendes s'affichent sur macOS (Apple Color Emoji) ; sur Linux, ils sont supprimés sauf si NotoColorEmoji est installé. Ne comptez jamais sur les émojis pour le sens.
Livraison
Fournissez à l'utilisateur : final.mp4, le bloc d'attribution de review/report.txt, et (si demandé) review/cover.jpg comme image de couverture.