Skip to main content
Hacer una llamada a /audio/speech es fácil. Narrar un artículo real es donde aparecen los problemas interesantes: el endpoint acepta como máximo 4096 caracteres por solicitud, cada voz pertenece a un modelo específico, los formatos de audio varían de un modelo a otro y el texto escrito para leerse no se parece en nada al texto escrito para escucharse. En este tutorial abordamos las cuatro cuestiones. El resultado es un script que convierte una URL en un único archivo de audio:
Haremos lo siguiente:
  1. Elegir un modelo y una voz adecuados para narración larga
  2. Hacer una única solicitud de voz y guardar el audio
  3. Dividir un artículo largo en fragmentos que quepan en el límite de caracteres
  4. Unir los fragmentos sintetizados en un solo archivo sin costuras audibles
  5. Reescribir el artículo en algo que valga la pena escuchar
  6. Combinar las piezas y, después, ver el streaming para uso interactivo

Configuración

Necesitas Python 3.9 o posterior, el paquete requests y una clave de API de Venice.

1. Elige un modelo y una voz

Las voces pertenecen a modelos. Enviar una voz de una familia a un modelo de otra es el primer error más común, así que empieza por listar lo que cada modelo acepta realmente:
model_spec.voices es la lista de voces autorizada de un modelo, y supported_formats te indica qué valores de response_format acepta. Quita el | length de la consulta para imprimir los nombres de las voces. Usaremos tts-xai-v1 con la voz eve. Admite pcm, que es lo que facilita la unión de fragmentos en la sección 4.
La velocidad de síntesis varía mucho más entre modelos de TTS que la calidad de la salida, y la diferencia es lo bastante grande como para cambiar tu arquitectura. Mide una solicitud realista con dos o tres candidatos antes de comprometerte con uno. Un fragmento que un modelo devuelve en unos segundos puede tardar varios minutos en otro.

2. Haz una única solicitud

El cuerpo de la respuesta es audio en bruto en lugar de JSON, así que escribe los bytes directamente en un archivo.
Las combinaciones no coincidentes se rechazan antes de generar audio, y el error te indica qué habría funcionado en su lugar:

3. Divide el texto en el límite de 4096 caracteres

El campo input acepta como máximo 4096 caracteres. El texto más largo se rechaza directamente en vez de truncarse en silencio:
Así que dividimos el artículo primero. Cortar por los límites de las frases es importante, porque un fragmento que termina a mitad de frase produce un tropiezo audible en la unión. Crea narrate.py:
Con un guion de 5362 caracteres, esto produce cuatro fragmentos, cada uno terminado en una frase:
El valor predeterminado de max_chars es 1500 en lugar de algo cercano al tope de 4096, y es intencional. El tiempo de síntesis crece con la longitud de la entrada, así que los fragmentos más pequeños vuelven antes y, como se ejecutan en paralelo, terminan todo el trabajo más rápido. Además abaratan los reintentos cuando falla una solicitud.

4. Une los fragmentos en un solo archivo

Concatenar audio codificado como MP3 no es fiable, porque cada fragmento lleva sus propios encabezados de trama. Solicitar pcm evita el problema por completo. PCM son muestras en bruto sin contenedor, así que unir es simplemente añadir bytes, y el módulo estándar wave de Python escribe el encabezado por nosotros.
Un solo fragmento se devuelve rápido en relación con la cantidad de audio que contiene:
Esa solicitud tardó unos 13 segundos en producir 89 segundos de voz. Ejecutar los cuatro fragmentos de forma concurrente es lo que mantiene el total en un tiempo razonable: la narración completa de abajo tardó 15 segundos de reloj. ThreadPoolExecutor.map devuelve los resultados en el orden en que se enviaron las entradas, así que los fragmentos aterrizan en orden de lectura aunque se hayan sintetizado al mismo tiempo.
El PCM en bruto no lleva la tasa de muestreo, así que tienes que proporcionar la correcta al escribir el encabezado WAV, y es específica de cada modelo. tts-xai-v1 devuelve 24 kHz mientras que tts-gradium-v1 devuelve 48 kHz. Si te equivocas, la narración se reproduce a velocidad y tono incorrectos.
Para averiguar la tasa de cualquier modelo, pide un clip corto como wav y lee el encabezado con el que vuelve:

5. Prepara texto que suene bien

El Markdown extraído leído en voz alta al pie de la letra es prácticamente inescuchable. Las URLs son el ejemplo más claro. Un modelo de voz las deletrea carácter por carácter, así que https://docs.venice.ai/llms.txt sale como:
h t t p s dos puntos barra barra docs punto venice punto a i l l m s punto t x t
Los encabezados, los marcadores de viñeta, las tablas y los bloques de código causan versiones más pequeñas del mismo problema. En lugar de pelearnos con Markdown a base de expresiones regulares, podemos pedirle a un modelo de chat que reescriba el artículo como algo pensado para hablarse. Crea article_to_audio.py:
La sustitución URL_PATTERN se queda como red de seguridad para el enlace ocasional que el modelo deje suelto.

6. Únelo todo

El punto de entrada extrae, escribe el guion, lo guarda y narra:
Guardar script.txt junto al audio vale las dos líneas. Cuando una narración suena mal, el guion casi siempre muestra por qué, y puedes arreglarlo sin pagar para sintetizar de nuevo.
Poco menos de seis minutos de narración, producidos en unos quince segundos. El guion ahora abre con prosa en lugar de con adornos de navegación:
Venice se construye sobre un principio sencillo pero poderoso. La privacidad del usuario está primero. Toda la arquitectura de la plataforma parte de ese compromiso filosófico.
Para revisar una narración sin escucharla entera, envía el audio de vuelta a través de /audio/transcriptions y compara la transcripción con script.txt. Transcribir los últimos veinte segundos es una forma rápida de confirmar que los fragmentos se unieron en el orden correcto, y detecta fragmentos perdidos o URLs deletreadas en segundos.

Streaming para uso interactivo

La narración por lotes optimiza el tiempo total. Una interfaz de voz tiene la prioridad contraria, que es sacar el primer audio lo antes posible. Establecer streaming: true devuelve el cuerpo frase por frase a medida que se genera, así que la reproducción puede empezar en aproximadamente un segundo en vez de esperar al clip completo.
Prefiere pcm sobre mp3 cuando alimentes la Web Audio API de un navegador o un dispositivo de audio directamente, ya que no necesita decodificarse.

Opciones de solicitud que vale la pena conocer

Errores

Como los fragmentos son independientes, un fallo solo te cuesta uno de ellos, y reintentar synthesize para ese fragmento siempre es seguro.

Próximos pasos

Algunas extensiones naturales desde aquí:

Texto a voz

Referencia del endpoint de voz y sus parámetros.

Clonación de voz

Narra con una voz personalizada en lugar de una preestablecida.

Respuestas citadas con búsqueda web

Genera el texto que esta herramienta narra.

Voz a texto

Transcribe audio para verificar una narración de principio a fin.