Cambiar el motor TTS fue lo fácil: el problema era encajar cada frase en su hueco
Katto pasó de Kokoro a Google Cloud Text-to-Speech con Chirp 3 HD y de 8 a 19 idiomas de doblaje. La llamada a la API resultó ser la parte pequeña del sistema.

Katto ya hacía doblaje con IA: cogías un clip, elegías idioma y recibías una versión traducida. La primera versión usaba Kokoro y cubría ocho idiomas. Ahora el motor principal es Google Cloud Text-to-Speech con las voces Chirp 3 HD, y el editor expone 19 idiomas de doblaje y 12 voces curadas. El autor esperaba un simple cambio de API. No lo fue.
Generar una frase que suene natural es fácil. Lo difícil es que esa frase empiece y acabe exactamente dentro del hueco que dejó el hablante original. Si el original dice algo en 2,4 segundos y la traducción tarda 3,2, ningún modelo lo arregla solo: la voz se mete en la frase siguiente, los subtítulos se desincronizan o hay que acelerar hasta que suena atropellado.
La duración es el contrato
El pipeline que acabó montando empieza por tratar el tiempo como dato. Katto ya tiene marcas de tiempo por palabra de su transcripción. En vez de mandar el texto entero a traducir y sintetizar de una vez, agrupa palabras en frases: una frase termina en puntuación, tras una pausa de más de 0,6 segundos o cuando pasaría de seis segundos. Cada segmento conserva su inicio y su fin, y esos números son el contrato de todas las etapas posteriores. Sintetizar el transcript completo suena más fluido, pero elimina las anclas que luego permiten devolver el audio a la línea de tiempo del vídeo.
La traducción también va condicionada por la duración. Una traducción escrita correcta puede ser un mal doblaje: hay idiomas que necesitan más sílabas para decir lo mismo. Cada grupo de frases pasa por Claude Haiku pidiendo una versión hablada natural, con preferencia por formulaciones cortas y menos sílabas, conservando el índice de cada segmento origen. El autor lo admite como heurística: un LLM no puede garantizar duración, porque la voz elegida también cambia el ritmo, y la capa de audio mide después el WAV generado. Hay una caché en proceso por idioma destino y segmentos que reutiliza la traducción mientras el worker sigue vivo.
La síntesis va frase a frase contra la API REST de Google en audio LINEAR16 a 24 kHz, con nombres de voz en el formato locale-Chirp3-HD-speaker que documenta Google. Google soporta más locales de los que Katto expone; limitó el producto a 19 a propósito, porque el resto de la cadena (interfaz, mapeo de locale, fuentes, subtítulos y comportamiento de reserva) tiene que aguantar ese idioma correctamente.
Ajustar sin destrozar
Después de sintetizar, compara la duración generada con la del hueco original y aplica el filtro atempo de FFmpeg, que acelera conservando el tono. El tope está en 1,3x. Con 1,6x encajaban más frases, pero algunas voces sonaban apresuradas; alinear perfecto no sirve si escucharlo es desagradable. Cada frase ajustada se coloca en su offset original dentro de una pista maestra.
Los subtítulos no se inventan a nivel de palabra: como la respuesta de síntesis no da marcas fiables del texto recién hablado, el doblaje usa subtítulos por frase generados de los mismos segmentos que alimentaron la voz, con tiempos que ya coinciden con la colocación del audio. El renderizador elige además fuentes que cubran el alfabeto destino, porque una tipografía latina no vale para japonés, chino, hindi o árabe.
En producción aparecieron los problemas de siempre. No todas las voces curadas funcionaban en todos los locales, así que si una no está disponible se reintenta una vez con un valor por defecto del género elegido. La previsualización del editor llama al mismo motor: usar otro modelo dejaría al usuario eligiendo una voz que nunca va a recibir. Y el fallo más tonto fue de red: la clave de producción está restringida a la IPv4 del VPS, pero el VPS prefería IPv6 para salir y las peticiones válidas se rechazaban hasta forzar la llamada por IPv4. API, clave y código estaban bien; la ruta no.
El doblaje genera una variante de vídeo aparte, así que si falla la traducción, la síntesis, el renderizado de subtítulos o el remux, el clip original queda intacto. Para los ocho idiomas de partida, Kokoro sigue disponible cuando la ruta de Google está desactivada o sin configurar.
Lo visible es la ampliación de 8 a 19 idiomas y las voces seleccionables. Lo de fondo es arquitectónico: el motor de Chirp 3 HD es sustituible, la fontanería de tiempos alrededor no lo es, y es lo que habría que rehacer otra vez si mañana cambia el proveedor. Katto no ha publicado métricas de latencia ni de coste por minuto doblado, que es justo lo que decide si un pipeline así se puede operar a escala.


