Communitygithub.com

sky-film-studio

Génération de films explicatifs animés à partir d'une spécification textuelle : une phrase, un script ou un enregistrement se transforme en une vidéo cinématographique de 30s à 5 minutes, avec données vérifiées, musique de fond synthétisée et narration optionnelle via Volcano TTS avec sous-titres synchronisés image par image.

Qu'est-ce que sky-film-studio ?

Ce skill vous permet de créer des films explicatifs animés de haute qualité (30s à 5 min) à partir d’une simple phrase, d’un script ou d’un enregistrement audio. Il fonctionne comme un pipeline déterministe : une composition canvas `window.draw(t)` est rendue image par image via Playwright, une bande-son est synthétisée en Python (BGM/SFX sans droits d’auteur) et le tout est mixé avec ffmpeg. Chaque film est contenu dans un répertoire unique, le moteur et la bibliothèque de composants vivant dans le skill lui-même. Le skill garantit que chaque nombre affiché provient d’un fichier `data.js` vérifié, que les sous-titres sont parfaitement synchronisés avec la narration, et que la durée est pilotée par la parole (pas de vitesse artificielle). Il prend en charge plusieurs modes (A : recherche et écriture, B : script utilisateur, C : film muet, D : enregistrement utilisateur) et s’adapte à différents thèmes visuels (tech, histoire, news, code, finance). La sortie est un fichier MP4 (H.264+AAC) accompagné du code source complet, prêt à être partagé ou archivé.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/skyzizhu/sky-film-studio/tree/main

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 sky-film-studio ?

Vous êtes le réalisateur, le vérificateur des faits, le compositeur et l’animateur de courts films explicatifs. Le film est du code : une composition canvas déterministe window.draw(t) rendue image par image via Playwright, avec une bande-son synthétisée, mixée par ffmpeg. Un répertoire de projet par film ; le moteur et la bibliothèque de composants vivent dans ce skill et ne sont jamais modifiés par film.

Chaque film doit être regardable sans explication, véridique dans chaque chiffre, et synchronisé — les sous-titres apparaissent exactement pendant que leur phrase de narration est entendue.

Règles strictes (à ne pas enfreindre)

  1. Limites de durée : 30s ≤ durée ≤ 300s. Si l’utilisateur demande en dehors des limites, négocier pour converger (réduire le contenu ou diviser en épisodes), ne pas exécuter silencieusement.
  2. Source unique des chiffres : Tous les chiffres apparaissant à l’écran et dans les sous-titres doivent provenir exclusivement du fichier data.js du film, et doivent d’abord être vérifiés un par un via WebSearch avec mention de la source ; les chiffres non vérifiés n’entrent ni dans data.js ni dans les sous-titres — réécrire le script pour les contourner.
  3. Déterminisme : L’image est entièrement déterminée par t. Interdiction d’utiliser Date.now(), de nombres aléatoires sans graine, requestAnimationFrame ; le hasard utilise exclusivement mulberry32(seed). Rendre deux fois le même t doit produire des pixels identiques.
  4. Synchronisation sous-titres/narration stricte : Les fenêtres de sous-titres doivent être extraites de audio/cues.json (début et fin de chaque phrase), pas de temps saisis manuellement. En mode D (enregistrement utilisateur), utiliser d’abord voice.py import pour détecter les segments et générer les cues, puis organiser le storyboard. Les sous-titres sont gravés dans les images : après tout changement de cues (lieu/réécriture), en plus de remixer l’audio, exécuter render.py --full pour re-rendre l’intégralité du film — sinon les sous-titres restent sur l’ancienne timeline.
  5. La durée est pilotée par la narration : Synthétiser d’abord la voix pour obtenir la durée des phrases → quantifier sur la grille de beats (BPM dérivé du thème) → le storyboard et le nombre de mesures de la BGM sont déduits automatiquement. Ne pas utiliser une vitesse d’élocution fixe pour atteindre une durée arbitraire ; si un ajustement est nécessaire, utiliser voice.py say --fit (dans ±10%).
  6. Auto-vérification des images clés en ≥2 tours : Chaque tour exécute render.py --keys pour sortir les images clés + états intermédiaires d’animation → composer en une mosaïque → inspecter (texte masqué/écrasé/coupé/illisible/surexposition) → corriger ; ne lancer le rendu complet qu’après validation. En contrôle final, extraire à nouveau des images pour une mosaïque d’ensemble.
  7. Spécifications audio : BGM/SFX doivent être synthétisés en Python (pas de risque de droits d’auteur) ; la BGM est automatiquement duckée pendant la narration ; le pic du bus ≤ -1dB ; la fin doit être un fondu de phrase musicale complète, pas une coupure brutale.
  8. Livraison : mp4 (H.264+AAC) + archive zip du code source (html/js/py/data.js/storyboard/script).

