Aller au contenu principal
Leçon 10 sur 18 · API Temps Réel et Agents Vocaux

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

Leçon 10 sur 18 Mis à jour le 3 novembre 2026 Développeur
Sur cette page
  1. L’API TTS : générer de la parole
  2. Premier appel TTS
  3. Modèles disponibles
  4. Formats de sortie
  5. Générer de l’audio par lots
  6. Limite de caractères et découpage
  7. Après le 6 janvier 2027 : faire parler un modèle Realtime
  8. Points clés à retenir

Mise à jour du 2 novembre 2026 — modèles audio. Plusieurs modèles de ce cours sont dépréciés : tts-1, tts-1-hd et gpt-4o-mini-tts s’arrêtent le 6 janvier 2027 (remplaçant indiqué : gpt-realtime-2.1-mini, que le guide TTS d’OpenAI déclare non pris en charge par /v1/audio/speech : la migration de la synthèse vocale passe par l’API Realtime) ; gpt-realtime, gpt-4o-realtime et les anciens modèles audio le 20 janvier 2027 (gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-audio-1.5) ; whisper-1, gpt-4o-transcribe et /v1/audio/translations le 26 février 2027 (gpt-transcribe, gpt-live-transcribe, v1/realtime/translations). Pour la voix full-duplex, GPT-Live 1 est disponible dans l’API depuis le 10 septembre 2026. Leçon corrigée le 3 novembre 2026 : response.stream_to_file() sur le résultat de speech.create() est déprécié par le SDK (« Due to a bug, this method doesn’t actually stream ») → with_streaming_response, comme dans le guide officiel ; modèles et voix mis à jour (gpt-4o-mini-tts et ses consignes de voix, 13 voix dont marin et cedar) ; nouvelle section sur la migration vers gpt-realtime-2.1-mini avant le 6 janvier 2027, d’après le guide Realtime conversations. Sources : Text to speech · Create speech · Realtime conversations · Deprecations.

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()

speech_file = Path("bienvenue.mp3")

with client.audio.speech.with_streaming_response.create(
    model="gpt-4o-mini-tts",
    voice="coral",
    input="Bienvenue sur Corsen Academy. "
          "Votre formation sur les agents vocaux commence maintenant.",
    instructions="Parle d'un ton chaleureux et posé.",
) as response:
    response.stream_to_file(speech_file)

L’API retourne un flux audio que vous pouvez sauvegarder directement ou streamer vers un lecteur. Passez par with_streaming_response, comme ici : appelée sur le résultat d’un simple speech.create(), la méthode stream_to_file() est dépréciée par le SDK, qui précise qu’elle ne diffuse pas réellement le flux.

Modèles disponibles

Les trois modèles de l’API Audio sont dépréciés et s’arrêtent le 6 janvier 2027 : c’est la période de transition pendant laquelle vous les utiliserez encore.

ModèleParticularitéVoix
gpt-4o-mini-ttsAccepte des consignes (instructions) : accent, émotion, intonation, vitesse, ton, chuchotement13 voix, dont marin et cedar, recommandées pour la qualité
tts-1Latence plus faible, qualité moindre9 voix : alloy, ash, coral, echo, fable, onyx, nova, sage, shimmer
tts-1-hdQualité supérieure à tts-1, latence plus élevéeLes mêmes 9 voix

Les consignes ne fonctionnent pas avec tts-1 et tts-1-hd. Le paramètre speed, de 0,25 à 4,0, règle le débit avec tous les modèles. D’après le guide, les voix sont optimisées pour l’anglais : écoutez-les en français sur OpenAI.fm avant de choisir. Les usages d’OpenAI exigent aussi d’indiquer clairement à vos utilisateurs que la voix qu’ils entendent est générée par une IA.

Formats de sortie

L’API produit six formats, choisis avec response_format :

