Générer une vidéo à partir de code
Créer, animer et rendre une vidéo avec Remotion, en raisonnant en images plutôt qu'en secondes.
Il y a une catégorie de vidéos qu'on refait sans arrêt et qui n'a rien de créatif : le rapport mensuel animé, la carte de résultats à décliner en trente exemplaires, la démonstration de produit qu'il faut reprendre à chaque changement d'interface. Dans un logiciel de montage, chacune de ces versions coûte une manipulation à la main. Un chiffre change, on rouvre le projet, on repositionne, on réexporte.
Décrire la vidéo en code renverse le rapport. La composition devient un programme, les données deviennent des paramètres, et produire trente variantes revient à lancer trente rendus. C'est la même bascule que passer d'un document mis en page à la main à un modèle qu'on remplit.
Ce guide utilise Remotion, qui décrit une vidéo avec des composants React. Toutes les commandes ci-dessous viennent de sa documentation. Le raisonnement, lui, vaut pour n'importe quel outil de rendu programmatique.
Avant de commencer
- Node.js installé, et un minimum de familiarité avec React
- Une vidéo réellement répétitive à produire, sinon un éditeur classique ira plus vite
- De quoi lire la licence avant de démarrer, voir l'avertissement plus bas
Remotion n'est pas sous licence libre classique
Sa licence prévoit une utilisation gratuite pour les particuliers, les organisations à but non lucratif et les entreprises à but lucratif jusqu'à trois salariés. Au-delà, une licence d'entreprise est requise. Vérifie ce point avant d'engager un projet en équipe : c'est le genre de détail qui se découvre mal trois mois plus tard.
1Décider si le code est le bon outil
Le rendu programmatique gagne sur trois terrains, et perd partout ailleurs.
- La répétition paramétrée. Une même vidéo déclinée par client, par ville, par produit. Un jeu de données, une boucle, un fichier par ligne.
- Le contenu qui change. Un chiffre issu d'une base, un texte relu par quelqu'un d'autre. Tu régénères au lieu de rééditer.
- Le versionnage. La vidéo vit dans le dépôt, les modifications se lisent dans un diff, on revient en arrière.
À l'inverse, si tu produis une vidéo unique, avec des choix de montage au jugé et des rushes filmés, un éditeur classique restera plus rapide. Écrire du code pour placer une coupe est un mauvais échange.
2Créer le projet et ouvrir le studio
La commande d'initialisation lance une interface interactive qui te fait choisir un modèle de départ :
npx create-video@latest
Pour éviter les questions, il existe un mode non interactif, qui exige un
indicateur de modèle et un nom de dossier. Les modèles disponibles incluent
--blank, --hello-world, --next, --next-pages-dir, --vercel et
--recorder :
npx create-video --yes --blank --no-tailwind ma-video
Une fois dans le dossier, le studio se lance avec :
npx remotion studio
Il ouvre un aperçu avec une réglette de lecture. Le point important : cet aperçu n'est pas un export, c'est ta composition jouée dans un navigateur. Ce que tu vois est ce qui sera rendu image par image.
3Raisonner en images, pas en secondes
C'est le changement de repère qui fait toute la différence, et celui que les agents ratent le plus souvent quand ils écrivent ce genre de code.
Une composition, dans Remotion, est la combinaison d'un composant React et de
métadonnées vidéo : une largeur en pixels, une hauteur en pixels, une cadence
fps et une durée durationInFrames exprimée en nombre d'images.
Tout le temps se compte donc en images. À 30 images par seconde, deux secondes
valent 60 images. Le hook useCurrentFrame() te donne le numéro de l'image en
cours de rendu, et ton composant doit répondre à une seule question : à quoi
ressemble l'écran à cette image précise.
Ne demande jamais une durée en secondes
Quand tu fais écrire une animation par un agent, donne-lui la cadence et exprime les durées en images. « Un fondu de 15 images à 30 fps » ne laisse aucune ambiguïté, « un fondu d'une demi-seconde » sera traduit au petit bonheur.
4Animer avec interpolate
L'animation se réduit à une transformation : à partir du numéro d'image,
calculer une valeur. La fonction interpolate prend quatre arguments, le
dernier étant facultatif : la valeur d'entrée, la plage d'entrée, la plage de
sortie et un objet d'options.
import {interpolate, useCurrentFrame} from 'remotion';
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 20], [0, 1]);
Ici, l'opacité passe de 0 à 1 entre l'image 0 et l'image 20, et vaut 0,5 à l'image 10.
Deux options méritent d'être connues tout de suite. extrapolateLeft et
extrapolateRight décident de ce qui se passe hors de la plage d'entrée. Leur
valeur par défaut est 'extend', ce qui veut dire que la valeur continue de
croître au-delà de l'image 20. C'est presque jamais ce que tu veux pour une
opacité : passe-les à 'clamp' pour bloquer aux bornes. L'option easing
permet de remplacer la progression linéaire par une courbe.
5Rendre en ligne de commande
Le rendu se fait hors du studio, et c'est ce qui rend l'automatisation possible. La commande prend l'identifiant de la composition et le fichier de sortie :
npx remotion render <composition-id> out/video.mp4
Le point d'entrée peut être passé en premier argument, sinon il est déterminé automatiquement. Quelques options utiles :
| Option | Ce qu'elle fait |
|---|---|
--codec | h264 par défaut. Accepte aussi h265, av1, vp8, vp9, prores, png, et des sorties audio seules comme mp3, aac, wav |
--props | Les paramètres passés à la composition, pour produire des variantes |
--scale | Multiplie la taille des images rendues. Supérieur à 0 et au plus 16, valeur par défaut 1 |
--concurrency | Le nombre de rendus menés en parallèle |
--frames | Rend des images précises, par exemple --frames=0,30,60, sous forme de séquence d'images |
Sous Windows, ne passe pas les props en JSON direct
La documentation signale que le JSON en ligne n'est pas pris en charge par les
interpréteurs Windows, parce qu'ils suppriment les guillemets. Écris tes
paramètres dans un fichier et passe son nom à --props. C'est de toute façon
la bonne pratique dès que tu déclines une vidéo à partir d'un jeu de données.
La production en série découle directement de là : un fichier de paramètres par
variante, une boucle qui appelle render pour chacun, un fichier de sortie
nommé d'après la ligne.
Quelques prompts pour aller plus loin
| Objectif | Prompt à adapter |
|---|---|
| Démarrer une composition | Ecris une composition Remotion de [LARGEUR]x[HAUTEUR] a [FPS] fps, d'une duree de [N] images, qui affiche [CONTENU]. Exprime toutes les durees en images. |
| Animation d'entrée | Ajoute un fondu et une translation verticale sur [ELEMENT], entre l'image [A] et l'image [B], avec extrapolateLeft et extrapolateRight a clamp. |
| Paramétrer | Rends cette composition parametrable : liste les props necessaires, avec leur type, et montre le fichier JSON a passer a --props. |
| Série de variantes | Ecris un script qui lit [FICHIER DE DONNEES] et lance un rendu Remotion par ligne, avec un fichier de sortie nomme d'apres la colonne [COLONNE]. |
| Vérifier le temps | Relis ce code et signale chaque endroit ou une duree est exprimee en secondes plutot qu'en images. |
| Sous-titres | A partir de ce texte et de cette cadence, calcule les intervalles en images pour afficher chaque phrase, et rends-moi le tableau. |
Tu as d’autres ressources comme ça ?
Ce que tu viens de lire est entièrement gratuit. Une nouvelle ressource part chaque semaine dans la newsletter : guides, modèles à copier et liens triés, sans compte à créer.
Me contacter
Une question, un projet, une envie de collaborer ? Écris-moi.
Cette page est en accès libre, n’hésite pas à la partager.