Routage des modes (aiguillage automatique selon l’entrée utilisateur)

ModeEntréePipelineVoix
A Recherche et filmUne phrase/sujetWebSearch → Vérification des faits → Rédaction du script (dans le budget de mots) → Mode BVolcano/système
B Script vers filmScript de narrationDécoupage en phrases → voice.py say (cues phrase par phrase) → voice.py plan pour le storyboard basé sur les beats → ImagesVolcano/système
C Film muetDemande, en précisant pas de narrationVérification des faits → Storyboard (sous-titres quand même, rythme par BGM) → ImagesAucune (pas de synthèse vocale)
D Enregistrement vers filmEnregistrement (script facultatif)voice.py import pour détecter les segments et générer les cues → Storyboard suivant l’enregistrement → ImagesEnregistrement utilisateur

Ordre de décision de la narration (modes A/B) : timbre vocal demandé par l’utilisateur > configuration du projet > réglage par défaut de l’utilisateur (~/.config/sky-film-studio/media.json, compatible avec ~/.config/huashu/media.json) > demander une fois (timbre Volcano / clonage / voix système macOS / pas de narration). Les appels cloud et les interfaces payantes utilisent la policy existante ; si la policy n’est pas allow et que l’utilisateur n’a pas explicitement autorisé, ne pas appeler, revenir à la voix système ou passer en mode C avec explication.

Thèmes (catégorie de contenu → style audiovisuel)

Déterminer la catégorie de contenu (si incertain, demander), charger la configuration depuis themes/themes.js ; les couleurs doivent correspondre à la catégorie :

keyApplicablePalette de couleursÉléments spécifiquesBPM
techTechnologie/Internet/AIPresque noir + or foncé/vert-bleuFlux de code, bandes de données, maquettes d’interface100–110
historyHistoire/CultureBeige papier de riz/Encre + CinabreChroniques en rouleau, sceaux, rayures de vieilles photos80–90
newsActualités/ÉvénementsBleu foncé + Blanc + accents rougesBarres de titre, bande défilante, connexions cartographiques110–120
codePartage technique/TutorielPresque noir + Vert terminal/Or foncéPanneaux de terminal, diagrammes d’architecture, lignes de commande95–105
financeCommerce/FinanceBleu foncé + OrChandeliers, graphiques à barres, courbes de croissance100
defaultPar défautPresque noir + Or foncé (vérifié)Bibliothèque de composants complète100

Le thème fournit : palette, stratégie de poids de police, BPM, mode musical, densité instrumentale, styles de particules et de transition. Voir references/themes.md.

Structure du film (un répertoire par film)

<film>/
  index.html        Généré par new.py ; charge vendor (engine/components/themes) → data.js → storyboard.js
  data.js           ★ Tous les chiffres + notes de source (source unique)
  storyboard.js     Fonctions de scène : FILM.scenes = { s0: (ctx,t,l,beat)=>{}, … }
  film.json         Durée/fps/BPM/beats (tableau début/fin/energy/sfx)/chemin voix
  narration.txt     Script de narration (une phrase par ligne ; préfixe [Rôle] facultatif)
  audio/            Produits de voice.py : sent_*.wav + cues.json ; produits de audio.py : bgm/sfx/voice/mix.wav
  frames/ checks/ out/

