Aller au contenu principal

L'API TTS : générer de la parole

L’API TTS : générer de la parole

L’API Text-to-Speech (TTS) d’OpenAI convertit du texte en audio de haute qualité. Contrairement à la Realtime API qui gère des conversations vocales complètes, l’API TTS est un service unitaire : vous envoyez du texte, vous recevez un fichier audio. C’est l’outil idéal pour générer des annonces, des notifications vocales, des audiobooks ou du contenu accessible.

Premier appel TTS

Générer de la parole est remarquablement simple :

from openai import OpenAI
from pathlib import Path

client = OpenAI()

response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Bienvenue sur Corsen Academy. "
          "Votre formation sur les agents vocaux commence maintenant."
)

# Sauvegarder le fichier audio
speech_file = Path("bienvenue.mp3")
response.stream_to_file(speech_file)

L’API retourne un flux audio que vous pouvez sauvegarder directement ou streamer vers un lecteur.

Modèles disponibles

Modèle Qualité Latence Usage recommandé
tts-1 Bonne Faible Applications temps réel, chatbots
tts-1-hd Excellente Plus élevée Audiobooks, contenus publiés

tts-1 est optimisé pour la vitesse avec une qualité très correcte. tts-1-hd produit un audio plus naturel et détaillé, au prix d’une latence supérieure. Pour un agent vocal interactif, choisissez tts-1. Pour du contenu préenregistré, tts-1-hd.

Formats de sortie

L’API supporte plusieurs formats audio en sortie :

# MP3 (par défaut) — bon compromis taille/qualité
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="mp3"
)

# Opus — idéal pour le streaming internet, faible latence
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="opus"
)

# AAC — format natif iOS/macOS
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="aac"
)

# FLAC — lossless, archivage
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="flac"
)

# WAV — non compressé, intégration directe
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="wav"
)

# PCM — brut 24kHz 16-bit mono, pour traitement en aval
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Texte à convertir",
    response_format="pcm"
)

Pour un agent vocal utilisant la Realtime API, le format pcm est idéal car il correspond directement au format attendu.

Générer de l’audio par lots

Pour de grands volumes de texte, traitez les segments en parallèle :

import asyncio
from openai import AsyncOpenAI

async_client = AsyncOpenAI()

async def generate_speech_batch(segments: list[dict]) -> list[bytes]:
    """Génère l'audio pour plusieurs segments en parallèle."""
    async def generate_one(segment):
        response = await async_client.audio.speech.create(
            model="tts-1-hd",
            voice=segment.get("voice", "alloy"),
            input=segment["text"],
            response_format="mp3"
        )
        return await response.aread()

    tasks = [generate_one(seg) for seg in segments]
    return await asyncio.gather(*tasks)

# Utilisation
segments = [
    {"text": "Chapitre un. Introduction aux agents vocaux.", "voice": "onyx"},
    {"text": "Les agents vocaux transforment l'interaction homme-machine.", "voice": "onyx"},
    {"text": "Dans ce chapitre, nous explorerons les fondamentaux.", "voice": "onyx"},
]

audio_chunks = asyncio.run(generate_speech_batch(segments))

# Concaténer les fichiers
from pydub import AudioSegment
import io

combined = AudioSegment.empty()
for chunk in audio_chunks:
    segment = AudioSegment.from_mp3(io.BytesIO(chunk))
    combined += segment

combined.export("chapitre_1.mp3", format="mp3")

Limite de caractères et découpage

L’API TTS a une limite de 4096 caractères par requête. Pour des textes plus longs, découpez intelligemment :

def split_text_for_tts(text: str, max_chars: int = 4000) -> list[str]:
    """Découpe un texte en segments respectant les limites TTS."""
    sentences = text.replace(". ", ".\n").split("\n")
    segments = []
    current = ""

    for sentence in sentences:
        if len(current) + len(sentence) + 1 > max_chars:
            if current:
                segments.append(current.strip())
            current = sentence
        else:
            current += " " + sentence if current else sentence

    if current:
        segments.append(current.strip())

    return segments

Points clés à retenir

  • tts-1 pour le temps réel (faible latence), tts-1-hd pour le contenu publié (haute qualité)
  • Six formats de sortie : MP3, Opus, AAC, FLAC, WAV et PCM brut
  • Le format PCM est idéal pour l’intégration avec la Realtime API
  • Limite de 4096 caractères par requête : découpez les textes longs aux frontières de phrases
  • Le traitement par lots avec le client asynchrone accélère la génération de contenu volumineux