Extension OpenCaptions
Branchez les sous-titres CWI (Caption With Intent) dans la pipeline de post-production du Content Engine. Au lieu de sous-titres plats et statiques, le CWI encode l'expérience ressentie de la parole — la hauteur tonale pilote le poids de la police, le volume pilote la taille de la police, l'emphase déclenche des animations lumineuses, et l'identité du locuteur est associée à des couleurs conformes WCAG AA. Le résultat est des sous-titres qui communiquent la manière dont quelque chose a été dit, et non seulement ce qui a été dit.
Le CWI est la norme de sous-titrage primée aux Oscars 2025 par FCB Chicago et la Chicago Hearing Society. OpenCaptions est la première chaîne d'outils logiciels open-source dédiée.
Point d'accroche dans la pipeline
Étape : Post-production (Étape 3) Position : Après la suréchelle et l'étalonnage, avant l'exportation finale.
Chaîne de post-production :
1. Suréchelle (Real-ESRGAN / Topaz) --> Résolution supérieure
2. Étalonnage (LUT marque / ffmpeg) --> Couleurs conformes à la marque
3. OpenCaptions (CWI) --> Sous-titres intelligents
4. Exportation finale (ffmpeg) --> Fichier prêt pour la production
L'extension reçoit un fichier vidéo étalonné et produit :
- Un document CWI (
.cwi.json) avec des annotations d'intention mot par mot - Un WebVTT de repli (
.vtt) pour les plateformes nécessitant des sous-titres standard - Un rapport de validation (JSON) avec les scores des piliers
- Une vidéo sous-titrée (
.mp4) rendue via Remotion ou incrustation ffmpeg
Fonctionnement
Vidéo étalonnée + Brief scène
|
├── [1] Transcription (faster-whisper) --> horodatages mot par mot
├── [2] Diarisation (pyannote-audio) --> attribution du locuteur
├── [3] Extraction d'intention --> hauteur, volume, émotion, emphase par énoncé
| V1 : parselmouth + FER (audio+vision)
| V2 : V-JEPA2 modèle du monde
| V3 : prédiction neuronale TRIBE v2
├── [4] Correspondance Intention -> CWI --> poids, taille, emphase, animation par mot
| V1 : RulesMapper (hauteur->poids, volume->taille)
| V2 : LearnedMapper (entraîné sur des données de correction)
| V3 : NeuralMapper (activations de régions cérébrales pilotent le style)
├── [5] Validation (12 règles) --> Scores d'attribution + synchronisation + intonation
└── [6] Rendu --> Superposition Remotion OU incrustation ffmpeg
Étape 1-2 : Transcription + Diarisation
La pipeline appelle le CLI OpenCaptions ou le serveur MCP, qui exécute faster-whisper pour les horodatages mot par mot et pyannote-audio pour la détection du locuteur. Ces étapes produisent un DiarizedTranscript où chaque mot est associé à un locuteur.
Étape 3 : Extraction d'intention
L'extracteur d'intention analyse l'audio et la vidéo pour déterminer le registre ressenti de chaque énoncé :
- Signaux vocaux : Hauteur (Hz), volume (dB), débit de parole (mots/min), timing des pauses
- Signaux affectifs : Valence (-1 à 1), arousal (0 à 1), émotion dominante
- Signaux sémantiques : Probabilité de sarcasme, mots d'emphase, figures de style
Ces signaux forment un IntentFrame pour chaque énoncé. Les mots individuels qui s'écartent de la ligne de base de l'énoncé reçoivent des surcharges WordIntent.
Étape 4 : Correspondance d'intention
Le mapper convertit les signaux d'intention en paramètres visuels CWI :
| Signal d'intention | Propriété CWI | Correspondance (V1 RulesMapper) |
|---|---|---|
| Hauteur (normalisée 0-1) | weight (100-900) | Interpolation linéaire : 100 + hauteur_norm * 800 |
| Volume (normalisé 0-1) | size (0.7-1.5) | Interpolation linéaire : 0.8 + volume_norm * 0.55 |
| Emphase sémantique + volume élevé | emphasis (booléen) | Mot dans mots_emphase OU volume > p90 |
| Identité du locuteur | Couleur du locuteur | Attribuée depuis une palette de 12 couleurs WCAG AA |
| Chuchotement (faible volume) | weight < 300 | Surcharge : poids limité à 100-250 |
| Cri (volume élevé) | size > 1.3 + emphasis | Surcharge : taille 1.35-1.5, emphase vrai |
Étape 5 : Validation
Le validateur @opencaptions/spec vérifie le document CWI par rapport à 12 règles réparties en trois piliers :
Attribution (3 règles) :
- ATT_001 : Chaque sous-titre a un locuteur dans le casting
- ATT_002 : Les locuteurs ont des couleurs uniques
- ATT_003 : Les couleurs respectent le contraste WCAG AA (4.5:1 sur #1a1a1a)
Synchronisation (5 règles) :
- SYN_001 : Tous les mots ont des horodatages
- SYN_002 : Horodatages strictement croissants
- SYN_003 : Les événements de sous-titres ne se chevauchent pas
- SYN_004 : Durée d'animation de 600 ms selon les spécifications
- FCC_001 : Pas de trous > 3 s pendant la parole
- FCC_002 : Maximum 42 caractères par ligne (conforme FCC)
Intonation (3 règles) :
- INT_001 : Poids dans la plage valide (100-900)
- INT_002 : Taille dans la plage valide (0.7-1.5)
- INT_003 : > 20 % des mots ont un poids non par défaut (les sous-titres varient réellement)
Chaque pilier obtient un score de 0 à 100. Un document CWI est validé si les trois piliers obtiennent un score >= 80.
Étape 6 : Rendu
Deux chemins de rendu :
Chemin Remotion (préféré pour Content Engine) : Les mots CWI deviennent des composants React dans une composition <CaptionOverlay>. Chaque mot apparaît à son horodatage avec une animation d'entrée spring(), la couleur du locuteur, le poids de police variable et une lueur d'emphase. Voir references/cwi-remotion-bridge.md pour la correspondance complète.
Incrustation ffmpeg (repli) : Générer un fichier de sous-titres ASS à partir du document CWI et l'incruster dans la vidéo via ffmpeg -vf ass=captions.ass. Perd l'animation mot par mot mais préserve les couleurs du locuteur et la variation de poids de police.
Utilisation du CLI
# Générer des sous-titres CWI à partir d'une vidéo
npx opencaptions generate video.mp4 --output captions.cwi.json
# Générer avec le backend neuronal TRIBE v2
npx opencaptions generate video.mp4 --backend tribe --output captions.cwi.json
# Valider un document CWI
npx opencaptions validate captions.cwi.json
# Prévisualiser les sous-titres dans le terminal (couleurs ANSI)
npx opencaptions preview captions.cwi.json
# Exporter vers WebVTT
npx opencaptions export captions.cwi.json --format webvtt
# Exporter vers After Effects ExtendScript
npx opencaptions export captions.cwi.json --format ae-json
# Exporter vers Premiere Pro XML
npx opencaptions export captions.cwi.json --format premiere-xml
# Vérifier les dépendances système
npx opencaptions doctor
# Installer les dépendances Python
npx opencaptions setup
Utilisation du serveur MCP
Le serveur MCP OpenCaptions expose quatre outils pour l'intégration avec les agents :
| Outil | Description |
|---|---|
generate_captions | Exécuter la pipeline complète sur un fichier vidéo |
validate_captions | Valider un document CWI par rapport aux 12 règles |
preview_captions | Prévisualisation formatée dans le terminal à un instant donné |
export_captions | Exporter au format WebVTT |
Pour l'utiliser via Claude Code, ajoutez le serveur MCP à vos paramètres :
{
"mcpServers": {
"opencaptions": {
"command": "npx",
"args": ["@opencaptions/mcp"]
}
}
}
Invoquez ensuite en conversation : "Générer des sous-titres CWI pour video.mp4" déclenche generate_captions.
Intégration avec compose-video.py
Le compose-video.py du Content Engine accepte un indicateur --captions :
python3 scripts/compose-video.py storyboard.md --brand arcan-studio --captions
Lorsque --captions est passé, après la génération et l'assemblage de tous les clips, la pipeline :
- Exécute
npx opencaptions generate {video-finale}.mp4 --output {dossier-sortie}/captions.cwi.json - Valide le document CWI (avertit si le score est < 80 mais ne bloque pas)
- Si
--remotionest également passé, injecte le JSON CWI dans la composition Remotion comme propriétés<CaptionOverlay> - Sinon, génère un WebVTT comme fichier satellite à côté de la vidéo finale
Si OpenCaptions n'est pas installé (npx opencaptions doctor échoue), la pipeline se dégrade gracieusement :
- Replie sur une superposition de texte de brief de scène (texte statique des descriptions
## Shotdu storyboard) - Journalise un avertissement : "OpenCaptions non disponible, utilisation de la superposition de texte du brief de scène"
- Produit toujours un fichier
.vttavec un timing dérivé des limites des clips
Styles de sous-titres
Trois préréglages de styles de sous-titres intégrés, sélectionnables via la configuration :
1. Mot par mot (brainrot)
Style à forte rétention : chaque mot apparaît individuellement, centré, variation de taille maximale. Utilisé pour les contenus sociaux/TikTok/Reels optimisés pour les accroches à dopamine.
- Un mot visible à la fois
- Grande taille de base (64 px en 1080p)
- Variation de poids extrême (100-900, plage complète)
- Les mots d'emphase passent à 1,5x avec lueur
- Fond : aucun (les mots flottent sur la vidéo)
- Police : Roboto Flex variable
2. Narratif (éditorial)
Affichage de phrases complètes avec style mot par mot. Utilisé pour les contenus longs, documentaires, intégrations vidéo dans des blogs.
- Événement de sous-titre complet visible, mots stylisés en ligne
- Taille de base moyenne (48 px en 1080p)
- Variation de poids modérée (300-700)
- Les mots d'emphase obtiennent une légère augmentation de taille (1,15x)
- Fond : pilule semi-transparente (rgba(0,0,0,0.6))
- Police : Roboto Flex variable
3. Minimal (tiers inférieur)
Présentation propre dans le tiers inférieur. Nom du locuteur + texte. Distraction visuelle minimale. Utilisé pour les interviews, têtes parlantes, enregistrements de conférences.
- Étiquette du nom du locuteur dans la couleur du locuteur, texte du sous-titre en blanc
- Petite taille de base (36 px en 1080p)
- Variation de poids uniquement pour l'emphase (400 par défaut, 700 emphase)
- Pas de variation de taille
- Fond : barre dégradée (15 % inférieurs du cadre)
- Police : system sans-serif
Contrat de données
Lectures (immuables)
- Actif vidéo étalonné de l'étape de post-production précédente
knowledge/compiled/brands/{slug_marque}.md-- pour la palette de couleurs des sous-titres et les préférences typographiques- Brief de scène (paramètre d'exécution) -- pour le contexte sur le ton émotionnel prévu
Écritures (espace de noms propre uniquement)
extensions/opencaptions/output/{id_actif}.cwi.json-- document CWIextensions/opencaptions/output/{id_actif}.vtt-- WebVTT de repliextensions/opencaptions/output/{id_actif}-report.json-- rapport de validationextensions/opencaptions/output/{id_actif}-captioned.mp4-- vidéo rendue (chemin Remotion uniquement)
Configuration
opencaptions:
# Préréglage de style de sous-titre
style: "narrative" # mot-par-mot | narrative | minimal
# Paramètres visuels
font_family: "Roboto Flex" # Police variable pour l'axe du poids
base_font_size: 48 # Pixels en 1080p
position: "bottom" # top | center | bottom
max_chars_per_line: 42 # Conformité FCC
background: "pill" # pill | shadow | gradient | none
background_opacity: 0.6 # 0.0 - 1.0
# Backend de la pipeline
backend: "av" # av (V1) | jepa (V2) | tribe (V3)
language: "en" # Indice ISO 639-1 pour la transcription
# Surcharges des locuteurs (optionnel, auto-détecté par défaut)
speakers:
- name: "Narrateur"
color: "#6B8AFF"
- name: "Invité"
color: "#FF6B6B"
# Rendu
render_mode: "remotion" # remotion | ffmpeg | sidecar-only
output_format: "mp4" # mp4 | webm
fps: 30 # Correspondre à la source vidéo
# Validation
min_score: 80 # Score minimum global pour continuer
fail_on_low_score: false # Si vrai, bloque la pipeline en cas de score bas
# Correspondance neuronale TRIBE v2 (backend V3 uniquement)
neural_mapping: false # Activer le style basé sur la réponse neuronale prédite
Dégradation gracieuse
L'extension ne bloque jamais la pipeline du Content Engine. Échelle de dégradation :
| Condition | Comportement |
|---|---|
| CLI OpenCaptions installé + toutes les dépendances Python | Pipeline CWI complète (transcription, diarisation, intention, correspondance) |
| CLI OpenCaptions installé, aucune dépendance Python | Backends simulés avec sous-titres factices + validation |
| CLI OpenCaptions non installé | Superposition de texte du brief de scène comme sous-titres statiques aux limites des clips |
| La vidéo n'a pas de piste audio | Ignorer la génération de sous-titres, journaliser un message d'information |
| Score de validation < 80 | Avertir mais continuer (sauf si fail_on_low_score: true) |
| Remotion non disponible | Replier sur l'incrustation ASS ffmpeg |
| ffmpeg non disponible | Sortir le JSON CWI + WebVTT comme fichiers satellites uniquement (pas de vidéo rendue) |
Liens connexes
- Projet OpenCaptions :
~/broomva/apps/opencaptions/ - Pont CWI-Remotion :
references/cwi-remotion-bridge.md - Guide d'intégration :
references/integration-guide.md - SKILL.md du Content Engine :
../../SKILL.md - Framework d'extension :
../README.md