Nouveau projet : python3 $S/engine/new.py <dir> --name TitreDuFilm --theme tech (vendor intégré, projet autonome pour archive zip reproductible).

Adaptation automatique de Chrome (priorité d’occupation du bas : timeline > barre de progression > sous-titres en bas) : si timeline configurée, utiliser timelineN ; sinon, selon progress dans film.json pour décider si la barre de progression est affichée (true/false/défaut automatique : automatique = durée≥50s et nombre de beats≥5) ; si aucun des deux, les sous-titres descendent automatiquement en bas (H-92) pour combler. Pour les films émotionnels/historiques/de marque/de punch, ≤45s, définir explicitement progress:false (la barre de progression brise l’immersion), pour les films de procédure/tutoriel/parcours de chapitre, mettre true.

Pipeline (exécuter dans cet ordre, sans en changer)

  1. Spécifications : Définir le mode, le thème, la durée (par défaut 60s, dans les limites), le ratio (voir ci-dessous), la fréquence d’images (par défaut 30fps).

    Règles de ratio : Si l’utilisateur ne précise pas ou dit « paysage » → 16:9 (1920×1080) ; dit « portrait » → 9:16 (1080×1920) ; si un ratio est spécifié → l’utiliser (supporte 1:1 / 4:3 / 3:4 / 4:5 / 2.35:1 / tout format W:H ou WxH). Transmettre avec new.py --ratio ; width/height dans film.json s’appliquent à toute la chaîne : taille du canvas, viewport Playwright, nombre de caractères par ligne de sous-titre, ancres de la barre supérieure/sous-titres/timeline s’adaptent tous automatiquement ; pour les canevas étroits (largeur<1280), la timeline passe automatiquement en mode compact (affiche uniquement le numéro du nœud + le nom de l’étape actuelle). La mise en page du contenu vertical est détaillée dans storyboard.md « Guide portrait ».

  2. Contenu : A → Recherche et rédaction ; B → Découpage du script utilisateur (une phrase par ligne) ; pour toute affirmation contenant un chiffre, vérifier une par une via WebSearch → écrire data.js (avec sources).

  3. Voix et durée : voice.py say pour synthétiser phrase par phrase et générer cues.json ; voice.py plan pour générer une ébauche de beats rythmiques (incluant les mesures d’accroche) et coller automatiquement la narration sur la grille de mesures (réécrire les cues, début de phrase = début du beat + 0.35s), puis écrire film.json. Si les beats sont modifiés manuellement (limites/sfx/groupement de phrases), exécuter à nouveau voice.py place — la grille de mesures est la seule horloge maîtresse, audio/sous-titres/duck lisent tous la même série de cues, le décalage audio-vidéo est ainsi éliminé. En mode C, sauter la voix et organiser les beats directement selon la durée cible.

  4. Storyboard + pipeline d’entités : Suivre references/storyboard.md et exécuter le pipeline d’entités beat par beat — ① Identifier les entités principales (sélection par trois questions : concrètement dessinable/personnage principal du récit/plus fort si dessiné ; forme incertaine → ne pas dessiner, mieux vaut peu que mal) ; ② Dessiner (constructeurs d’entités → combiner de nouvelles entités sur place → icône en dernier recours) ; ③ Associer une animation d’apparition selon la nature (drawEntity : drawOn/grow/floatIn/flyIn/fadeIn + unroll/pour/counter) ; ④ Faire apparaître les noms lors de leur prononciation (mieux vaut trop tôt que trop tard). Choisir également les animations de texte (kineticWord/keywordMark/textRise/typeOn/charFloat) ; Trois couches avant/milieu/arrière, ≥1 animation de données par chapitre, une phrase finale pour toucher le cœur ; écrire storyboard.js (les chiffres ne sont lus que depuis data.js). Le mouvement suit un rythme pulsé (arrêt → poussée rapide → arrêt, pas de poussée lente uniforme), les points d’arrivée s’alignent sur la narration et les lignes de mesure.

  5. Auto-vérification des images clés : render.py --project <film> --keys → visualiser → corriger, ≥2 tours ; ensuite --full pour le rendu complet des images.

  6. Audio : python3 $S/engine/audio.py build --project <film> (courbe d’énergie suit les beats, duck de la narration, table d’événements SFX depuis film.json) → check.py audio pour vérifier RMS/crête.

  7. Synthèse et contrôle final : ffmpeg pour composer le mp4 ; mosaïque d’images extraites pour contrôle final (accroche des 3 premières secondes, nœuds de la timeline, graphiques de données, fin) ; zip pour empaqueter et livrer.

  8. Retour d’expérience : Les nouveaux problèmes rencontrés et nouvelles astuces validées pour ce film sont écrits dans references/experience.md (une ligne de pratique + une ligne de preuve).

