Communitygithub.com

Shorts Video Studio

Créez des vidéos verticales professionnelles (9:16) pour YouTube Shorts / Reels / TikTok, entièrement en Python, avec script recherché, voix off synthétique, animations graphiques avancées et vérification qualité visuelle.

Qu'est-ce que Shorts Video Studio ?

Shorts Video Studio est un outil puissant pour la génération procédurale de vidéos courtes au format vertical (1080x1920), destiné aux créateurs de contenu, développeurs et utilisateurs d'agents IA. Il automatise entièrement la production d'une vidéo de 30 à 60 secondes à partir d'un script, incluant la recherche de faits, la génération de voix off via ElevenLabs, la synchronisation mot-à-mot, des animations graphiques multi-polices et multi-palettes, des icônes emoji colorées, et huit types de transitions différents. Le pipeline s'exécute en Python avec OpenCV, PIL et ffmpeg, et intègre des règles de variété strictes pour éviter l'aspect « généré par IA ». Un système de contrôle qualité (QA gate) vérifie automatiquement la conformité audio (loudness LUFS, crête), le respect des règles de variété, l'exactitude des faits, et la synchronisation des animations. L'outil prend en charge les scripts en anglais, hindi et hinglish, et génère également des sous-titres SRT et un rapport de qualité.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mohdkhatab/shorts-video-studio/tree/HEAD/skills/shorts-video-studio

Demander à votre IA préférée

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

Documentation

Que fait Shorts Video Studio ?

Produit une vidéo MP4 30-60 s, 1080x1920 + SRT + script. Tout est procédural (Python + OpenCV + PIL + ffmpeg), piloté par un moteur d'animation basé sur des repères temporels (cues) pour que les visuels correspondent exactement au mot prononcé.

Fichiers de cette compétence

  • scripts/shorts_engine_template.py - moteur de référence fonctionnel (9 scènes, 9 arrière-plans, 8 transitions, audio, synchronisation vocale). Copiez-le et modifiez-le ; ne le réécrivez pas de zéro.
  • scripts/tts_elevenlabs.py - génère la voix off via l'API REST (nécessite ELEVENLABS_API_KEY). Utilisez d'abord --check et --list-voices.
  • scripts/review_frames.py - planche contact + preuve QA : durée, codec, résolution, LUFS intégré, plage de loudness, crête réelle. Quitte avec un code non nul en cas d'échec.
  • scripts/setup.sh - crée .venv, installe les dépendances, vérifie ffmpeg et les polices. Exécutez ensuite source .venv/bin/activate.
  • assets/fonts/ - 15 fichiers de police OFL-1.1 / 12 familles + Noto Color Emoji (icônes réelles). Licences incluses, indexées dans assets/fonts/LICENSES.md.
  • references/design-bible.md - palettes, polices, vocabulaire des icônes, arrière-plans, transitions, effets, grille de mise en page. Lisez avant de concevoir les scènes.
  • references/script-and-voice.md - modèle de script, règles Hinglish, règles de vérification des faits, voix et détails d'alignement. Lisez avant d'écrire le script.

