Communitygithub.com

dmtrKovalenko/fframes

Créez, animez, révisez et rendez des vidéos en code avec fframes (Rust, scènes SVG, encodage ffmpeg, rendu GPU Skia). Utilisez-le dès qu'un utilisateur souhaite une vidéo, une animation, un motion design, une vidéo explicative, une promotion, un clip social, un carton-titre, un visuel de podcast, une vidéo de paroles/sous-titres ou tout fichier .mp4/.webm généré programmatiquement, ou demande de modifier, corriger, accélérer ou vérifier une vidéo fframes. Couvre l'installation de fframes, la création d'un projet, la conception de mouvements élégants, les plans 3D (`fframes::three_d`, scènes de type three.js), le son (musique, voix, bruitages, volume), la visualisation dans une fenêtre de prévisualisation en temps réel, et la vérification du résultat sans le regarder : images et planches contact en PNG, détection automatique des problèmes, données de volume, rendus rapides et par plage.

Qu'est-ce que fframes ?

Cette compétence permet de créer des vidéos animées en utilisant fframes, une bibliothèque Rust qui génère des vidéos à partir de code. Elle transforme des structures Rust, où chaque image est une scène SVG construite avec la macro `svgr!`, en vidéos .mp4 ou .webm via ffmpeg. La compétence guide l'utilisateur à travers l'installation, la création de projet avec des templates (`single-scene` ou `multi-scene`), la conception de motion design unique (évitant les choix par défaut comme le « slop »), l'ajout de son (musique, voix, SFX) et la prévisualisation en temps réel via le backend Skia GPU. Elle propose une boucle de développement rapide : après chaque modification, des commandes CLI (`timeline`, `inspect`, `strip`, `frame`, `onion`, `preview`) permettent de vérifier la structure, détecter les problèmes, examiner les mouvements et juger la composition sans encoder la vidéo complète. La compétence met l'accent sur la planification préalable, l'absence de tests (utilisant les outils d'inspection intégrés), et l'optimisation du rendu avec des paramètres comme `--draft` et `--release`.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/dmtrKovalenko/fframes/tree/HEAD/skills/fframes-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 avec fframes

fframes est une bibliothèque Rust qui permet de générer des vidéos à partir de code. Une vidéo est une structure Rust avec une méthode render_frame(frame) -> Svgr : pour chaque image, elle retourne un arbre SVG, construit avec la macro svgr! (balisage SVG avec {expressions rust}). Les scènes divisent la timeline, timeline! et les ressorts animent les valeurs, une carte audio place le son, et ffmpeg encode le résultat.

Chaque projet obtient une interface en ligne de commande (depuis fframes::cli). Utilisez-la pour tout : rendre une vidéo, ouvrir la fenêtre de prévisualisation en temps réel, et consulter les images, les planches contact et les données de volume sous forme de fichiers que vous pouvez lire. Lisez references/design.md avant de concevoir, references/api.md pendant l'écriture du code, references/audio.md pour le son et references/3d.md pour les plans 3D (fframes::three_d).

Lorsque vous correspondez à une vidéo fournie, suivez d'abord les directives d'analyse de référence dans references/design.md. Ses coupes, son rythme et ses mouvements priment sur les valeurs par défaut de conception ci-dessous ; les montages rapides et les images noires intentionnelles peuvent faire partie du résultat demandé.

Deux règles avant tout

Planifiez avant d'écrire du code

N'ouvrez pas le modèle et ne commencez pas à animer. D'abord :

  1. Définissez le brief : qui regarde et où (la plateforme détermine le format et la durée), la seule chose que le spectateur doit retenir, le ton, et les éléments existants (logo, plans produits, séquences, musique, voix-off). Demandez à l'utilisateur ce qui manque et est important. N'inventez jamais de faits, de chiffres ou de citations liés au produit.
  2. Lorsque la vidéo est montée sur de la musique ou une voix, choisissez d'abord le son. Son tempo, ses battements et ses phrases définissent le timing de tout le reste.
  3. Planifiez d'abord le motion design, synchronisez le motion design avec les pics sonores pour créer un flux unique : d'où les éléments apparaîtront, comment ils se transformeront. Essayez de créer un motion design unique pour chaque scène afin qu'elle paraisse unique et soignée. La vidéo ne doit pas ressembler à un diaporama.
  4. Essayez de raisonner sur la ressenti de la personne qui regarde la vidéo finale et ajustez chaque élément de conception en conséquence : le flux, le tempo, les battements, le mouvement et les couleurs.

Pas de « slop »

