Que fait framevelo ?
FrameVelo transforme une page qui dessine ses images à partir de code en un fichier MP4. Les images restent sur le GPU (drawElementImage ou le canvas de la page) et partent directement vers l'encodeur matériel, ce qui permet un rendu utilisant une fraction du CPU et de la mémoire des rendus par capture d'écran. Les projets HyperFrames sont compilés par le pipeline officiel HyperFrames ; FrameVelo ne remplace que la capture et l'encodage.
Appel
Utilisez les outils MCP de ce plugin lorsqu'ils sont disponibles. Au tout premier démarrage, le plugin installe FrameVelo dans ~/.cache/framevelo (environ une minute) ; si les outils sont absents juste après l'installation du plugin, attendez et reconnectez-vous (/mcp), ou utilisez la CLI ci-dessous.
render: effectue le rendu ; renvoie le chemin de sortie, le nombre d'images, la taille, les timings, les avertissements et les dernières lignes de log.doctor: vérifie Node, FFmpeg, Chrome,drawElementImage, les encodeurs matériels et la prise en charge HyperFrames.install_browser: télécharge chrome-headless-shell (environ 100 Mo) lorsqu'aucun Chrome 151+ n'est installé.
Sans les outils, utilisez la CLI. --json affiche le résultat (ou {"error": ...}) sur stdout :
npx -y -p github:gnipbao/framevelo -p @hyperframes/[email protected] -p @hyperframes/[email protected] framevelo render /abs/project -o /abs/out.mp4 --json -q
La première exécution de npx installe pendant environ trente secondes. Si vous effectuez des rendus fréquents, suggérez à l'utilisateur de l'installer une fois pour toutes : npm install -g github:gnipbao/framevelo @hyperframes/[email protected] @hyperframes/[email protected]. La CLI accepte les mêmes options que l'outil, sous forme de flags (--frames 30 --quality draft). framevelo render --help les liste.
Utilisez des chemins absolus. Lancez un rendu à la fois : ils partagent l'unique encodeur matériel, et le serveur MCP les met de toute façon en file d'attente.
Flux de travail
- Trouver l'entrée : un répertoire de projet avec
index.html, ou un fichier.html. La durée, les fps et la taille proviennent de la page (HyperFramesdata-duration/data-fps/data-width,window.__framevelo.duration, la longueur de la timeline GSAP,window.__comp). Ne les transmettez que pour les surcharger. - Prévisualiser une tranche lorsque la composition est nouvelle ou vient d'être modifiée :
{ input, output: "/tmp/preview.mp4", start: 2, frames: 30, quality: "draft" }. Cela prend quelques secondes. Regardez une image :ffmpeg -v error -ss 0.5 -i /tmp/preview.mp4 -frames:v 1 /tmp/preview.png, puis visualisez le PNG. - Effectuer le rendu complet avec les valeurs par défaut. Ajoutez
scale: 2pour du 4K à partir d'une mise en page 1080p, ousubframes: 3pour du flou de mouvement. - Vérifier le résultat :
framescorrespond au nombre attendu ;audioest vrai lorsque la composition contient du son ; lisezwarnings.screenshotFrames > 0signifie que certains intervalles ont échoué à la vérification et ont été capturés par capture d'écran (toujours correct, mais plus lent). - Signaler le chemin de sortie, la durée, la taille et le temps pris (
wallMs).
Rendre une page rendable
Chaque image doit être une fonction pure du temps. FrameVelo parcourt la page via la première de ces méthodes qu'il trouve :
window.__framevelo = { seek(t), duration, fps }.seekpeut retourner une promesse.window.__seek(t), avec unwindow.__durationoptionnel.- Une timeline GSAP en pause sur
window.__timelines.main(ou la première clé).
<canvas id="scene" width="1920" height="1080"></canvas>
<script>
const g = document.getElementById("scene").getContext("2d");
function draw(t) {
g.fillStyle = "#05060a";
g.fillRect(0, 0, 1920, 1080);
g.fillStyle = "#6cf";
g.fillRect(200 + 300 * t, 500, 120, 120);
}
window.__framevelo = { duration: 4, seek: draw };
</script>
- Placez les séquences vidéo sur la timeline avec
<video data-start="1.5" src="clip.mp4">(optionnellementdata-media-start,data-duration,data-playback-rate). FrameVelo la positionne exactement sur l'image souhaitée ; les sources à longs GOP bénéficient d'un proxy tout-intra mis en cache. Math.randomest ensemencé, donc les rendus sont reproductibles.- Les boucles
requestAnimationFrame, les transitions CSS, les animations basées surDate.now()etperformance.now()ne peuvent pas être parcourues. Déplacez-les surseek(t)ou une timeline GSAP en pause. - Attendez les ressources (polices, images) à l'intérieur de la page avant d'exposer le pilote, ou retournez une promesse depuis
seek.
Options à connaître
| Besoin | Arguments |
|---|---|
| Vérification rapide | frames: 30, quality: "draft", start: <s> |
| 4K à partir d'une mise en page 1080p | scale: 2 |
| Page verticale sans taille déclarée | viewport: "1080x1920" |
| Fichiers plus petits | codec: "hevc" |
| Flou de mouvement | subframes: 3 (et shutter, par défaut 0.5) |
| Remplacer la bande sonore | audio: "/abs/music.m4a" |
| Capturer un élément | selector: "#stage" |
| DOM transparent sur une couleur | background: "#000" |
| Compétence code-video introuvable | mounts: {"/@skill/": "/abs/path/to/code-video"} |
| Projet HyperFrames comme page simple | hyperframes: false |
En cas d'échec
| Message | Action |
|---|---|
Chrome not found | Appelez install_browser (ou exécutez framevelo browser install), puis relancez le rendu. |
FFmpeg / FFprobe échoue dans doctor | Demandez à l'utilisateur d'installer FFmpeg (brew install ffmpeg). N'installez pas de logiciel système vous-même. |
The page exposes no way to seek time | La page a besoin d'un pilote temporel ; voir "Rendre une page rendable". |
Unknown duration | Transmettez duration ou frames, ou déclarez la durée dans la page. |
The composition failed to set up | Une erreur de script dans la composition. Corrigez la page ; le message contient l'erreur de la page. |
No element matches selector / Nothing to capture / has no size | Pointez selector vers un élément visible avec une taille, ou corrigez la mise en page. |
Rendering a HyperFrames project needs ... @hyperframes/producer | Utilisez la commande npx -p @hyperframes/... ci-dessus, ou installez les paquets à côté de FrameVelo. |
No paint event within ... | La page a cessé de peindre ; généralement un script bloqué. Vérifiez-la dans un navigateur. |
Les rendus sont atomiques : un rendu échoué ou annulé ne laisse aucun fichier de sortie.