Compétence Voix-Off de Démonstration
Générer et synchroniser une narration vocale IA pour des vidéos de démonstration.
Comment cela s'intègre
Il s'agit de la troisième étape du pipeline de production vidéo :
/demo-script → /record-demo → /demo-voiceover
(planification) (capture) (narration et livraison)
Peut également être utilisé de manière autonome pour ajouter une narration à n'importe quelle vidéo existante avec un journal d'horodatage.
Entrées
La compétence nécessite :
- Script de démonstration JSON — provenant de
/demo-script(workspace/<date>/demo-script-<nom>.json) - Fichier vidéo brut — provenant de
/record-demo(workspace/<date>/<nom>_raw.mp4) - Journal d'horodatage — provenant de
/record-demo(workspace/<date>/<nom>_timestamps.json)
Format du journal d'horodatage (produit par /record-demo) :
{
"video_file": "demo_raw.mp4",
"start_epoch": 1739545200.0,
"steps": [
{
"scene_id": "intro",
"step_index": 0,
"action": "navigate",
"narration": "Bienvenue sur OneTest. Créons votre premier cas de test.",
"timestamp_sec": 0.0,
"completed_sec": 1.2
},
{
"scene_id": "navigate-to-test-cases",
"step_index": 0,
"action": "click",
"narration": "Ouvrez la section Cas de test depuis la barre latérale.",
"timestamp_sec": 3.2,
"completed_sec": 3.8
}
]
}
Pipeline
Étape 1 : Planification de la narration
Déterminer quand chaque segment de narration doit jouer par rapport à la vidéo :
Options de stratégie de synchronisation :
| Stratégie | Quand la narration commence | Idéal pour |
|---|---|---|
on_action | Au moment où l'action commence (timestamp_sec) | Expliquer ce qui va se passer |
after_action | Après la fin de l'action (completed_sec) | Décrire ce qui vient de se passer |
before_action | 0,5s avant le début de l'action | Créer de l'anticipation |
fill_pause | Pendant la fenêtre pause_after_ms | Narrer pendant la pause intentionnelle |
Par défaut : fill_pause — la narration est jouée pendant la pause après chaque action, de sorte que le spectateur voit l'action se dérouler, puis entend l'explication pendant que l'écran est stable. C'est ce qui semble le plus naturel.
Sortie de la planification :
{
"segments": [
{
"index": 0,
"text": "Bienvenue sur OneTest. Créons votre premier cas de test.",
"video_start_sec": 1.2,
"max_duration_sec": 2.0
},
{
"index": 1,
"text": "Ouvrez la section Cas de test depuis la barre latérale.",
"video_start_sec": 3.8,
"max_duration_sec": 1.5
}
]
}
Étape 2 : Génération audio (ElevenLabs)
Générer chaque segment de narration à l'aide du point d'accès avec horodatages d'ElevenLabs :
- Renvoie un alignement au niveau du caractère (durée exacte à la milliseconde près)
- Permet la génération gratuite de sous-titres
- Prend en charge le chaînage de continuité via
previous_request_ids(max 3)
Exécutez python scripts/generate_narration.py --plan voiceover_plan.json --voice rachel --output-dir .
Pour les détails de l'API, consultez references/elevenlabs-api.md.
Étape 3 : Réconciliation des durées
Après avoir généré l'audio, réconcilier les durées prévues et réelles :
- L'audio tient dans la fenêtre disponible -> placer au début prévu
- L'audio est plus court -> un silence supplémentaire est acceptable (les démos respirent)
- L'audio est plus long -> accélérer (max 1,15x via
atempo), ou raccourcir le texte et regénérer
Limiter l'ajustement de vitesse à 1,15x — au-delà, le résultat semble précipité.
Étape 4 : Assemblage audio
Fusionner les segments de narration avec la vidéo à l'aide du script utilitaire :
bash scripts/merge_audio_video.sh demo_raw.mp4 narration_results.json final_demo.mp4
Le script construit un filter_complex ffmpeg avec adelay par segment et atempo pour les ajustements de vitesse.
Étape 5 : Génération de sous-titres
Les horodatages au niveau du caractère d'ElevenLabs permettent la génération gratuite de SRT :
- Regrouper les caractères en mots, les mots en lignes de sous-titres (max 8 mots)
- Décaler de
video_start_secpour chaque segment - Sortie au format SRT standard
Pour graver les sous-titres dans la vidéo :
ffmpeg -i final_demo.mp4 -vf subtitles=demo.srt \
-c:v libx264 -crf 18 -c:a copy \
final_demo_subtitled.mp4
Configuration vocale
Choisissez la voix en fonction de l'audience, utilisez eleven_turbo_v2 pour les brouillons, eleven_multilingual_v2 pour la version finale.
Pour les identifiants de voix, le guide des paramètres, la comparaison des modèles et les détails du chaînage de continuité, consultez references/elevenlabs-api.md.
Ajustements de rythme
| Problème | Solution | Limite |
|---|---|---|
| Audio légèrement trop long | Accélérer avec le filtre atempo | Max 1,15x |
| Audio beaucoup trop long | Raccourcir le texte de narration, regénérer | Regénérer uniquement le segment |
| Audio trop court | Ajouter un silence de remplissage (naturel) | Le silence pendant les démos est acceptable |
| Intervalle gênant entre segments | Prolonger la pause ou ajouter une phrase de transition | Maintenir les pauses sous 3s |
Fichiers de sortie
| Fichier | Description |
|---|---|
<nom>_final.mp4 | Vidéo + narration fusionnées |
<nom>_final_subtitled.mp4 | Vidéo + narration + sous-titres incrustés |
<nom>.srt | Fichier de sous-titres (séparé) |
<nom>_narration_full.mp3 | Piste audio complète de narration (pour réutilisation) |
narration_NNN.mp3 | Segments individuels (pour régénération) |
<nom>_voiceover_plan.json | Plan de synchronisation (pour débogage/itération) |
Tous sauvegardés dans workspace/<date>/
Flux de travail itératif
La compétence permet de refaire des segments individuels sans régénérer l'intégralité :
- L'utilisateur examine la vidéo : "La narration de la scène 3 est trop rapide"
- L'agent ajuste : raccourcit le texte, régénère uniquement le segment 3
- Utilise
previous_request_idsdes segments 1-2 pour la continuité - Re-fusionne avec ffmpeg (seule la piste audio change, la vidéo reste)
C'est rapide car :
- La vidéo n'a pas besoin d'être réenregistrée
- Un seul appel API ElevenLabs par segment modifié
- La fusion ffmpeg ne prend que quelques secondes