Communitygithub.com

muneebsajjad/demo-reel

Créez une vidéo de démonstration soignée de votre produit en enregistrant l'application réelle dans un navigateur, puis en ajoutant un cadre, des sous-titres et en effectuant le rendu — de bout en bout, sans éditeur vidéo. Idéal pour les démos, les lancements, les vidéos de fonctionnalités ou les enregistrements d'écran à rendre présentables.

Qu'est-ce que demo-reel ?

demo-reel est un outil en ligne de commande pour macOS qui permet de produire des vidéos de démonstration professionnelles de produits web, sans aucune édition vidéo manuelle. L'outil enregistre en direct le produit réel dans un navigateur, puis ajoute automatiquement un cadre de fenêtre, des déplacements de caméra, des sous-titres et des cartes de titre/fin. Le pipeline se déroule en huit étapes : storyboard, scénario, prise, montage, vérification des images, sous-titres, rendu et contrôle qualité. Il prend en charge les formats 4:5, 1:1, 9:16 et 16:9, et propose une sélection musicale automatique basée sur le profil de la vidéo. Le résultat est une vidéo MP4 prête à être publiée sur LinkedIn, X, une page de lancement ou un listing de boutique. L'enregistrement nécessite macOS (ScreenCaptureKit), tandis que le compositing et le rendu fonctionnent sur toutes les plateformes.

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add muneebsajjad/demo-reel

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 demo-reel ?

Vous produisez la vidéo entière vous-même : la personne vous donne le produit et ce qu'il faut montrer, et reçoit en retour un MP4 qu'elle peut publier. Tout ce qui est à l'écran est le produit réel, enregistré en direct ; le polissage (cadre de fenêtre, mouvements de caméra, sous-titres, cartes de titre et de fin) est ajouté après coup à partir de l'enregistrement.

Le pipeline, et le fichier que chaque étape produit :