FormatUsage
mp3 (par défaut)Usage général
opusStreaming sur Internet et communication, faible latence
aacCompression numérique, privilégiée par YouTube, Android et iOS
flacCompression sans perte, pour l’archivage
wavNon compressé, pour éviter le coût du décodage
pcmÉchantillons bruts à 24 kHz, 16 bits signés, sans en-tête
for fmt in ("mp3", "opus", "aac", "flac", "wav", "pcm"):
    with client.audio.speech.with_streaming_response.create(
        model="gpt-4o-mini-tts",
        voice="marin",
        input="Texte à convertir",
        response_format=fmt,
    ) as response:
        response.stream_to_file(f"exemple.{fmt}")

Pour un agent vocal bâti sur l’API Realtime, le format pcm est le plus pratique : ses échantillons à 24 kHz sur 16 bits correspondent au format audio/pcm à 24 kHz de l’API Realtime.

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="gpt-4o-mini-tts",
            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

Après le 6 janvier 2027 : faire parler un modèle Realtime

OpenAI désigne gpt-realtime-2.1-mini comme remplaçant des trois modèles, et prévient : ce n’est pas un modèle de l’endpoint /v1/audio/speech, la migration change de méthode de travail. On passe par une session Realtime. Le guide Realtime conversations montre comment obtenir une réponse sans contexte, qui ignore la conversation et ne suit que ses instructions : c’est le moyen de faire dire un texte donné.

import base64
import json
import os
import wave

import websocket  # pip install websocket-client

TEXTE = "Bienvenue sur Corsen Academy. Votre formation sur les agents vocaux commence maintenant."

ws = websocket.WebSocket()
ws.connect(
    "wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini",
    header=[f"Authorization: Bearer {os.environ['OPENAI_API_KEY']}"],
)

# Sortie audio seule, en PCM 16 bits à 24 kHz, avec la voix choisie
ws.send(json.dumps({
    "type": "session.update",
    "session": {
        "type": "realtime",
        "output_modalities": ["audio"],
        "audio": {"output": {"format": {"type": "audio/pcm", "rate": 24000}, "voice": "marin"}},
    },
}))

# Une réponse sans contexte (input vide), qui doit dire le texte tel quel
ws.send(json.dumps({
    "type": "response.create",
    "response": {
        "input": [],
        "output_modalities": ["audio"],
        "instructions": f"Dis exactement le texte suivant, sans rien ajouter :\n{TEXTE}",
    },
}))

audio, transcription = bytearray(), []
while True:
    event = json.loads(ws.recv())
    if event["type"] == "response.output_audio.delta":
        audio += base64.b64decode(event["delta"])
    elif event["type"] == "response.output_audio_transcript.delta":
        transcription.append(event["delta"])
    elif event["type"] == "error":
        raise RuntimeError(event["error"]["message"])
    elif event["type"] == "response.done":
        break
ws.close()

with wave.open("bienvenue.wav", "wb") as wav:
    wav.setnchannels(1)
    wav.setsampwidth(2)  # 16 bits
    wav.setframerate(24000)
    wav.writeframes(bytes(audio))
print("Texte prononcé :", "".join(transcription))

Deux différences avec l’API Audio comptent en production. Le résultat n’est plus garanti mot pour mot : un modèle Realtime suit une consigne, il ne lit pas un fichier. Comparez donc la transcription de ce qu’il a dit, renvoyée dans response.output_audio_transcript.delta, au texte attendu, et régénérez en cas d’écart. La facturation change aussi : elle suit les tarifs du modèle Realtime, en tokens texte et audio, indiqués sur sa fiche. Une clé refusée, enfin, n’empêche pas la connexion : elle arrive juste après, dans un événement error.

Points clés à retenir

  • gpt-4o-mini-tts, tts-1 et tts-1-hd s’arrêtent le 6 janvier 2027 ; gpt-4o-mini-tts est le seul à accepter des consignes de voix (instructions)
  • Enregistrez l’audio avec with_streaming_response : stream_to_file() sur un simple speech.create() est déprécié
  • 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
  • La migration passe par une session Realtime avec gpt-realtime-2.1-mini : réponse sans contexte, audio PCM 24 kHz, transcription à comparer au texte