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-1pour le temps réel (faible latence),tts-1-hdpour 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