ÉtapeCommandeProduit
1. Storyboardvous, avec la personne3–5 fonctionnalités, un sous-titre chacune
2. Scénarioécrire scenario.mjsles étapes qu'un utilisateur suivrait
3. Prisebin/reel take scenario.mjs takes/take1take1.mov (image + son de l'application), take1.json (événements, positions des éléments)
4. Montageécrire edit.jsonscènes, plans, sous-titres, marque
5. Images fixesbin/reel check edit.json, bin/reel layers edit.json, puis bin/reel stills edit.json 1,4,9problèmes détectés tôt ; images de prévisualisation
6. Sous-titresbin/reel subtitles edit.json, puis lire et corriger build/subtitles.srtce qui est dit, sous forme de sous-titres
7. Rendubin/reel render edit.json renders/x.mp4 --format allla vidéo dans chaque format, avec son .srt
8. Vérificationbin/reel sheet renders/x.mp4 1,4,9,…planche contact, durée, volume sonore

examples/sawt/ est un exemple complet (une extension Chrome qui lit les articles à voix haute). Ouvrez son scenario.mjs et edit.json avant d'écrire les vôtres. docs/edit-format.md est la référence du fichier de montage ; docs/lessons.md liste ce qui a mal fonctionné la première fois, alors lisez-le avant d'enregistrer.

0. Configuration (une fois)

Exécutez bin/reel doctor d'abord : il vérifie chaque outil et permission et indique quoi corriger. bin/reel setup construit l'enregistreur (Swift, ScreenCaptureKit), installe playwright-core et Chrome pour les tests. Également nécessaires : ffmpeg, uv, Google Chrome (pour le rendu des calques de superposition). Le terminal qui vous exécute a besoin de l'autorisation d'enregistrement de l'écran et de l'audio système (Réglages Système → Confidentialité & Sécurité) ; si l'enregistreur signale qu'il n'est pas autorisé, demandez à la personne de l'accorder et de redémarrer le terminal.

1. Storyboard

Convenez, en quelques lignes, avant d'enregistrer quoi que ce soit :

  • les fonctionnalités, dans l'ordre, chacune avec un sous-titre : un court accroche ("Zoom mot") et un titre d'au maximum deux lignes courtes, avec le bénéfice en <b> ("Suivez le fil. Chaque motgrossit lorsqu'il est prononcé.");
  • quel contenu réel utiliser pour la démo : une page publique, un compte échantillon, des données préremplies. Choisissez un contenu qui met la fonctionnalité en valeur et vérifiez-le (pour Sawt : un article dont les mots difficiles ont des fiches, sur un site où les fiches ont de la place à côté de la colonne);
  • la marque : couleur d'accent, une variante claire, teintes d'arrière-plan, logo ; texte de la carte de titre et de fin.

Format par défaut : 1080×1350 (4:5), 25–35 s — il remplit le mieux un flux de téléphone, et la plupart des gens regardent sans le son, donc les sous-titres doivent raconter l'histoire par eux-mêmes. Demandez où la vidéo sera publiée : 1:1, 9:16 et 16:9 proviennent du même montage (--format), alors proposez-les. Vérifiez les images fixes de chaque format rendu : un plan qui cadre bien en 4:5 peut couper un titre en 1:1 ; ajustez-le par format ("1:1": {"dy": 20}).

Lorsque le produit parle (ou que la prise a une narration), créez des sous-titres : reel subtitles, puis lisez le .srt et corrigez les noms et le jargon avant le rendu — la transcription est bonne, pas parfaite. Mettez les mots difficiles dans subtitles.words pour la guider.

2. Scénario

Un scénario est un module ES (voir drive/take.mjs pour l'API complète) :

export const config = { url: "https://…", width: 1700, height: 1090, extension: "./ext" };
export async function setup(api) { /* réglages, connexion ; api.rect("titre", "h1") pour les cibles de caméra */ }
export async function run(api)   { /* la démo ; api.mark("étape") à chaque moment où vous couperez */ }
export async function after(api) { /* images fixes à montrer comme scènes image, p. ex. une popup à 3x */ }
  • Marquez chaque moment où vous couperez ou déplacerez la caméra (api.mark("phrase", {n})). Le montage s'ancre sur ces marques, donc une prise plus rapide ou plus lente coupe toujours au bon endroit.
  • Enregistrez les cibles de caméra avec api.rect(nom, sélecteur | fn, arg) en pixels de la fenêtre. Les éléments dans une racine ombre fermée ne peuvent pas être mesurés : calculez où ils seront (voir les fiches Sawt).
  • Les produits pilotés par clic ont besoin d'un pointeur visible. L'automatisation ne déplace aucun curseur réel, donc les formes apparaissent et les boutons s'activent tout seuls. Appelez api.pointer.show() dans setup, puis pilotez avec api.pointer.click(sélecteur | [x, y]), .drag(de, vers), .move(x, y), .type(texte) et .key(k) : une flèche sur la page suit, les clics ondulent, les mouvements sont progressifs et la frappe a un rythme humain. Contrôlez les clics par sélecteur (un title ou aria-label est généralement stable) afin que leurs positions viennent de la page.
  • Contenu Canvas (dessins, graphiques, cartes) n'a pas d'élément à mesurer : enregistrez la boîte dans laquelle vous avez dessiné avec api.rect(nom, {x, y, width, height}) en px CSS.
  • Extensions Chrome : exécutez les actions via le code propre de l'extension avec api.inWorker(fn). Une extension qui dépend de activeTab a besoin d'une copie d'enregistrement avec accès hôte, car l'automatisation ne peut pas utiliser les raccourcis du navigateur (voir examples/sawt/prepare.sh). Ne modifiez rien qu'un spectateur voit.
  • Popups et autres petites UI : capturez-les dans after() à un facteur d'échelle de l'appareil de 3 avec CDP (voir l'exemple), et montrez-les comme une scène image. Capturez les deux états d'un interrupteur au même moment en cliquant sur la commande réelle, pas en rechargeant.

Exécutez-le, puis regardez la prise avant le montage : ffmpeg -ss 6 -i takes/take1.mov -frames:v 1 x.png et lisez le PNG. Vérifiez que la page est stylée, que la fonctionnalité s'est déclenchée, que rien ne la cache. Refaites la prise librement — une prise coûte une minute.

3. Montage

Écrivez edit.json (référence : docs/edit-format.md). Règles pour qu'il ait l'air fabriqué, pas enregistré :

  • Coupez dans les pauses. bin/reel speech take1.mov liste où il y a du son ; les morceaux commencent juste avant une étape et se terminent avant que la suivante ne commence. Ancrez-les à des marques : "phrase#5-0.15".
  • Le contenu côte à côte ne tient pas dans les fenêtres hautes. Une barre d'outils à gauche et un diagramme à droite peuvent nécessiter plus de largeur qu'une fenêtre 4:5 n'en montre ; reel check avertit, par format, de combien un plan ajusté sera rogné. Affichez moins de choses, ou ajustez le plan pour ce format.
  • Plans à partir de rectangles. {"fit": ["titre", {"rect": "carte1", "dh": 330}], "pad": 60}. Un plan large d'établissement, puis un zoom sur ce dont parle le sous-titre. Gardez le texte d'au moins ~20 px de haut dans la sortie ; un plan large peut devenir plus petit un instant, jamais longtemps.
  • Un sous-titre par scène, présent pendant toute la scène ; changez de sous-titre uniquement lors d'un mouvement de caméra.
  • Laissez les mouvements respirer : 1,0–1,5 s par mouvement de caméra, maintenez au moins 1,5 s après l'arrivée.
  • Carte de titre 2–2,5 s, carte de fin 3–3,5 s. Scènes image (popup, panneau de réglages) 3–4 s.

Vitesse

Un rendu 4:5 de 30 secondes prend environ 3 minutes sur un ordinateur portable 6 cœurs : les images sont rendues en parallèle par morceaux (4 par défaut ; --jobs N), assemblés sans ré-encodage, et les calques inchangés sont réutilisés. Pendant que le montage évolue encore, utilisez reel render … --draft (15 ips, encodeur rapide, environ la moitié du temps) et reel stills ; lancez le vrai rendu une fois que les images fixes sont correctes.

4. Vérification, à chaque fois

  1. bin/reel layers et bin/reel stills au début, au milieu et à la fin de chaque scène et à chaque mouvement de caméra. Lisez chaque PNG. Cherchez : texte ou UI coupé au bord du cadre, titre à moitié visible en haut, sous-titre sur quelque chose d'important, cadre complètement vide.
  2. Rendu, puis bin/reel sheet sur toute la vidéo et lisez-la.
  3. La durée doit correspondre à ce que vous avez prévu ; le volume sonore environ −16 LUFS lorsque le produit émet du son.
  4. Synchronisation : le moment où une étape apparaît à l'écran et où son son commence doit correspondre à la prise.

Ensuite, mettez le MP4 sous les yeux de la personne, avec la vignette (build/layers/title.png), et dites clairement ce qui est réel et ce qui a été modifié pour l'enregistrement.

Musique

Par défaut, le système choisit un fond sonore adapté à la vidéo (docs/music.md) : il profile la vidéo (durée, parole, rythme, mots des sous-titres), classe les candidats instrumentaux sous licence — le dossier music/ de la personne, puis la bibliothèque CC0 incluse (library/), puis en ligne seulement si rien de local ne convient — par tempo mesuré, énergie et stabilité, et garde le meilleur. Exécutez reel music auto edit.json --audition renders/x.mp4 pour voir le classement et obtenir un aperçu des meilleurs morceaux. Vous ne pouvez pas entendre, alors donnez les aperçus à la personne avant de déclarer la vidéo terminée. Lorsque les meilleurs morceaux sont uniquement accessibles par lien (le site bloque les téléchargements scriptés), donnez les liens à la personne ; elle en télécharge un et exécute reel music add <fichier> --candidate N. S'ils apportent leur propre morceau, enregistrez sa licence avec reel music add et placez-le dans le montage. Donnez-leur toujours le .credits.txt à côté du rendu, et dites quand sa licence nécessite un crédit publié.

Limites

  • L'enregistrement est uniquement macOS (ScreenCaptureKit). Le compositing et les calques fonctionnent partout.
  • Produits navigateur seulement pour l'instant ; une application de bureau a besoin de son propre pilote (scripting d'accessibilité), mais l'enregistreur (--app <id bundle>) et tout ce qui suit fonctionnent déjà pour n'importe quelle application.
  • La génération de musique (reel music generate) nécessite un modèle local câblé ; ACE-Step est suggéré mais pas encore testé avec demo-reel.

Skills associés