Communitygithub.com

geoqiao/short-video-skills

Créez des vidéos courtes avec voix off à l'aide de code, sans modèle de génération vidéo. Idéal pour les graphiques, le texte, le code et les données, comme les tutoriels, les démos de produits et l'analyse de données.

Qu'est-ce que short-video-skills ?

Ce skill permet de créer des vidéos courtes avec voix off en utilisant uniquement du code, éliminant le besoin de modèles de génération vidéo. Il est parfait pour les contenus basés sur des graphiques, du texte, du code et des données, tels que les explications de concepts, les tutoriels logiciels, les présentations de fonctionnalités de produits, l'analyse de données et les listes. Le principe est simple : un canvas dessine chaque image en fonction du temps, edge-tts génère la voix off et aligne le rythme visuel sur les mots, Playwright pilote Chrome pour capturer chaque image, et ffmpeg assemble le tout en vidéo. Le skill génère également trois formats de couverture (16:9, 4:3, 3:4) et une fiche de contact. Il est conçu pour créer un nouveau projet vidéo, ajouter un épisode, modifier la voix off ou les visuels, et exporter des images fixes pour vérifier les débordements. Il est pris en charge par Claude Code, Cursor et d'autres agents, et nécessite Node 20+, uv, ffmpeg et Google Chrome. La documentation complète (SKILL.md) décrit la structure du projet, le déroulement d'un épisode, la rédaction du script, la conception des visuels et le processus de rendu.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/geoqiao/short-video-skills/tree/HEAD/skills/code-video

Demander à votre IA préférée

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

Documentation

Créer des vidéos courtes avec du code

L'image est uniquement déterminée par le temps : la page expose window.render(t), on lui donne un nombre de secondes et elle dessine l'image de cet instant. Le script de rendu utilise un Chrome sans tête pour l'appeler image par image et faire des captures d'écran, puis ffmpeg assemble les captures et la voix off en mp4. Modifier l'image revient à modifier le code, il suffit de relancer le rendu.

Cette approche provient d'un article de xilo sur X (2026-09-29, https://x.com/xilo2991/status/2104912748794589515). Ce skill ajoute l'alignement de la voix off, les couvertures, la vérification des images fixes et un ensemble de règles pour écrire des scripts et dessiner les images.

Pour commencer

Nécessite Node 20+, uv, ffmpeg et Google Chrome installé localement. La police par défaut est Songti, PingFang et SF Mono de macOS ; sur d'autres systèmes, remplacez-les dans brand.json sous fonts par des polices disponibles localement.

  1. Copiez tout le dossier template/ de ce skill dans un nouveau répertoire de projet.
  2. Dans le nouveau répertoire, exécutez npm install (installe seulement playwright-core).
  3. Modifiez brand.json : series est le nom de la série en haut à gauche de la couverture, handle est le nom pour la couverture et le générique, avatar est le chemin relatif de l'image d'avatar (peut être null), colors et fonts sont les couleurs et polices.
  4. Exécutez l'exemple :
uv run tools/voice.py demo                # Voix off, musique, timeline -> episodes/01-demo/build/
node tools/render.mjs demo --stills auto  # Image fixe à la fin de chaque plan
node tools/render.mjs demo                # Rendu complet -> episodes/01-demo/out/video.mp4 et cover.png
sh tools/covers.sh demo                   # Couvertures 4:3 et 3:4
sh tools/sheet.sh demo                    # Couverture + dernière image de chaque plan -> build/sheet.png

Dans les commandes, on utilise uniquement le slug ; le script trouve lui-même episodes/<numéro>-<slug>/. La voix off envoie le texte du commentaire au service en ligne TTS de Microsoft.

