Communitygithub.com

JaviMaligno/agilabs-video-studio

Construis les scènes d'une vidéo explicative d'article dans Remotion – écris src/timeline.ts à partir d'un script approuvé, choisis et configure des composants d'animation (Counter, BarCompare, FlowDiagram, KeyQuote, StatGrid), ajoute un composant sur mesure avec un frameState testé, reste dans la zone de sécurité verticale et vérifie les rendus d'images fixes à l'œil. À utiliser lors de la composition, modification ou débogage des scènes d'une vidéo réalisée avec ce plugin.

Qu'est-ce que agilabs-video-studio ?

Ce skill permet de construire une vidéo explicative d'article en utilisant Remotion, à partir d'un fichier `src/timeline.ts` structuré en trois types de scènes : `intro` (accroche visuelle), `anim` (composant d'animation choisi dans un catalogue) et `outro` (carte de fin). Le développeur écrit la timeline en définissant des lignes de narration bilingues (anglais/espagnol) avec des beats de synchronisation, et peut utiliser cinq composants prêts à l'emploi : Counter (compteur animé), BarCompare (barres de comparaison), FlowDiagram (schéma avec nœuds et arêtes), KeyQuote (mise en évidence mot par mot) et StatGrid (grille de statistiques). Pour les scènes marquées 'bespoke', le skill guide l'ajout d'un composant personnalisé : il impose d'écrire d'abord une fonction pure `frameState` testée unitairement, puis de dessiner le composant React en utilisant les tokens de marque (couleurs, gradient, typographie Inter). Les animations sont contraintes à une zone de sécurité verticale (1080x1920) pour éviter les recouvrements par l'interface de la plateforme. Une vérification manuelle des images fixes (stills) à différentes trames est requise avant le rendu final, avec des règles strictes de lint (durée, vélocité des sous-titres, noms de composants).

Compatible avec~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/JaviMaligno/agilabs-video-studio/tree/HEAD/skills/explainer-animation

Demander à votre IA préférée

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

Documentation

Animation explicative

Une vidéo est une liste ordonnée de scènes dans src/timeline.ts. Trois types :

  • intro : la carte d'accroche. Sa première ligne est l'accroche, affichée en grand, ses mots s'illuminent au fur et à mesure qu'ils sont prononcés (elle sert également de légende).
  • anim : un composant d'animation issu du registre, synchronisé avec les lignes de narration de la scène.
  • outro : la carte de fin avec le badge AGILabs, javieraguilar.ai et le titre de l'article provenant de SETTINGS.articleTitle.

Écrire la timeline

import type { Cuts } from './types.ts';
import { L, anim, intro, outro, say, videos } from './narrate.ts';

const build = (): Cuts => ({
  main: [
    intro('hook', [say(0.4, 'EN hook line.', 'ES hook line.')]),
    anim(
      'result',
      'BarCompare',
      { bars: [{ label: L('Avec le pourquoi', 'Con el porqué'), value: 14, display: '14/20', highlight: true },
               { label: L('Sans lui', 'Sin él'), value: 4, display: '4/20' }], max: 20 },
      [say(0.3, 'First line.', 'Primera línea.'), say(0, 'Second line.', 'Segunda línea.')],
      { min: 4 },
    ),
    outro('outro', [say(0.4, 'More at javieraguilar.ai.', 'Más en javieraguilar.ai.')]),
  ],
});

export const VIDEOS = videos(build);
export const TIMELINE = VIDEOS.en.main;
  • say(at, en, es, spoken?) : une ligne de narration. at est la seconde de scène la plus précoce où elle peut commencer ; les lignes ne se chevauchent jamais (écart de 0,35 s), et la scène dure jusqu'à la fin de sa dernière ligne plus 0,8 s, ou min. spoken ({ en?, es? }) est ce que le TTS lit quand cela diffère du texte de la légende (voir narration).
  • Beats. Le temps de début de chaque ligne dans une scène est un beat. Les composants jouent l'étape i au beat i (la barre i grandit, le nœud i apparaît, la tuile i surgit), donc écrivez une ligne par étape que vous voulez révéler. Avant le TTS, les beats proviennent d'une estimation de durée ; après npm run tts, ils proviennent de l'audio réel, donc vérifiez à nouveau les images fixes après la narration.
  • L(en, es) : une étiquette bilingue à l'écran. Une chaîne simple est utilisée pour les deux langues.
  • Les identifiants de scène doivent être uniques : les clés de lignes (<scene>-01, ...) nomment les fichiers audio.
  • opts.chapter sur anim est stocké sur la scène mais n'est pas dessiné par un composant pour le moment.
  • Exécutez npm run lint après chaque modification : vérification de la durée par rapport à targetSeconds (±20 %), des indications de légende (sous-titres) sous 0,8 s ou plus de 17 caractères/s, et des noms de composants manquants dans le registre.

Catalogue des composants

Tous les composants reçoivent t, beats, dur, lang et vertical de la scène ; les propriétés ci-dessous proviennent de la timeline. Les nombres affichés à l'écran utilisent la forme exacte de l'article : préférez display / valeur string au texte calculé chaque fois que l'article écrit "14/20", "0.0018" ou "83 %".

ComposantUtilisationPropriétés
CounterUn chiffre clé qui défile vers le haut, avec une étiquette en dessousvalue: number, label: Label, prefix?, suffix?, decimals? (0-8), beat? (indice du beat auquel le compteur démarre, par défaut 0)
BarCompare2 à 5 barres horizontales qui grandissent une par beat ; celle mise en évidence avec le dégradé d'accentuationbars: { label: Label; value: number; display?: string; highlight?: boolean; at?: number }[], max? (échelle maximale, par défaut la plus grande valeur), unit? (ajouté quand il n'y a pas de display)
FlowDiagramBoîtes et flèches apparaissant dans l'ordre ; une arête broken est en tirets et atténuée, avec un espacenodes: { id; label: Label; at?: number }[], edges: { from; to; label?: Label; broken?: boolean }[], `layout: 'vertical'
KeyQuoteLa phrase clé, mot par mot, les mots accentués en couleur d'accent avec un soulignementtext: Label, emphasis?: string[] (mots ou phrases, comparés sans tenir compte de la casse ni de la ponctuation), beat?
StatGrid2 à 4 tuiles de chiffres apparaissant une par beatstats: { value: string; label: Label; at?: number }[]