Pipeline (effectuez les étapes dans l'ordre)

  1. Recherche - si le sujet est d'actualité/ tendance, effectuez une recherche web sur 3+ sources, collectez les faits avec dates et chiffres ("en date du "). N'inventez jamais de chiffres. Signalez les affirmations que vous n'avez pas pu vérifier et adoucissez le libellé ("selon les rapports").
  2. Script - 120-140 mots pour ~45-50 s, accroche dans les 2,5 premières secondes, 7-9 courtes séquences, CTA à la fin. Voir script-and-voice.md. Sauvegardez sous script.txt (un paragraphe par scène).
  3. Plan des scènes - une scène par paragraphe. Pour chaque scène, décidez : style d'arrière-plan, palette, 2 polices, icônes (emoji), animation vedette, mots repères, transition vers la suivante. Appliquez les RÈGLES DE VARIÉTÉ ci-dessous. Écrivez le plan dans plan.md.
  4. Voix - générez UNE prise de voix off pour l'ensemble du script (tts_elevenlabs.py ou le MCP ElevenLabs). Sauvegardez sous voice.mp3. Si vous ne pouvez pas télécharger l'audio (sandbox), demandez à l'utilisateur de télécharger le fichier ; en attendant, construisez avec une durée estimée.
  5. Construction - copiez le modèle dans video.py, remplacez le texte des SCÈNES, écrivez les fonctions bgN/dN, définissez HIT et TRANS. Utilisez les recherches par repère C(scene_idx, "motparlé", occurrence, secondes_par_défaut) pour chaque début d'animation.
  6. Rendu TEST - TEST=1 python video.py écrit des PNG (état final, état intermédiaire et une image par transition). Exécutez review_frames.py / regardez-les. Corrigez tout ce que la passerelle QA signale.
  7. Rendu final - VOICE=voice.mp3 python video.py. Lancez-le en arrière-plan (setsid nohup ... &) et surveillez le journal ; les appels au premier plan peuvent être interrompus par les timeouts de l'outil. Environ 1,5 à 3 min par 50 s sur un seul CPU. Le mixage est normalisé en loudness à LUFS (par défaut -16) automatiquement.
  8. Passerelle QA (ci-dessous) sur le mp4 final, puis livrez video.mp4, captions.srt, script.txt, plan.md, qa_report.md.

RÈGLES DE VARIÉTÉ (ce qui rend la vidéo humaine, pas générée par IA)

La violation de l'une de ces règles entraîne un ÉCHEC à la passerelle QA.

  • Chaque scène a sa propre technique d'arrière-plan et sa propre palette (rayons, grille synthwave, soleil en demi-teintes, pluie de code, dégradé + blobs, grille de plan, rayures de danger, anneaux radar, confettis...). Jamais deux voisines identiques. Jamais une couleur globale.
  • >= 7 polices différentes dans la vidéo, en mélangeant les catégories : condensé impact, gras display, large display, grotesque, serif, italic serif, monospace, pixel, écriture. Maximum 2-3 polices par scène.
  • >= 5 traitements de texte différents : remplissage dégradé, contour épais + ombre portée dure, lueur, rebond lettre par lettre, machine à écrire, pastille autocollante/pill, tampon pivoté, inclinaison manuscrite.
  • Icônes réelles, pas de formes géométriques : emoji couleur (Noto Color Emoji) comme icônes, animées (apparition avec dépassement, rotation à l'entrée, flottement, orbite, balancement). Ne livrez jamais de scènes sans icônes. N'utilisez jamais de logos de marque (Adobe, GitHub octocat, etc.) ; utilisez des icônes génériques.
  • 8+ transitions différentes, une par changement de scène : glitch, flou panoramique, zoom traversant, iris + anneau, volet à lattes, flash + secousse, pixellisation, poussée vers le haut. Jamais la même deux fois.
  • Moments d'impact avec effets combinés : explosion d'étincelles + onde de choc + secousse de caméra + split RVB + boom SFX.
  • Sous-titres : 2-3 mots à la fois, gros et gras avec contour épais, mot courant surligné dans la couleur de la scène, petite échelle d'apparition par groupe.
  • Mouvement sur tout : rien n'apparaît sans animation, rien ne reste parfaitement immobile (oscillation / flottement / zoom lent 0 -> 3,5 %).

Disposition et zones de sécurité (canevas de travail 720x1280, agrandi en 1080x1920)

  • Haut 0-130 px : zone libre (interface de la plateforme). Pastille de tag à y~62 uniquement.
  • Zone de contenu y 150-830. Zone des sous-titres centre y = 950 (H-330). Bas 250 px : zone libre (interface de la plateforme).
  • Largeur budgétaire 640 px. Utilisez TXF(texte, taille, police, maxw) pour toute ligne qui pourrait dépasser. Largeur estimée = caractères x 0,55-0,75 x taille selon la police (polices display larges ~0,75).
  • Compteurs : taille de police fixe, jamais de réduction automatique pendant le comptage (évite les sauts).

Voix + synchronisation (résumé ; détails dans les références)

  • Une seule prise, puis alignement : apply_voice_peaks détecte les pics d'énergie des syllabes et les fait correspondre par DP aux syllabes du script (stable à ~0,2 s près). ALIGN=pauses est le repli pour les voix lentes avec des pauses nettes.
  • Les repères utilisent le premier mot dont le texte en minuscules, sans ponctuation, commence par le jeton (chiffres : correspondance exacte). Utilisez occurrence pour les mots répétés.
  • Début de scène = premier mot de la scène - 0,45 s. La durée totale suit la voix (+1,2 s de queue).
  • La musique est synthétisée (nappe + grosse caisse + charleston + basse + arpège) et réduite d'environ 55 % sous la voix ; la voix subit un filtre passe-haut + compression + loudnorm (-15 LUFS). Whoosh à chaque transition, boom sur les impacts, ticks de frappe, ding sur les compteurs, pop sur le CTA.

Passerelle QA (un juge/agent QA doit valider TOUT avant la livraison)

  1. python scripts/review_frames.py out/video.mp4 out/contact.png 12 doit afficher PASS (sinon, quitte avec un code non nul). La loudness et la crête proviennent de cette commande, pas de volumedetect.
  2. Durée 30-60 s, 1080x1920, h264+aac, loudness intégrée environ -18 à -13 LUFS, crête réelle < -1 dBTP (pas d'écrêtage).
  3. Planche contact de >= 9 images + chaque image de transition visualisée : pas de texte coupé/débordant, pas d'éléments superposés, rien dans les 130 px du haut ou 250 px du bas sauf tag/sous-titres, sous-titres lisibles sur chaque arrière-plan.
  4. Règles de variété satisfaites (listez les polices, palettes, arrière-plans et transitions réellement utilisés dans plan.md).
  5. Faits : chaque nombre/date/nom dans le script peut être retracé jusqu'à une source notée dans plan.md ; affirmations adoucies si non vérifiées ; pas de formulation "copie"/"volé" sauf si sourcé ; alpha/limitations indiquées le cas échéant.
  6. Vérification ponctuelle de la synchronisation : choisissez 5 repères (mot d'accroche, un nombre, un nom, une transition, CTA) et confirmez que le visuel commence dans les 0,25 s du mot parlé (comparez les temps SRT/SW aux horodatages des images). Si l'un des contrôles échoue : corrigez, relancez le rendu, relancez la passerelle. Signalez honnêtement les problèmes restants connus.

Pièges déjà rencontrés (à éviter)

  • pip install dans le Python système échoue sur Debian/Ubuntu moderne (externally-managed-environment, PEP 668). Utilisez scripts/setup.sh (crée .venv) et source .venv/bin/activate ; n'utilisez pas --break-system-packages.
  • Comparer le mean_volume de ffmpeg volumedetect (dBFS non pondéré) à une cible LUFS n'a pas de sens et a fait échouer les versions précédentes à leur propre passerelle. Mesurez toujours avec ebur128 (review_frames.py le fait déjà).
  • Image.fromarray sur une image PIL ou sur un recadrage non contigu -> TypeError: expected string or buffer. Gardez les sprites sous forme de tableaux numpy contigus ; rcard() renvoie une image PIL, pas un tableau.
  • Des tranches de tableau vide dans cv2.add -> erreur d'assertion ; protégez b > a avant de découper les bandes.
  • Les processus en arrière-plan démarrés sans setsid nohup meurent lorsque l'appel de l'outil se termine.
  • La génération audio en bac à sable (MCP) ne peut pas être téléchargée par le bac à sable : demandez à l'utilisateur de télécharger le mp3/wav.
  • La synchronisation basée sur les pauses échoue sur les voix AI serrées (seulement 4 pauses trouvées à -35 dB) ; l'alignement basé sur les pics est donc la valeur par défaut.
  • Fenêtres de repères qui se chevauchent : si deux éléments partagent un même mot parlé, décalez le second de 0,2-0,4 s.
  • Les emoji avec sélecteurs de variation (ex. bouclier, avertissement) s'affichent correctement avec embedded_color=True ; redimensionnez avec INTER_AREA (réduction) / INTER_CUBIC (agrandissement).
  • Une police manquante se rabat silencieusement sur DejaVu/Liberation avec une ligne [warn] - vérifiez le journal de rendu pour [warn] avant d'accuser la mise en page.

Skills associés