Le « slop » est une vidéo faite de choix par défaut : elle pourrait concerner n'importe quel produit avec seulement le texte changé, et les spectateurs la reconnaissent en une seconde. À moins que l'utilisateur ne le demande, ne livrez pas :

  • Reliquats de modèle : la mise en page, les couleurs, la police ou les décorations de départ, le texte de substitution, les logos factices, les chiffres inventés.
  • Spam de battements : tout le cadre qui zoome, tremble ou clignote à chaque battement. Synchronisez de petits éléments sur le battement (un trait, un mot, une étincelle) et changez le cadre entier uniquement à quelques coupes.
  • Un seul mouvement pour tout : chaque élément qui apparaît en fondu de 40 px avec la même easing et la même durée.
  • Scènes statiques : un élément apparaît, reste et disparaît en fondu sans que rien d'autre ne bouge.
  • Copie générique : « Présentation », « Libérez », « Fluide », « Prochain niveau », des slogans de trois mots (« Rapide. Simple. Puissant. »). Écrivez le texte à l'écran comme une personne le dirait.
  • Texte en général : la quantité de texte doit être limitée et pertinente.

À la place, donnez à chaque élément une raison liée au sujet et retirez ce qui n'en a pas. Investissez l'effort dans le détail et le mouvement plutôt que dans les mots : mouvement secondaire, entrées décalées, traits dessinés, objets qui réagissent les uns aux autres, éléments portés à travers les coupes. Avant de montrer quoi que ce soit à l'utilisateur, regardez une bande et demandez-vous si la vidéo fonctionnerait toujours pour un produit différent avec seulement le texte changé. Si c'est le cas, changez l'idée, pas les couleurs.

1. Installation

Rust depuis https://rustup.rs, puis les bibliothèques système avec lesquelles ffmpeg est construit :

# macOS
brew install pkg-config ffmpeg x264 x265 opus nasm ninja
# Debian / Ubuntu
sudo apt-get install -y yasm nasm ffmpeg libx264-dev libx265-dev libopus-dev libclang-dev clang ninja-build libvpx-dev libasound2-dev
# Arch
sudo pacman -S ninja yasm nasm ffmpeg x264 x265 opus clang

Windows utilise une version précompilée partagée de FFmpeg 9 à la place (définissez FFMPEG_DIR sur le dossier décompressé ffmpeg-n9.0-latest-win64-gpl-shared depuis BtbN/FFmpeg-Builds, ajoutez son bin à PATH, installez LLVM avec winget install LLVM.LLVM et définissez LIBCLANG_PATH). Les détails sont dans le README de fframes.

2. Créer un projet

curl -fsSL https://raw.githubusercontent.com/dmtrKovalenko/fframes/main/scripts/new-video.sh | bash -s -- my-video --yes
# ou installez le générateur une fois et utilisez-le directement :
cargo install --locked cargo-fframes
cargo fframes new my-video --format landscape --fps 30 --yes

Options : --template single-scene|multi-scene, --format landscape|portrait|square|uhd, --fps, --title, --backend, --dir. Le projet dépend de la version de fframes qui correspond à cargo-fframes installée ; --git utilise la branche main du dépôt à la place. Passez toujours --yes pour éviter d'attendre une entrée.

Modèles :

  • single-scene (par défaut) : une scène. Il s'adapte à tous les formats ; commencez ici pour les clips à un seul plan, les cartons-titres et les vidéos portrait.
  • multi-scene : deux scènes. Commencez ici pour tout ce qui comporte plusieurs scènes ; il n'accepte que landscape et uhd.

Le contenu du modèle est un code de démonstration qui montre l'API. Remplacez sa mise en page, ses couleurs, ses polices et ses décorations par une conception faite pour la vidéo demandée par l'utilisateur.

Utilisez le backend GPU Skia (par défaut). cargo fframes new sélectionne Skia sur Metal (macOS) ou Vulkan (Linux, Windows). Il rend environ 10 fois plus vite que le backend CPU et vous offre la fenêtre de prévisualisation en temps réel preview. Sur macOS et Linux, la première compilation télécharge Skia et ffmpeg précompilés et ne compile que les dépendances Rust (environ une minute ; les autres cibles, ou metal et vulkan ensemble, compilent Skia à partir des sources pendant ~20 minutes). Lancez-le tout de suite et écrivez la vidéo pendant qu'il tourne :

cd my-video && cargo build --release        # exécutez en arrière-plan, la première compilation est la plus lente

--backend cpu ne nécessite pas Skia mais n'a pas de fenêtre de prévisualisation ; choisissez-le uniquement lorsqu'il n'y a pas de GPU.

Le projet se rend comme généré :

my-video/
  src/lib.rs        # la vidéo (à partir du modèle)
  src/main.rs       # l'interface en ligne de commande
  media/            # polices, images et audio compilés dans le binaire (une police de départ)
  README.md         # les commandes ci-dessous