Structure du projet

  • brand.json : Marque. Modifiez ici, pas dans le moteur.
  • src/lib.js : Outils de dessin, attachés à window.E.
  • src/run.js : Planification de la timeline. L'image 0 est la couverture, elle reste 0,3 seconde avant de glisser vers le premier plan ; les plans sont disposés horizontalement, reliés par des glissements ; les sous-titres et la barre de progression sont également dessinés ici.
  • src/stage.html : Page de rendu.
  • tools/voice.py : Synthèse ligne par ligne de la voix off, utilise les timestamps mot par mot pour déterminer le début de chaque phrase, ajoute de la musique de fond et des bips sonores, normalise le volume à -14 LUFS. En cas d'échec de synthèse, réessaie ; après trois échecs, signale une erreur.
  • tools/render.mjs : Quatre pages en parallèle pour capturer les images, encodage ffmpeg, 30 images par seconde.
  • tools/covers.sh, tools/cover-vertical.mjs : Couverture horizontale 4:3 (couverture 16:9 avec fond de couleur étendu) et couverture verticale 3:4 avec mise en page séparée.
  • tools/sheet.sh : Extrait la couverture et la dernière image de chaque plan de la vidéo finale pour créer une fiche de contact.
  • episodes/<numéro>-<slug>/ : Un répertoire par épisode, contenant script.json, shots.js, et les dossiers générés build/ et out/.

Déroulement d'un épisode

Suivez les étapes dans l'ordre ; ne passez pas à l'étape suivante si la précédente n'est pas terminée.

Le contenu et les faits sont de votre responsabilité ; ce skill commence à partir de la rédaction du script.

  1. Script : Créez episodes/<numéro>-<slug>/, écrivez script.json, et écrivez le numéro dans cover.no.
  2. Visuels : Écrivez shots.js dans le même répertoire ; le nombre de plans doit correspondre au nombre de lignes de commentaire.
  3. Voix off : uv run tools/voice.py <slug>. Relancez si vous modifiez le commentaire, la voix ou le texte de la couverture.
  4. Vérification des images fixes : Voir la section "Vérification des images fixes" ci-dessous.
  5. Vidéo finale : node tools/render.mjs <slug>, puis exécutez covers.sh et sheet.sh, et vérifiez la fiche de contact.
  6. Livraison : Voir la dernière section de ce document.

Lorsque vous ajustez le numéro d'épisode, modifiez à la fois le préfixe du nom du répertoire et cover.no, puis relancez la voix off et le rendu. Si vous modifiez uniquement le texte de la couverture, pas besoin de relancer la voix off : modifiez cover dans script.json, remplacez cover dans build/timeline.js par le même contenu, puis relancez le rendu et covers.sh.

script.json

{
 "title": "Cette vidéo est dessinée par du code",
 "cover": { "no": "01", "lines": ["Cette vidéo", "est dessinée par du code"], "hot": 1, "tag": "Pas de logiciel de montage, ni de modèle vidéo" },
 "voice": "zh-CN-YunxiNeural",
 "rate": "+6%",
 "lines": [["Chaque image que vous voyez, ", "est dessinée par du code."], ["La page n'expose qu'une fonction : ", "donnez-lui un temps, ", "elle dessine l'image de cet instant."]]
}
  • Une ligne est un plan, chaque segment à l'intérieur d'une ligne est un rythme visuel. Les segments peuvent être écrits comme [texte parlé, texte des sous-titres] : parlez "soixante-quinze" mais affichez "75%" ; utilisez également cette méthode pour corriger la prononciation de termes anglais difficiles.
  • Couverture : lines deux lignes maximum, hot est la ligne qui utilise la couleur principale, tag est un crochet avec un nombre ou une conclusion spécifique, no est un numéro d'épisode à deux chiffres. Le titre de la couverture, le titre de la plateforme et la première phrase du commentaire disent la même chose.