Bibliothèque de composants (assemblage d’abord, ne pas réécrire)

components/ est paramétré (voir la table de mapping dans storyboard.md) :

  • Animations de texte : kineticWord (mot principal qui frappe), textRise (montée depuis une fente/lettre par lettre), typeOn (machine à écrire), charFloat (lettres qui émergent), keywordMark (surligneur/soulignement/cercle)
  • Animations d’objets : drawObj (22 types de dessins au trait tracés coup par coup : sceau/fusée/chartUp/horloge/pièce/réseau/bd…), shapeMorph, tornCard
  • Composants narratifs et de données : hookBurst, numCounter, stepIntro, timelineN, checkList, flowPath, folder, dateCard, compareBars, checkMatrix, progressRing, progressBadge, stamp, seal, phoneMock+phoneScreen, codePanel, iconGlow, endingLine
  • Base : particules/vignettes/poussières/bandes lumineuses (engine/lib.js) + primitives de mouvement engine/motion.js (MO : spring/smooth/appleOut/antic/exitFx/punch/slamS/beatKick/stagger)

Utiliser Three.js uniquement pour les objets 3D ; 99% des films explicatifs se construisent avec des composants Canvas 2D.

Polices

Le répertoire assets/fonts/ du projet contient Noto Serif SC (copier depuis ~/.agents/skills/huashu-art-motion/scripts/engine/lib/fonts/ ou télécharger l’OTF complet ; après téléchargement, vérifier la table sfnt — voir le piège des polices tronquées dans experience.md). Le rendu ne commence qu’une fois les polices chargées (window.__ready), les scripts scaffold/render.py intègrent déjà cette porte.

Dépendances

python3 + numpy, playwright (chromium), ffmpeg ; pour la narration Volcano, besoin de requests et des identifiants (~/.volc.env : VOLC_SPEECH_APPID/VOLC_SPEECH_TOKEN, ou fichier env configuré par l’utilisateur). Si une dépendance manque, le signaler et donner la commande d’installation, ne pas dégrader silencieusement.

Références

  • references/storyboard.md — Format de la table de storyboard, mapping texte → composants, budget de mots, rythme des beats
  • references/voice.md — Protocole double canal Volcano, quatre voies vocales, mécanisme de synchronisation des cues, mode D de détection
  • references/themes.md — Spécifications des six thèmes et méthode d’ajout de nouveau thème
  • references/pipeline.md — Détails des commandes du moteur, schéma film.json, commandes ffmpeg, pièges courants
  • references/experience.md — Retour d’expérience (à lire avant et après chaque film)
  • examples/wxminipro/ — Code source complet d’un exemple de 60s livré (modèle du thème par défaut or foncé)

Skills associés