---
name: auroflow-narration-timing
description: Crear una narración continua con ElevenLabs, convertir sus tiempos de caracteres en palabras verificables para montaje y efectos, y crear, editar y exportar subtítulos por palabra (SRT/ASS) desde esos tiempos. Usar para voz en off independiente y subtitulado sincronizado; conservar la voz ligada de un Character cuando ese sea el encargo.
---

# Narración continua y tiempos

El helper de este paquete funciona en Python 3.9+, sin SDK. Es una herramienta
local del agente; no declara un endpoint de narración en el MCP público de Auro.
La voz externa tiene presupuesto propio y no modifica `cost_max:0` de Flow.

Preparar un JSON con `id` estable `narration-…`, `text` literal, `model_id`
(`eleven_multilingual_v2` o `eleven_flash_v2_5`), `voice_id` observado o null,
`language_code`, `voice_settings` y `price_per_1000_usd` decimal como cadena.
Usar una toma continua por pieza. Escribir las cifras como deben pronunciarse;
las abreviaturas para pantalla se editan después en la pista de subtítulos.

```sh
python3 scripts/narration.py quote --request narracion.json
python3 scripts/narration.py voices
python3 scripts/narration.py synthesize --request narracion.json --voice-id ID_OBSERVADO --store salida/voz --allow-paid --max-usd 0.50
```

Las rutas de los ejemplos son relativas a esta skill. `quote` no hace red.
`voices` y `synthesize` leen `ELEVENLABS_API_KEY` del entorno; no poner la clave
en argumentos, JSON, logs o el chat. La selección de voz debe corresponder al
idioma y dirección del encargo; no tomar un ID de ejemplo por una voz elegida.
Consultar [operación](references/operation.md) al ejecutar o recuperar una voz.
Para una pista opcional de subtítulos por palabra con esos tiempos, leer
[word-captions.md](references/word-captions.md) (`scripts/captions.py`).

`synthesize` exige autorización de gasto y un máximo explícito, guarda intención
antes del POST y no reintenta. Si existe recibo completo devuelve el mismo asset;
si sólo existe intención, inspeccionar ese ID. Una respuesta incierta no justifica
otra petición ni otro directorio. `recover` importa la respuesta ya obtenida del
mismo envío sin conectar al proveedor.

El resultado conserva MP3, respuesta original, SHA-256, ID de petición observado
y palabras con offsets y tiempos. La decodificación y duración se verifican con
FFprobe. Un texto o alineamiento incompatible deja la operación pendiente de
revisión, sin inventar tiempos. No declarar acento, identidad o aprobación humana
a partir de ASR, metadatos o un estado técnico completo.