Chaque commande ci-dessous est cargo run --release -- <commande>. Définissez une fonction shell courte (une variable comme R="cargo run --release --" ne se sépare pas en mots dans zsh, le shell macOS) :

R() { cargo run --release -- "$@"; }

3. La boucle

N'écrivez pas de tests du tout lorsque vous utilisez cette compétence. Ne créez pas de tests unitaires, d'intégration, de snapshot ou de régression visuelle, ni de modules de test ou de harnais de test. Validez la vidéo avec inspect, les images rendues, les planches contact, les vérifications audio et la prévisualisation native.

Prévisualisez, ne rendez pas. Si la vidéo utilise le backend de rendu GPU et qu'un GPU est disponible sur cette machine, exécutez la prévisualisation native (ou montrez la commande à l'utilisateur) au lieu de rendre la vidéo à nouveau après chaque modification. Une fois les changements prêts à être révisés :

  1. Montrez une commande complète dans un bloc de code shell copiable, en utilisant le chemin réel du projet et le nom du package ; n'exigez pas que l'utilisateur ait défini l'assistant $R. Par exemple : cd /chemin/absolu/vers/fframes && cargo run --release -p my-video -- preview 0s.
  2. Proposez explicitement d'exécuter cette prévisualisation pour l'utilisateur. S'il a déjà autorisé l'ouverture ou l'actualisation de la prévisualisation, montrez la commande et continuez dans le cadre de cette autorisation.

Après un changement demandé, définissez l'heure de début de la commande sur une seconde spécifique à ou juste avant la section modifiée, avec suffisamment d'avance pour voir son entrée ou sa transition. Par exemple, preview 8.5s permet à l'utilisateur de réviser un changement vers 9 secondes sans rejouer le début. Indiquez quelle section ils verront. Rendez la vidéo complète lorsque l'utilisateur demande l'export final ; ne demandez pas une autre confirmation si cette demande est déjà explicite.

Après chaque modification :

  1. $R timeline liste les scènes avec leurs plages d'images et de secondes, et chaque piste audio. Vérifiez la structure et le rythme ici avant de regarder les pixels.
  2. $R inspect vérifie une image toutes les 0,25 s ainsi que la première et la dernière image de chaque scène. Il signale les images, polices ou glyphes manquants, le texte coupé par le bord du canevas, les SVG invalides (rectangles de taille nulle, mauvais rayons), les transformations cassées et les paniques, chacun avec son heure et sa scène. Il se termine avec le code 2 en cas d'erreur. Corrigez tout ce qu'il signale. Un avertissement qui n'apparaît que sur les premières images d'une scène est généralement une entrée ; vérifiez-le avec une bande.
  3. $R strip <scène ou plage> -n 12 écrit une planche contact (strip.png) : images espacées uniformément dans une seule image étiquetée. Ouvrez-la avec votre outil d'image. C'est le moyen le plus rapide de juger la mise en page, le rythme et le mouvement. $R strip 2s,5s,9s place les heures choisies côte à côte.
  4. $R frame Intro@end,Outro@50% écrit des PNG pleine taille dans frames/ pour les vérifications de détail (typographie, alignement, contraste) et imprime les problèmes trouvés dans ces images. Jugez les petits détails (contact entre les éléments, bords, petites formes) sur un recadrage agrandi net, jamais sur une image réduite : $R frame 3s --crop 1100,520,240,120 (pixels vidéo, zoomés à environ 960 px de large). --ids dessine et nomme chaque élément qui a un id, pour trouver quelle forme est quoi.
  5. $R onion "[email protected]@1s" -n 6 fusionne les images en une seule image (onion.png) pour montrer le chemin et l'espacement d'un mouvement : easing, dépassement, décalage.
  6. $R preview Intro ouvre une fenêtre en temps réel avec du son pour que l'utilisateur regarde (espace lecture/pause, h/l cherche une seconde, j/k avance d'une image, q quitte). Elle bloque jusqu'à la fermeture, donc lancez-la en arrière-plan lorsque vous l'exécutez pour l'utilisateur. Montrez la commande et proposez de la lancer comme décrit ci-dessus ; après les modifications, utilisez une seconde spécifique près du changement.

Lorsqu'un échantillon encodé est nécessaire, $R render Intro --draft encode une scène à moitié résolution. $R render écrit la vidéo complète pour un export final demandé.

Avant de montrer une vidéo terminée, exécutez $R inspect --pops : il rend chaque image en petit et avertit des pops, parties de l'image qui changent en une image entre des images fixes, comme un élément qui apparaît, disparaît ou saute devant un autre au lieu de s'y déplacer. Chaque avertissement donne la commande frame ... --crop ... pour le regarder ; les répétitions de la même région (compteurs, lumières clignotantes) sont regroupées en un seul avertissement.

