Auto-Loom
Transformez n'importe quelle application web en un MP4 narré et auto-piloté. La page défile, surligne des éléments et navigue entre les routes pendant qu'une voix IA narre — synchronisée à la milliseconde près. Fini les captures d'écran manuelles, fini les prises Loom ratées. Modifiez une ligne de narration et regénérez en quelques minutes.
Comment ça marche : ElevenLabs génère un clip audio par séquence du storyboard.
ffprobe mesure la durée exacte de chaque clip. Playwright pilote le navigateur
pendant exactement cette durée par séquence tout en enregistrant la fenêtre. ffmpeg assemble le
MP4 final avec une piste de sous-titres. La durée audio est la référence — les visuels
sont asservis à celle-ci, donc la synchronisation est parfaite.
Ce dossier contient tout le moteur. Les compétences sœurs sont de simples points d'entrée vers ces mêmes scripts :
- auto-loom-proof — Vidéo de validation d'une Software Factory : exécute les critères d'acceptation d'un build devant la caméra, un critère par séquence
Ce SKILL.md couvre le moteur ainsi que le mode développeur : vous avez le codebase, l'application tourne sur localhost, et vous pouvez ajouter des sélecteurs stables dans le JSX.
Configuration (unique, ~3 minutes)
cd <dossier-de-la-compétence>
bash scripts/setup.sh # installe Playwright + Chromium, crée .env.local
# éditez .env.local → ajoutez votre clé API ElevenLabs
node scripts/doctor.mjs # vérifie node, ffmpeg, playwright, la clé, la voix
Pas encore de compte ElevenLabs ? Inscrivez-vous avec le lien de parrainage du mainteneur : https://try.elevenlabs.io/atherial.
doctor.mjs affiche la correction exacte pour tout élément manquant. Prérequis : Node 18+,
ffmpeg (brew install ffmpeg), une clé API ElevenLabs. Options vocales :
references/voices.md.
Test de fumée (30 secondes, enregistre example.com) :
node scripts/run.mjs --beats examples/smoke-beats.json
Étape 0 — Interviewez d'abord l'utilisateur
Ne commencez pas à construire. Demandez :
1. Quelle URL ou application enregistrons-nous ? Tourne-t-elle en local ?
2. Qui est le destinataire — nom et contexte ?
3. Quelle est l'histoire ? Qu'est-ce qui a changé, ou que montrons-nous pour la première fois ?
4. Quelles fonctionnalités, métriques ou sections spécifiques devons-nous mettre en avant ?
5. Quel est le ton ? (mise à jour client, démo interne, présentation prospect)
6. L'application nécessite-t-elle une connexion ? (voir references/auth.md — ne demandez jamais de mots de passe dans le chat)
7. Durée cible — 30s, 60s ou 75s ?
En cas d'urgence : demandez 1 à 3 et déduisez le reste de l'application.
Étape 1 — Écrivez le storyboard (beats.json)
Écrivez la narration avant de toucher au code et faites-la approuver textuellement.
Règles d'écriture et cadrage des séquences : references/tts-rules.md.
{
"meta": {
"title": "Visite guidée du tableau de bord Acme",
"slug": "acme-visite-guidee",
"cta": "Envoyez-moi vos retours et nous passerons à la phase suivante.",
"targetLengthSec": 70
},
"baseUrl": "http://localhost:3000",
"viewport": { "width": 1920, "height": 1080 },
"beats": [
{
"id": 1,
"page": "/dashboard/insights",
"text": "Salut Jim. Nous avons livré quelques mises à jour de votre suivi de visibilité A-I.",
"actions": [
{ "fn": "waitFor", "sel": "[data-vn=kpi-row]" },
{ "fn": "scrollToEl", "sel": "[data-vn=kpi-row]", "opts": { "instant": true } },
{ "fn": "hl", "sel": "[data-vn=kpi-row]" }
]
}
]
}
Schéma complet : schema/beats.schema.json. Tableau des actions et guide des sélecteurs :
references/actions.md. Options de connexion (étapes scriptées ou session sauvegardée) :
references/auth.md.
Vérifiez avant de dépenser quoi que ce soit :
node scripts/validate.mjs --beats <fichier> # structure + TTS + lint du rythme
node scripts/run.mjs --beats <fichier> --script-only # affiche la narration et s'arrête
Le validateur détecte les actions inconnues, les sélecteurs manquants, les problèmes de TTS (tirets cadratins, sigles non développés, phrases trop longues) et un rythme qui ne tiendrait pas dans la durée cible.
--script-only est la porte de révision qui économise de l'argent : il affiche la narration de
chaque séquence avec des estimations de durée par séquence et se termine avant tout appel ElevenLabs
ou tout enregistrement. Faites approuver le script ici, puis relancez sans le
flag pour dépenser des crédits.
Étape 2 — Instrumentez la page (mode développeur)
Playwright a besoin de sélecteurs stables. Avec l'accès au codebase, ajoutez des attributs data-vn
dans le JSX des composants :
<div data-vn="kpi-row" className="grid grid-cols-4 gap-4">
<Card data-vn="competitor-chart" ...>
Référencez-les ensuite : { "fn": "hl", "sel": "[data-vn=kpi-row]" }.
Supprimez les interactions profondes pendant l'enregistrement. Les cartes cliquables avec
role="button" / tabIndex={0} peuvent recevoir le focus automatiquement lors des surlignages et
ouvrir un tiroir en cours de vidéo. Conditionnez-les avec votre flag de mode démo :
{!isDemoMode() && <MetricBreakdownSheet ... />}.
Si l'application nécessite une authentification en local, soit mettez en place un mode démo (ignore
auth, données fictives correspondant exactement aux chiffres de la narration), soit utilisez un
chemin d'auth depuis references/auth.md.
Note sur la CSP : l'enregistreur lance Chromium avec bypassCSP: true pour
pouvoir injecter presenter.js dans les pages à CSP stricte. Si vous pointez vers une
application de production avec une session active, sachez que la Content-Security-Policy est
désactivée dans ce contexte de navigateur automatisé.
Étape 3 — Une seule commande
node scripts/run.mjs --beats <fichier>
Ceci exécute : validation → audio (mis en cache par hash du texte) → preflight (passage sans tête
qui résout chaque sélecteur avant tout enregistrement) → enregistrement → sous-titres → assemblage
→ vérification. La sortie atterrit dans demo-video-out/<slug>/ :
<slug>-demo.mp4— vidéo finale (H.264/AAC, piste de sous-titres souple)<slug>-demo-contact-sheet.png— images échantillonnées pour inspectionqa/beat-NN.png— capture d'écran exacte au point d'arrêt de chaque séquencecaptions.srt,audio/,video/recording.webm
Tous les flags : --script-only (affiche le script de narration et se termine avant tout appel
ElevenLabs ou enregistrement — la porte de révision de l'Étape 1),
--preflight-only (vérifie les sélecteurs, ne dépense rien), --skip-audio
(changements purement visuels — l'audio est réutilisé), --skip-preflight (saute la vérification
des sélecteurs sans tête — seulement quand le preflight vient de passer et que rien n'a changé),
--burn-captions (grave les sous-titres dans les pixels pour les plateformes qui suppriment les
pistes), --no-captions, --out <dossier>, --env <fichier_env>.
Étape 4 — Vérifiez avant d'envoyer
run.mjs vérifie la durée (MP4 = somme des audios à 0,5s près), le niveau audio (détection de piste
silencieuse) et dépose les captures de contrôle. Vous inspectez quand même :
- La planche contact +
qa/beat-NN.png: chaque image montre ce que sa séquence narre — pas de pages de connexion, d'états d'erreur ou de modales surprises. - La première séquence nomme le destinataire ; la dernière séquence délivre l'appel à l'action textuellement.
Itérations
- Modification de la narration → relancez ; seule l'audio de la séquence modifiée est regénérée.
- Modification visuelle/rythme →
--skip-audio. - Sélecteur cassé →
--preflight-onlymontre exactement quelle séquence et quel sélecteur.
Pièges connus
- Le rechargement à chaud efface le script injecté. Déjà géré — le script se réinjecte avant chaque séquence. Mais évitez de modifier l'application pendant l'enregistrement.
- Dérive de port.
yarn devprend le port 3001 si 3000 est occupé — mettez à jourbaseUrl. - Voix gratuites vs payantes. Les voix clonées/bibliothèque renvoient
payment_requiredsur le palier gratuit.doctor.mjsdétecte cela avant le rendu. - Redirections i18n.
/en/dashboard→/dashboardles redirections sont suivies correctement ; les séquences sur la même page ne re-naviguent pas. - Livraison. Le MP4 est autonome — email, Slack, LinkedIn DM, embed Notion, ou import dans Descript pour une intro personnelle par-dessus.