Producteur Automatique de Démo
Produisez automatiquement des démos vidéo professionnelles narrées de N'IMPORTE QUELLE application web.
Aperçu du Pipeline
Contexte utilisateur → Script de démo → Diapositives → Narration TTS → Enregistrement navigateur → MP4 final
Trois phases, entièrement automatisées :
- Narration — edge-tts (Microsoft Neural TTS gratuit) génère l'audio par scène
- Enregistrement — Playwright pilote Chromium headless avec capture vidéo
- Assemblage — ffmpeg fusionne la vidéo et l'audio en un MP4 soigné
Quand Activer
- L'utilisateur demande de « créer une démo », « enregistrer un parcours commenté », « faire une vidéo de démo »
- L'utilisateur fournit une URL + une description de ce qu'il faut montrer
- L'utilisateur souhaite un screencast automatisé avec voix off
Flux de Travail Étape par Étape
Étape 1 : Recueillir le Contexte
Demandez à l'utilisateur :
- URL cible — l'application web à démontrer (ex.
https://myapp.azurewebsites.net) - Ce qu'il faut montrer — fonctionnalités clés, parcours utilisateur ou scénarios
- Public — qui va regarder ? (dirigeants, développeurs, clients)
- Durée cible — combien de temps doit durer la démo ? (1 à 5 min typique)
- Préférence vocale — langue et genre (par défaut :
en-US-JennyNeural) - Marque — nom du produit, sous-titre, organisation, couleur d'accent pour l'intro/outro
Étape 2 : Créer le Script de Démo
Générez un fichier demo_script.md en utilisant ce format :
# Démo : {Nom du Produit}
## intro | 5
> slide intro
Bienvenue dans cette démo du Nom du Produit. Aujourd'hui, nous allons parcourir les fonctionnalités clés.
## login | 8
> goto {base_url}
> fill Utilisateur [email protected]
> fill Mot de passe ****
> click button Connexion
Nous nous connectons à l'application avec nos identifiants de démonstration.
## tableau_de_bord | 10
> wait 2
> scroll down 300
Le tableau de bord offre une vue d'ensemble en temps réel de tous les éléments actifs.
## fonctionnalite_un | 12
> click link Fonctionnalité Un
> wait 1
> scroll down 200
Explorons la fonctionnalité Un, qui vous permet de créer et gérer des flux de travail.
## outro | 5
> slide outro
Merci d'avoir regardé ! Rendez-vous sur contoso.com pour plus d'informations.
Règles de format du script :
## scene_id | duree_minimale_secondes— en-tête de scène> action args...— actions Playwright (voir le répertoire des actions ci-dessous)- Les lignes de texte brut = narration (prononcée par la voix TTS)
- La narration détermine la durée réelle de la scène (ajustée pour correspondre à la longueur audio)
Étape 3 : Générer les Diapositives
Exécutez le générateur de diapositives pour créer les fichiers HTML d'intro/outro :
python generate_slides.py `
--title "Nom du Produit" `
--subtitle "Votre slogan ici" `
--org "Contoso" `
--badge "Propulsé par Azure" `
--accent "#60a5fa" `
--out-dir ./slides
Étape 4 : Installer les Dépendances
pip install edge-tts playwright
playwright install chromium
# Assurez-vous que ffmpeg est disponible :
# Windows : winget install Gyan.FFmpeg
# macOS : brew install ffmpeg
# Linux : sudo apt install ffmpeg
Étape 5 : Exécuter l'Enregistreur
python record_demo.py `
--script demo_script.md `
--base-url "https://myapp.azurewebsites.net" `
--voice en-US-JennyNeural `
--slides-dir ./slides `
--output demo_final.mp4
Options supplémentaires :
--resolution 1280x720pour une taille de fichier plus petite--var project_id=abc123pour des variables personnalisées dans le script--var [email protected]pour des flux paramétrés
Étape 6 : Réviser et Itérer
Après l'enregistrement, révisez la vidéo de sortie. Ajustements courants :
- Trop rapide ? Augmentez
duree_minimaledans les en-têtes de scène - Mauvais timing ? Ajoutez des actions
> wait Nentre les étapes - Étapes manquantes ? Ajoutez plus de scènes au script
- Mauvaise voix ? Essayez une autre voix edge-tts
Répertoire des Actions
| Action | Syntaxe | Description |
|---|---|---|
goto | > goto https://url.com | Naviguer vers une URL |
slide | > slide intro | Afficher une diapositive HTML depuis le répertoire des diapositives |
click | > click link Texte du Lien | Cliquer sur un lien par son texte |
click | > click button Texte du Bouton | Cliquer sur un bouton par son texte |
click | > click text Texte quelconque | Cliquer sur n'importe quel élément par son texte |
fill | > fill Label valeur | Remplir un champ de formulaire |
type | > type #sélecteur valeur | Taper dans un élément via un sélecteur CSS |
hover | > hover Texte de l'Élément | Passer la souris sur un élément |
select | > select Label Option | Sélectionner une option dans une liste déroulante |
scroll | > scroll down 300 | Défiler vers le bas de N pixels |
scroll | > scroll up 200 | Défiler vers le haut de N pixels |
wait | > wait 2 | Pause de N secondes |
screenshot | > screenshot nom.png | Sauvegarder une capture d'écran |
Sélection de la Voix
Voix edge-tts populaires (toutes gratuites, aucune clé API nécessaire) :
| Voix | Langue | Style |
|---|---|---|
en-US-JennyNeural | Anglais (États-Unis) | Chaleureux, conversationnel |
en-US-GuyNeural | Anglais (États-Unis) | Professionnel, clair |
en-US-AriaNeural | Anglais (États-Unis) | Naturel, polyvalent |
en-GB-SoniaNeural | Anglais (Royaume-Uni) | Raffiné, professionnel |
it-IT-IsabellaNeural | Italien | Naturel, clair |
de-DE-KatjaNeural | Allemand | Professionnel |
fr-FR-DeniseNeural | Français | Élégant |
es-ES-ElviraNeural | Espagnol | Clair |
ja-JP-NanamiNeural | Japonais | Naturel |
zh-CN-XiaoxiaoNeural | Chinois | Polyvalent |
Liste complète : edge-tts --list-voices
Variables
Utilisez {nom_variable} dans les scripts. Variables intégrées :
{base_url}— définie via l'argument--base-url
Variables personnalisées via --var clé=valeur :
> goto {base_url}/projects/{project_id}
> fill Recherche {search_term}
Sortie
La compétence produit :
demo_final.mp4— vidéo H.264, audio AAC, optimisée pour le web (faststart)- Résolution : 1920×1080 (par défaut) ou personnalisée
- Qualité : CRF 18 (haute qualité), AAC 192kbps
Conseils pour de Superbes Démonstrations
- Le script d'abord — Écrivez la narration avant les actions. L'histoire détermine le rythme.
- Scènes courtes — 8 à 15 secondes par scène. Gardez-les percutantes.
- Pauses généreuses — Ajoutez
> wait 1-2après les navigations pour un espace visuel de respiration. - Faire correspondre narration et action — Décrivez ce qui se passe à l'écran au moment où cela se produit.
- Diapositives d'intro/outro — Utilisez-les toujours pour un aspect professionnel.
- Testez de manière incrémentale — Enregistrez d'abord une scène pour vérifier le timing, puis ajoutez-en d'autres.
- Cohérence de marque — Les couleurs des diapositives d'intro/outro DOIVENT correspondre à la palette de marque du PoC (à partir du
threadlight-designCross-cutting Pattern 1). N'utilisez pas les dégradés bleu/violet par défaut pour un client à marque rouge. Copiez les propriétés CSS personnalisées dudemo-deck.htmldu PoC dans les fichiers HTML des diapositives. - Sous-titres — Générez un fichier WebVTT à partir du texte de narration. N'utilisez PAS de
<track src="file.vtt">externe — Edge bloque le CORS sur le protocolefile://. Au lieu de cela, intégrez le VTT en ligne sous forme d'URL de blob JS :var blob = new Blob([vttData], {type:'text/vtt'}); track.src = URL.createObjectURL(blob);et ajoutez dynamiquement l'élément<track>. Les horodatages DOIVENT utiliser le formatHH:MM:SS.mmm(pasMM:SS.mm— Edge le rejette). - Intégration dans le deck — Si le PoC livre un
demo-deck.html, intégrez la vidéo comme solution de repli sur la carte de la démo en direct. Ajoutez une bascule avec la touche V : appuyez sur V pour lire la vidéo en ligne sur la diapositive.is-cue, appuyez à nouveau sur V pour l'arrêter. Ajoutez une barre de contrôle visible (bouton lecture/pause + barre de progression cliquable + affichage du temps) afin que le présentateur ne dépende pas uniquement des raccourcis clavier. Arrêt automatique sur l'événementended. L'indication de repli (« Appuyez sur V pour la solution de repli pré-enregistrée ») s'affiche sous le texte de repère à faible opacité.
Enregistrement de Démonstrations d'Agents (modèle éprouvé)
Cette section est extraite de 6 tentatives d'enregistrement échouées sur un PoC d'agent hébergé par Foundry. Les modèles ci-dessous sont la seule approche qui produit de manière fiable une vidéo regardable lorsque le temps de réponse de l'agent est imprévisible (10 à 50 secondes).
Le problème
Les démonstrations d'agents IA ne sont pas enregistrables en temps réel. L'agent prend 10 à 50 secondes pour répondre. Si vous enregistrez le navigateur en continu et superposez un audio de narration pré-généré, la voix décrit la réponse pendant que l'écran affiche encore « Travail en cours... ». Aucune accélération en post-production ni décalage audio ne résout ce problème de manière fiable — les deux timelines sont fondamentalement désynchronisées.
La solution : jump-cuts par capture d'écran par scène
Ne montrez jamais « Travail en cours... » dans la vidéo. Coupez directement de « question tapée » à « réponse rendue ». L'attente de l'agent se produit hors caméra entre les captures d'écran.
Flux de travail par scène :
- Tapez l'invite → capture d'écran de l'état tapé (le narrateur introduit la question sur cette image)
- Cliquez sur « Demander » → interrogez jusqu'à ce que la réponse soit entièrement rendue (hors caméra — pas d'enregistrement)
- Capturez la réponse terminée (le narrateur décrit la réponse sur cette image)
- Construisez le segment : image fixe + clip audio de narration correspondant (durée exacte)
- Concaténez tous les segments : intro → K1tapé → K1terminé → K2tapé → K2terminé → … → outro
Attente intelligente — interrogation apparition → disparition :
# Phase 1 : attendre que l'indicateur de chargement APPARAISSE (confirme que l'appel API a commencé)
for _ in range(30):
if await page.evaluate("() => !!document.body.innerText.match(/Travail en cours/)"):
break
await page.wait_for_timeout(500)
# Phase 2 : attendre que l'indicateur de chargement DISPARAISSE (confirme que la réponse est rendue)
for _ in range(120):
if not await page.evaluate("() => !!document.body.innerText.match(/Travail en cours/)"):
break
await page.wait_for_timeout(1000)
await page.wait_for_timeout(2000) # laisser le DOM se stabiliser
Adaptez l'expression régulière (/Travail en cours/) pour correspondre à l'indicateur de chargement
utilisé par l'espace de travail. Le modèle en 2 phases évite le bogue courant où le
script vérifie avant même l'apparition de « Travail en cours... » et procède immédiatement.
Construction d'un segment à partir d'une image fixe + audio :
def make_segment(image_path, audio_path, output_path):
audio_dur = ffprobe_duration(audio_path)
subprocess.run([
"ffmpeg", "-y",
"-loop", "1", "-i", str(image_path),
"-i", str(audio_path),
"-c:v", "libx264", "-preset", "fast", "-crf", "18",
"-c:a", "aac", "-b:a", "192k",
"-t", str(audio_dur),
"-pix_fmt", "yuv420p",
"-movflags", "+faststart", str(output_path),
], check=True)
La durée de chaque segment est égale à celle de son audio de narration — le narrateur décrit toujours ce qui est à l'écran.
Anti-modèles (issus de 6 tentatives d'enregistrement échouées sur un PoC d'agent hébergé par Foundry)
| ❌ Approche | Pourquoi ça échoue |
|---|---|
| Enregistrer en continu + superposer l'audio après | Les timelines audio et vidéo ne s'alignent jamais — le narrateur parle des citations pendant que l'écran affiche « Travail en cours... » |
Accélérer les parties vidéo « Travail en cours... » avec setpts | A l'air saccadé ; le facteur d'accélération dépend du temps de réponse imprévisible de l'agent |
Minuteries > wait 35 fixes dans le script | Le temps de réponse de l'agent est de 10 à 50 s ; les minuteries fixes coupent les réponses ou gaspillent 30 s à ne rien montrer |
| Enregistrer la vidéo et l'audio simultanément en temps réel | Playwright ne peut pas capturer l'audio système ; Chromium headless n'a pas de périphérique audio |
| Post-traiter avec détection de décalage audio | Trop fragile ; le texte « Travail en cours... » apparaît dans le DOM mais les spinners de chargement varient selon l'espace de travail |
Sélection de la voix pour les démos d'agents
Utilisez une voix britannique (en-GB-SoniaNeural) pour les PoC destinés à un public britannique —
elle lit naturellement au rythme d'une démo et correspond au registre professionnel.
Évitez les voix américaines décontractées pour les démos dans des secteurs réglementés (FSI, télécoms, santé).
Emplacements des Fichiers
Lorsqu'elle est activée en tant que compétence CLI Copilot globale, les scripts se trouvent à :
~/.copilot/skills/auto-demo-producer/scripts/record_demo.py~/.copilot/skills/auto-demo-producer/scripts/generate_slides.py
Copiez-les dans votre répertoire de projet avant de les exécuter, ou référencez-les directement.
Prérequis
- Python 3.10+ avec
pip - edge-tts —
pip install edge-tts(Microsoft Neural TTS gratuit) - Playwright —
pip install playwright && playwright install chromium - ffmpeg — binaire système (voir les commandes d'installation ci-dessus)