Comment écrire le script

  • Pour les vidéos courtes vues verticalement sur mobile, une durée de 75 à 90 secondes avec 8 à 9 plans est appropriée. Avec un débit vocal de +6%, environ 4,8 caractères par seconde (y compris les pauses), le commentaire fait environ 380 à 430 caractères (caractères chinois plus mots anglais). Si le script dépasse, supprimez d'abord des caractères, puis faites la voix off.
  • Les deux premières secondes doivent contenir l'élément le plus accrocheur de l'épisode. Avant d'écrire le script, demandez-vous : quel est l'élément vraiment captivant de cet épisode ? C'est généralement un nombre contre-intuitif, un résultat concret ou un problème que rencontre le public. Dans le modèle, le commentaire commence après 0,5 seconde (HEAD dans tools/voice.py), donc à 2 secondes, on ne peut dire que 8 à 9 caractères. Le premier segment doit donc être court, et les premiers mots doivent être cet élément ; le premier plan doit l'afficher en gros caractères avant 1,2 seconde ; le tag de la couverture doit également dire la même chose. Utilisez les propres termes du public pour cet élément, avec des mots-clés thématiques ("Ne poussez pas l'intensité de raisonnement à fond", puis "De High à Max, coût 2,9 fois, score seulement 0,6 de plus"), puis entrez dans le vif du sujet. Pas de préambule, pas de présentation personnelle, pas de "Aujourd'hui, on va parler de", pas de "Qu'est-ce que X ?" seul, ni de "Le même A, le même B" comme introduction vide. Ceci est basé sur l'expérience de quelques vidéos, à considérer comme à vérifier.
  • Les ordres suivants peuvent servir de point de départ, adaptez-les au contenu.
  • Tutoriel : Résultat final → Une étape par plan → Pièges courants → Une phrase pour conclure.
  • Présentation de produit : Le problème qu'il résout → Deux ou trois fonctions principales, une fonction par plan → Comment commencer → Une phrase pour conclure.
  • Explication de concept : Conclusion et chiffres → Ancienne méthode ou idée fausse courante → Problème → Nouvelle méthode → Mécanisme spécifique → Données de test ou officielles → Une phrase pour conclure.
  • Résultat de recherche : Conclusion et chiffres → Idée reçue courante → Comment l'expérience a été menée → Résultats → Recherches ultérieures → Raison → Une phrase pour conclure.
  • Pour la conclusion, d'abord résumez la conclusion ou donnez une manière de faire, puis posez une question à laquelle le public peut répondre par sa propre expérience ("Quel réglage utilises-tu d'habitude ?"), pour générer des commentaires. La question doit faire écho au commentaire épinglé. Cette règle est également à vérifier en fonction de l'évolution du nombre de commentaires. Ne faites pas de plan séparé pour les limites ; les conditions des données sont écrites dans la note de bas de page du plan de données.
  • Ne dites pas "Dans le prochain épisode", "Dans l'épisode précédent" ; l'ordre de publication peut être modifié. Pour faire référence à un autre épisode, dites "L'épisode sur X".
  • Lorsque la source donne une marge d'erreur, une différence dans la marge est décrite comme "presque inchangée". Les chiffres dérivés par vous-même doivent être mentionnés comme preuve faible lors de la livraison.
  • N'utilisez pas d'URL dans le commentaire oral, ne dites pas "Allez voir sur X", "Cherchez Y" (la plateforme considère cela comme une redirection externe, voir le skill video-publish).

Comment dessiner les visuels

