Voz en off TTS — narración con sincronización a nivel de palabra
Los tiempos de palabra son lo que hace que los subtítulos resalten en la palabra correcta y que las escenas avancen al ritmo correcto. Genera SIEMPRE la voz en off PRIMERO y anima según sus tiempos reales — nunca al revés.
Inicio rápido (gratuito, sin clave API)
pip install edge-tts
python scripts/vo_gen.py --text "Pythagore. Dans un triangle rectangle…" --voice fr-FR-DeniseNeural --rate -4%
Salidas (prefijo vo por defecto):
vo.mp3— el audiovo_words.json—{ words:[{text,fromMs,toMs}], captions:[{startMs,durationMs,text,tokens[]}] }donde los subtítulos son páginas agrupadas de ≤3 palabras (un espacio >700ms rompe la página) con ventanas por palabravo.js—window.VO_B64(mp3 en base64) +window.VO_DATA(el JSON), listo para un pipeline de canvas/seek:<script src="vo.js">luegodecodeAudioDatapara reproducción yVO_DATA.captionspara dibujar
Listar voces: python scripts/vo_gen.py --list-voices fr (también: en, ja, es, de, pt, zh, ar…).
Menú de voces (selección rápida)
| Idioma | Narrador tranquilo | Enérgico |
|---|---|---|
| fr | fr-FR-DeniseNeural | fr-FR-HenriNeural |
| en | en-US-AriaNeural | en-US-GuyNeural |
| ja | ja-JP-NanamiNeural | ja-JP-KeitaNeural |
| es | es-ES-ElviraNeural | es-ES-AlvaroNeural |
| de | de-DE-KatjaNeural | de-DE-ConradNeural |
| pt | pt-BR-FranciscaNeural | pt-BR-AntonioNeural |
| zh | zh-CN-XiaoxiaoNeural | zh-CN-YunjianNeural |
Sintaxis de velocidad: --rate -4% más lento / +10% más rápido. Las frases cortas dan límites de palabra más limpios; regenera por frase para corregir una línea mala sin rehacer toda la pista.
Problemas conocidos (aprendidos por experiencia)
- edge-tts ≥ 7: los límites de palabra están DESACTIVADOS por defecto —
boundary="WordBoundary"es obligatorio (vo_gen.py ya lo pasa). Síntoma del error: el audio está bien,wordsvacío. - HTTP 403 del servicio: tu edge-tts es demasiado antiguo para el esquema de token actual —
pip install -U edge-tts(usa un venv si la instalación del sistema está bloqueada). - Los desplazamientos de palabra están en unidades de 100 nanosegundos en el flujo original; divide entre 10⁴ para obtener ms.
Alternativas y mejoras
- Kokoro (
pip install kokoro) — TTS neuronal local, 82M parámetros, varios idiomas. - Piper — completamente offline, rápido, descargas de voz por idioma.
- ElevenLabs — de pago, multilingüe v2; la API
with-timestampsdevuelve tiempos a nivel de carácter que alimentan directamente los subtítulos. - VOICEVOX (japonés) — API HTTP local en
localhost:50021, tiempos por fonema (ideal para animación de labios en JP). - Cualquier audio existente → tiempos de palabra mediante faster-whisper:
pip install faster-whisper python - <<'EOF' from faster_whisper import WhisperModel; import json m = WhisperModel("small"); segs, _ = m.transcribe("track.mp3", word_timestamps=True) json.dump([w._asdict() for s in segs for w in s.words], open("words.json","w")) EOF
Mezcla en un vídeo (referencia rápida)
Voz, música y SFX como pistas SEPARADAS, luego: base musical −18…−22 LUFS bajo la voz, ducking con sidechaincompress de ffmpeg (voz como disparador), final loudnorm=I=-14:TP=-1.5:LRA=11. Estilo de subtítulo que funciona: mayúsculas en negrita, 1–3 palabras por aparición, palabra activa en color de acento con un aumento de escala ~20%, fondo negro tipo píldora o borde para contraste, y manteniéndose fuera de las zonas de la interfaz de la plataforma.