Règles :

  • Regardez les PNG avant de dire que tout va bien.
  • Préférez strip à plusieurs appels frame ; ajoutez --scale 0.5 lorsque la composition est tout ce dont vous avez besoin.
  • Ajoutez --json lors de l'analyse de la sortie : le résultat va sur stdout, la progression sur stderr.
  • Gardez --release : les compilations de débogage rendent plusieurs fois plus lentement.

Adresser le temps

120 (image), 3.2s, 500ms, 1:05.5, 50%, start, end ; scènes par nom de structure, Intro (correspond également à IntroScene, insensible à la casse), #3 (index de scène), Intro[1] (deuxième scène de ce type) ; à l'intérieur d'une scène [email protected], Intro@12, Intro@50%, Intro@end. Plages : a..b (fin exclusive), a.., ..b, all, ou un nom de scène pour la scène entière. Séparez plusieurs heures par des virgules.

Toutes les commandes

commandeutilisez-la pour
timelinevoir les scènes, les durées, les pistes audio et leurs paramètres de mixage
inspect [PLAGE] [--every 0.1s | --all-frames] [--fail-on warning] [--pops]trouver des problèmes sans rendre les pixels ; --pops trouve également les éléments qui apparaissent ou disparaissent brusquement
strip [PLAGE | HEURES] -n N [--columns 4] [--width 480] [--crop x,y,w,h]réviser le flux et le mouvement dans une image
frame HEURES [-o dossier] [--svg] [--crop x,y,w,h] [--zoom N] [--ids]PNG pleine taille (et le SVG mis en page) des images choisies, recadrages nets, éléments étiquetés
onion PLAGE -n Nvoir la trajectoire et l'easing d'un mouvement
svg HEURElire le SVG final d'une image sous forme de texte (positions, texte, couleurs)
preview [HEURE] [--paused] [--mute]fenêtre en temps réel avec du son, pour l'utilisateur
render [PLAGE] [-o out.mp4] [--draft]encoder la vidéo ou une partie de celle-ci (audio coupé pour correspondre)
audio analyze [PLAGE] [--waveform w.png]volume (LUFS), pic réel, écrêtage, silence, par scène
audio at HEURESquels sons jouent à un moment donné, où dans leur fichier et à quel volume
audio render [PLAGE] -o a.wavle mixage sous forme de fichier WAV

Éditeur navigateur

fframes dispose également d'un éditeur web avec une timeline et un défilement, utile lorsqu'une personne souhaite modifier une vidéo de manière interactive. Il exécute la vidéo compilée en WebAssembly et nécessite Node.js plus wasm-pack ; la configuration est le dossier editor/ de l'exemple hello-world dans le dépôt fframes (https://github.com/dmtrKovalenko/fframes/tree/main/examples/hello-world). Mentionnez-le lorsque l'utilisateur demande un éditeur GUI. Pour regarder, utilisez preview, et pour votre propre révision, utilisez la CLI.

4. Écrire la vidéo

impl Video for MyVideo<'_> {
    const FPS: usize = 30; const WIDTH: usize = 1920; const HEIGHT: usize = 1080;
    fn duration(&self) -> Duration<'_> { Duration::Auto }            // somme des scènes
    fn audio(&self) -> AudioMap<'_> { AudioMap::none() }              // voir references/audio.md
    fn define_scenes(&self) -> Scenes<'_> { Scenes::from(vec![&self.intro as &dyn Scene, &self.main]) }
    fn render_frame<'a>(&'a self, frame: Frame, ctx: &FFramesContext<'a, '_>) -> Svgr<'a> {
        fframes::svgr!(<svg xmlns="http://www.w3.org/2000/svg" width={Self::WIDTH} height={Self::HEIGHT}>
            <rect width={Self::WIDTH} height={Self::HEIGHT} fill={BACKGROUND} />
            {ctx.render_scenes(&frame)}
        </svg>)
    }
}
  • Une scène par idée, 2 à 6 s chacune. Dans une scène, frame.seconds() compte à partir du début de la scène.
  • Par défaut, utilisez frame.animate(fframes::timeline!(...)) directement dans les attributs svgr! pour les mouvements avec des valeurs fixes. svgr! élève ces animations dans des statics mis en cache. Définissez les easings en ligne dans la timeline, y compris Easing::Spring { mass: 1.0, stiffness: 180.0, damping: 20.0 } ; les constantes d'easing nommées sont facultatives. Laissez l'heure de fin d'un ressort vide pour qu'il

…

Skills associés