shots.js est une fonction immédiatement exécutée qui se termine par window.SHOTS = [...]. Chaque plan est (c, k) => {} :

  • c est le contexte 2D du Canvas en 1920×1080.
  • k.at(i, delay, dur) retourne la progression ease-out de 0 à 1 pour le segment i, commençant après delay secondes et durant dur secondes ; k.raw est la progression linéaire équivalente ; k.t est le temps écoulé depuis le début du plan, k.d est la durée de cette ligne de commentaire, k.segs sont les secondes de chaque segment par rapport au début du plan.
  • Les outils de dessin sont dans window.E : title (titre du plan avec trait de marque), txt, measure, rise (fondu avec déplacement), pop (apparition), rrect, path (ligne brisée selon la progression), arrow, chip (bloc d'étiquette), code (bloc de code machine à écrire), stroke (trait de marque), mark (avatar), sign (générique de fin), fmt, couleurs C, polices F. Lisez d'abord les signatures des fonctions dans src/lib.js avant de les utiliser. Les outils manquants sont écrits dans le shots.js de l'épisode concerné ; ne modifiez pas lib.js et run.js pour un seul plan.

Règles :

  • Chaque segment correspond à un nouvel élément visuel ; il doit y avoir un changement toutes les 2 à 4 secondes. Un plan ne traite qu'un seul sujet, illustré graphiquement : flèches de processus, matrice de points, barres de comparaison, blocs de code, tableaux, pas de texte plein écran.
  • Alignez à gauche, asymétrique. Évitez les arrière-plans foncés avec grands caractères centrés, ne faites pas apparaître tous les éléments en même temps, pas d'effet lumineux.
  • La couleur d'accentuation principale marque "le nombre à regarder sur cet écran", ne représente pas le bien ou le mal ; la couleur d'accentuation secondaire est utilisée au maximum une ou deux fois par écran.
  • Déterminez la taille de la police en fonction de l'affichage vertical du téléphone pour un écran horizontal : txt relève les tailles inférieures à 56 (24px dessinés en 34px, 30 dessinés en 38px), la valeur transmise pour les informations portées ne doit pas être inférieure à 30, les notes de bas de page de source peuvent être 24. La largeur estimée est calculée en fonction de la taille relevée ; chaque caractère d'une police à chasse fixe représente environ 0,6 fois la taille de la police.
  • Limites de mise en page : la barre de sous-titres est en dessous de y 932, une ligne contient environ 30 caractères pleine largeur ; la phrase d'accroche de la couverture touche l'avatar à environ 14 caractères pleine largeur ; le plan a un léger zoom avant de 1,025x, les éléments au bord doivent avoir une marge de 20px ou plus ; une note de bas de page de 24px contient environ 48 caractères pleine largeur par ligne.
  • La police Songti Black n'a pas de "÷", le "×" sera dessiné comme une grande croix : utilisez PingFang pour les opérateurs, ou écrivez "divisé par" ou "fois". Dans un grand titre de 200px, les lettres anglaises descendantes peuvent écraser la ligne suivante.
  • Lorsque le premier segment est très court, le début du plan peut être vide : placez la structure du graphique (axes, en-têtes de tableau, contours) dans le premier segment, et les données apparaissent avec les segments suivants.
  • Les icônes qui ne sont pas des données réelles sont marquées "schéma". Les nombres lus à partir de graphiques de la source originale sont marqués en note de bas de page "lu à partir du graphique original". En bas du plan de données, écrivez la source (uniquement le nom, "Source : Documentation officielle de X"), pas de nom de domaine ni d'URL.
  • Chaque plan utilise E.title pour le titre ; le dernier plan utilise E.sign pour le générique.

Vérification des images fixes

node tools/render.mjs <slug> --stills auto produit la dernière image de chaque plan ; --stills 0,t1,t2,… produit des images à des secondes spécifiques (0 est la couverture). Les images intermédiaires sont prises environ 0,4 seconde après le début de chaque ligne et environ 1 seconde après chaque segment ; les points temporels sont lus dans build/timeline.js de l'épisode. Chaque exécution de --stills efface le lot précédent, donc examinez par lots ou combinez les points temporels dans une seule commande. Lorsque le nombre d'images est élevé, utilisez ffmpeg pour les assembler en une fiche de contact ; examinez la couverture et la dernière image en taille réelle.

Vérifiez une par une :

  • Le texte dépasse-t-il des cartes, blocs de code, colonnes de tableau, ou est-il masqué par la barre de sous-titres et la barre de progression ?
  • Les nombres alignés à droite et les étiquettes de gauche se touchent-ils ? Les étiquettes d'axe et les étiquettes de courbe se chevauchent-elles ?
  • La dernière image du plan est-elle la plus complète en termes d'informations ? Y a-t-il des éléments qui ne sont pas encore entrés ?
  • Les deux lignes de titre de la couverture sont-elles trop petites ? La phrase d'accroche est-elle trop large ?
  • Y a-t-il des images vides de 2 à 3 secondes sans rien de nouveau, surtout au début du plan ?

Si vous trouvez un problème, corrigez-le ; ne produisez pas de vidéo finale avec des débordements connus. Si vous modifiez uniquement les visuels, relancez simplement le rendu.

Limitations connues

  • edge-tts utilise l'interface non officielle de Microsoft. La version 7.2.8 retourne 403 depuis octobre 2026 (rany2/edge-tts #490) ; tools/voice.py est fixé sur le commit de la PR de correction #491 ; après la sortie d'une nouvelle version officielle, remplacez par edge-tts==<nouvelle_version>. Si 403 réapparaît, consultez d'abord le dépôt upstream pour les issues.
  • L'agent n'entend pas la voix off : la prononciation et le débit des termes anglais doivent être vérifiés par une personne. Les interruptions de flux pendant la synthèse sont gérées par la vérification de durée dans voice.py.
  • Pas de flou de mouvement, ni de montage sur le rythme musical.

Ce qu'il faut mentionner lors de la livraison

  • La voix off n'a pas été écoutée par une personne.
  • Le résultat de la vérification des images fixes, y compris les problèmes connus encore présents.
  • Le chemin de la vidéo finale, des trois couvertures et de la fiche de contact, ainsi que la durée.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Skills associés