Narration
npm run tts vocalise chaque ligne de src/timeline.ts dans public/audio/<lang>/<key>.wav, avec
les horodatages de mots Cartesia dans <key>.words.json, et réécrit src/audio.generated.ts avec
les longueurs réelles des lignes. Les lignes sont mises en cache par moteur, voix, modèle, vitesse et texte : seules les lignes nouvelles ou modifiées sont revocalisées. npm run tts -- en ou -- es limite à une seule langue.
Configuration Cartesia
- Les paramètres se trouvent dans
video.config.mjs(tts) : modèlesonic-3.6-2026-08-27, vitesse1. - Voix EN :
5568a7df-e5ab-4442-9fae-2e9ba1b15ad8(en-GB). CARTESIA_API_KEYest recherchée dans cet ordre :- l'environnement ;
.envdans le dossier vidéo (gitignoré ; copier.env.example) ;~/Documents/repos/.env.
- Ne jamais afficher la clé, l'echo ou la committer. Vérifier son existence sans la montrer, par
exemple
test -n "$CARTESIA_API_KEY" && echo set.
Moteurs et repli Kokoro
tts.engine dans video.config.mjs :
auto(par défaut) : Cartesia lorsqu'une clé est trouvée et que le service répond ; sinon, toute la langue est vocalisée avec Kokoro (local, gratuit) et un avertissement est affiché. Une langue n'est jamais un mélange de deux voix : si Cartesia abandonne en cours de route, toute la langue est refaite avec Kokoro, et la prochaine exécution avec Cartesia de retour la refait à nouveau.cartesia: échouer au lieu de basculer en repli.kokoro: rester hors ligne. Voix :af_bella(EN),ef_dora(ES). Kokoro ne fournit pas d'horodatage de mots, donc les sous-titres sont synchronisés proportionnellement.
Un avertissement concernant Kokoro dans la sortie signifie que la vidéo n'a pas la voix Cartesia : le dire lors de la remise de la vidéo.
Voix espagnole
voices.es est null jusqu'à ce qu'une version espagnole soit réalisée. Choisir une voix espagnole dans la bibliothèque
de voix Cartesia, écouter un échantillon de ligne du script, enregistrer son identifiant dans video.config.mjs
(es : { id : '<voice-id>', language : 'es' }), et ajouter 'es' à SETTINGS.voices (et à
SETTINGS.subtitles si les sous-titres espagnols sont souhaités).
Prononciation
Le TTS lit le texte de la narration ; les sous-titres montrent le texte écrit. Lorsque le TTS lit mal
un nombre ou un symbole, donner à la ligne une forme parlée comme quatrième argument de say, et conserver
la forme écrite de l'article comme sous-titre :
say(0.3, 'It solved 14/20 tasks.', 'Resolvió 14/20 tareas.', {
en: 'It solved fourteen out of twenty tasks.',
es: 'Resolvió catorce de veinte tareas.',
})
- Le TTS vocalise la forme parlée (et le cache revocalise la ligne lorsqu'elle change) ; la longueur de ligne en provient.
- Le sous-titre affiche le texte écrit, synchronisé proportionnellement sur la ligne (les horodatages des mots appartiennent aux mots parlés, donc ils ne sont pas utilisés pour cette ligne).
- Écrire la ligne simplement ("14/20", "83 %", "p = 0,0018") et ajouter une forme parlée uniquement lorsqu'une écoute montre que le TTS se trompe.
- Les barres obliques, les chaînes de version ("gpt-5.6"), les noms de fichiers et les acronymes sont les problèmes courants. Écouter chaque ligne qui en contient un.
Contrôle qualité audio
npm run audio-qa (écrit dans out/audio-qa.md) :
- normalise chaque ligne à la même intensité sonore (une fois par version de fichier) ;
- signale une ligne comme écrêtée lorsque son pic source atteint -0,1 dBFS ;
- signale une ligne comme trop longue lorsqu'elle dure plus de 1,6x son estimation à partir de la longueur du texte : un signe de parole déformée ou répétée. Écouter chaque ligne signalée et la revocaliser (modifier légèrement le texte, ou supprimer son fichier wav) si elle est erronée ;
- après
npm run render, mesure chaque mixage dansout/par rapport à -16 LUFS intégré, ±1 LU (pic réel -1,5 dBTP) et se termine par 1 si l'un est hors cible.
Après la narration, exécuter à nouveau npm run lint : les longueurs réelles remplacent les estimations et peuvent pousser
la vidéo hors de sa durée cible ou un sous-titre au-delà de 17 caractères/s.
Fond musical
Un fond doux est généré localement (npm run music, fait automatiquement par npm run render lorsqu'il est
manquant ; nécessite python3 avec numpy, ou uv). Il est atténué à 30 % de son volume pendant qu'une ligne
joue. Définir SETTINGS.music à null pour ne pas avoir de musique.