at sur une barre, un nœud ou une tuile le fixe à une seconde de scène au lieu de son propre beat. Les étapes sans beat ni at suivent 0,6 s après la précédente. Chaque composant est ajusté pour se terminer à la fin de la scène : la dernière image montre toujours l'état final.

Pour voir toute la bibliothèque : npm run studio et ouvrez Gallery-vertical, ou rendez des images fixes.

Ajouter un composant sur mesure

Lorsque le script marque une scène "bespoke" :

  1. L'état d'abord, avec un test. Écrivez src/anim/<Nom>.state.ts avec le type des propriétés et une fonction pure frameState(props, t, beats, dur) qui renvoie des nombres et des chaînes simples. Pas d'import Remotion ou React ici. Construisez-le à l'aide de src/anim/steps.ts (sceneTime, stepTimes, fit, progress, beatAt, easeOutCubic) pour qu'il soit total : valeurs finies à tout t, champs de progression dans [0, 1], rien de visible avant son premier beat, état final à t = dur.
  2. Ajoutez un cas à CASES dans test/anim.test.ts (et un test de son propre comportement), puis exécutez npm test. Il vérifie l'état pour t < 0, chaque beat, dur et au-delà de dur, avec des beats manquants, tardifs et très courts.
  3. Dessinez-le dans src/anim/<Nom>.tsx : appelez frameState, dessinez dans <Stage vertical={...}>, utilisez les jetons de marque de src/brand.ts (C, GRADIENT, alpha) et Inter. Pas de nouvelles couleurs ni polices.
  4. Enregistrez-le dans ANIMS dans src/anim/index.ts. Gardez ANIMS comme un simple objet littéral de noms : npm run lint les lit à partir du code source.
  5. Optionnellement, ajoutez un exemple dans src/Gallery.tsx. S'il est réutilisable, il doit retourner dans le template du plugin.

Images générées. La plupart des scènes doivent être dessinées en code (SVG et CSS à partir des jetons de marque). Si une scène a vraiment besoin d'une image générée (un arrière-plan, une image de base, un moment texturé), un modèle d'image peut la créer, par exemple la génération d'images de Codex CLI. Enregistrez-la sous public/, chargez-la avec staticFile(), gardez-la dans la palette de la marque, et vérifiez l'image fixe.

Zone de sécurité verticale (1080x1920)

  • L'interface de la plateforme couvre les ~220 px du haut et les ~380 px du bas ; gardez 72 px sur les côtés.
  • Les animations se dessinent uniquement à l'intérieur de la scène : de y = 280 (sous le badge AGILabs) à y = 1280 (au-dessus des deux lignes de légende), 936 px de large. Stage / stageOf() vous donne cette boîte.
  • Les légendes se trouvent sous la scène, au maximum deux lignes d'environ 32 caractères, dans ~900 px.

Images fixes : regardez-les

Rendez des images fixes et lisez chaque PNG avant de rendre la vidéo. Un lint ou une construction propre n'affiche pas de débordement, de texte coupé ou un nombre erroné.

npx remotion still src/index.ts Main-EN-vertical out/stills/f0150.png --frame=150

Prenez une image fixe par scène une fois sa dernière étape jouée, plus une toutes les ~3 s (toutes les 90 images à 30 ips). Vérifiez : le badge AGILabs et rien d'autre comme marque, rien en dehors de la zone de sécurité, aucun texte débordant de sa boîte, chaque chiffre égal à celui de l'article, et la légende à l'écran correspondant à ce que l'animation montre à ce moment-là.

Individual skills in this repo

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

Skills associés