> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Générez de l'audio en temps réel

Le streaming WebSocket permet d’envoyer et de recevoir des données via une connexion unique et persistante. Cette méthode est utile pour les applications en temps réel, lorsque vous devez diffuser des données audio dès qu’elles sont disponibles.

Pour tester rapidement la latence (délai avant le premier octet) d’une connexion WebSocket à l’API Text to Speech d’ElevenLabs, installez `elevenlabs-latency` via `npm` et suivez les instructions [ici](https://www.npmjs.com/package/elevenlabs-latency?activeTab=readme).

> **Note**
>
> Les WebSocket sont disponibles pour Text to Speech et la plateforme Agents. Ce guide couvre le WebSocket **Text
> to Speech** (`/v1/text-to-speech/{voice_id}/stream-input`). Ce point de terminaison ne prend **pas**
> en charge les modèles `eleven_v3` ou `eleven_v4`. Pour un dialogue avec **Eleven v3** ou **Eleven v4** via
> WebSocket, consultez [Realtime Text to Dialogue](/docs/fr/eleven-api/guides/how-to/websockets/realtime-tdd)
> et [WebSocket Text to Speech et Text to Dialogue ](/docs/fr/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets).

## Prérequis

* Un compte ElevenLabs avec une clé API, voici comment [trouver votre clé API](/docs/fr/api-reference/authentication).
* Python ou Node.js, ou un autre environnement d’exécution JavaScript, installé sur votre machine

## Configuration

Installez les dépendances requises :

**`Python`**

```python Python
pip install python-dotenv
pip install websockets
```

**`TypeScript`**

```typescript TypeScript
npm install dotenv
npm install @types/dotenv --save-dev
npm install ws
```

Créez ensuite un fichier `.env` dans le répertoire de votre projet et ajoutez votre clé API :

**`.env`**

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

## Initialiser la connexion WebSocket

Après avoir choisi une voix dans la Voice Library et le modèle Text to Speech que vous souhaitez utiliser, initialisez une connexion WebSocket à l’API Text to Speech.

**`text-to-speech-websocket.py`**

```python text-to-speech-websocket.py
import os
from dotenv import load_dotenv
import websockets

# Load the API key from the .env file
load_dotenv()
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")

voice_id = 'Xb7hH8MSUJpSbSDYk0k2'

# For use cases where latency is important, we recommend using the 'eleven_flash_v2_5' model.
model_id = 'eleven_flash_v2_5'

async def text_to_speech_ws_streaming(voice_id, model_id):
    uri = f"wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id={model_id}"

    async with websockets.connect(uri) as websocket:
       ...
```

**`text-to-speech-websocket.ts`**

```typescript text-to-speech-websocket.ts
import * as dotenv from "dotenv";
import * as fs from "node:fs";
import WebSocket from "ws";

// Load the API key from the .env file
dotenv.config();
const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

const voiceId = "Xb7hH8MSUJpSbSDYk0k2";

// For use cases where latency is important, we recommend using the 'eleven_flash_v2_5' model.
const model = "eleven_flash_v2_5";

const uri = `wss://api.elevenlabs.io/v1/text-to-speech/${voiceId}/stream-input?model_id=${model}`;
const websocket = new WebSocket(uri, {
  headers: { "xi-api-key": `${ELEVENLABS_API_KEY}` },
});

// Create a directory for saving the audio
const outputDir = "./output";

try {
  fs.accessSync(outputDir, fs.constants.R_OK | fs.constants.W_OK);
} catch (err) {
  fs.mkdirSync(outputDir);
}

// Create a write stream for saving the audio into mp3
const writeStream = fs.createWriteStream(outputDir + "/test.mp3", {
  flags: "a",
});
```

## Envoyer le texte d’entrée

Une fois la connexion WebSocket ouverte, configurez d’abord les paramètres de voix. Envoyez ensuite le message texte à l’API.

**`text-to-speech-websocket.py`**

```python text-to-speech-websocket.py
async def text_to_speech_ws_streaming(voice_id, model_id):
    async with websockets.connect(uri) as websocket:
        await websocket.send(json.dumps({
            "text": " ",
            "voice_settings": {"stability": 0.5, "similarity_boost": 0.8, "use_speaker_boost": False},
            "generation_config": {
                "chunk_length_schedule": [120, 160, 250, 290]
            },
            "xi_api_key": ELEVENLABS_API_KEY,
        }))

        text = "The twilight sun cast its warm golden hues upon the vast rolling fields, saturating the landscape with an ethereal glow. Silently, the meandering brook continued its ceaseless journey, whispering secrets only the trees seemed privy to."
        await websocket.send(json.dumps({"text": text}))

        # Send empty string to indicate the end of the text sequence which will close the WebSocket connection
        await websocket.send(json.dumps({"text": ""}))
```

**`text-to-speech-websocket.ts`**

```typescript text-to-speech-websocket.ts
const text =
  "The twilight sun cast its warm golden hues upon the vast rolling fields, saturating the landscape with an ethereal glow. Silently, the meandering brook continued its ceaseless journey, whispering secrets only the trees seemed privy to.";

websocket.on("open", async () => {
  websocket.send(
    JSON.stringify({
      text: " ",
      voice_settings: {
        stability: 0.5,
        similarity_boost: 0.8,
        use_speaker_boost: false,
      },
      generation_config: { chunk_length_schedule: [120, 160, 250, 290] },
    })
  );

  websocket.send(JSON.stringify({ text: text }));

  // Send empty string to indicate the end of the text sequence which will close the websocket connection
  websocket.send(JSON.stringify({ text: "" }));
});
```

## Enregistrer l’audio dans un fichier

Lisez le message entrant depuis la connexion WebSocket et écrivez les segments audio dans un fichier local.

**`text-to-speech-websocket.py`**

```python text-to-speech-websocket.py
import asyncio

async def write_to_local(audio_stream):
    """Write the audio encoded in base64 string to a local mp3 file."""

    with open(f'./output/test.mp3', "wb") as f:
        async for chunk in audio_stream:
            if chunk:
                f.write(chunk)

async def listen(websocket):
    """Listen to the websocket for audio data and stream it."""

    while True:
        try:
            message = await websocket.recv()
            data = json.loads(message)
            if data.get("audio"):
                yield base64.b64decode(data["audio"])
            elif data.get('isFinal'):
                break

        except websockets.exceptions.ConnectionClosed:
            print("Connection closed")
            break

async def text_to_speech_ws_streaming(voice_id, model_id):
    async with websockets.connect(uri) as websocket:
          ...
          # Add listen task to submit the audio chunks to the write_to_local function
          listen_task = asyncio.create_task(write_to_local(listen(websocket)))

          await listen_task

asyncio.run(text_to_speech_ws_streaming(voice_id, model_id))
```

**`text-to-speech-websocket.ts`**

```typescript text-to-speech-websocket.ts
// Helper function to write the audio encoded in base64 string into local file
function writeToLocal(base64str: any, writeStream: fs.WriteStream) {
  const audioBuffer: Buffer = Buffer.from(base64str, "base64");
  writeStream.write(audioBuffer, (err) => {
    if (err) {
      console.error("Error writing to file:", err);
    }
  });
}

// Listen to the incoming message from the websocket connection
websocket.on("message", function incoming(event) {
  const data = JSON.parse(event.toString());
  if (data["audio"]) {
    writeToLocal(data["audio"], writeStream);
  }
});

// Close the writeStream when the websocket connection closes
websocket.on("close", () => {
  writeStream.end();
});
```

## Exécuter le script

Vous pouvez exécuter le script en lançant la commande suivante dans votre terminal. Un fichier audio MP3 sera enregistré dans le répertoire `output`.

**`Python`**

```python Python
python text-to-speech-websocket.py
```

**`TypeScript`**

```typescript TypeScript
npx tsx text-to-speech-websocket.ts
```

## Configuration avancée

Les WebSocket proposent plusieurs paramètres avancés pour affiner votre génération audio en temps réel.

### Mise en mémoire tampon

Lors de la génération audio en temps réel, deux notions importantes doivent être prises en compte : le délai avant le premier octet (TTFB) et la mise en mémoire tampon. Pour produire un audio de haute qualité et déduire le contexte, le modèle nécessite un certain seuil de texte d’entrée. Plus vous envoyez de texte via une connexion WebSocket, meilleure est la qualité audio. Si ce seuil n’est pas atteint, le modèle ajoute le texte à une mémoire tampon et génère l’audio une fois celle-ci remplie.

En matière de latence, le TTFB correspond au temps nécessaire pour que le premier octet audio soit envoyé au client. C’est important, car cela affecte la latence perçue de l’audio. Vous pouvez donc contrôler la taille du tampon pour trouver le bon équilibre entre qualité et latence.

Pour ce faire, utilisez le paramètre `chunk_length_schedule` lors de l’initialisation de la connexion WebSocket ou de l’envoi de texte. Ce paramètre est un tableau d’entiers représentant le nombre de caractères envoyés au modèle avant la génération audio. Par exemple, si vous définissez `chunk_length_schedule` sur `[120, 160, 250, 290]`, le modèle générera l’audio après l’envoi de 120, 160, 250 et 290 caractères, respectivement.

Voici comment cela fonctionne avec les paramètres par défaut de `chunk_length_schedule` :

![](/docs/_fern-img/077efc232570b0f92355aed2d6766b66bba815e335466e81cd64f8dfcce10ada.webp)

Dans le schéma ci-dessus, l’audio n’est généré qu’après l’envoi du deuxième message au serveur. En effet, le premier message est inférieur au seuil de 120 caractères, tandis que le deuxième fait dépasser ce seuil au nombre total de caractères. Le troisième message dépasse le seuil de 160 caractères, l’audio est donc immédiatement généré et renvoyé au client.

Vous pouvez spécifier une valeur personnalisée pour `chunk_length_schedule` lors de l’initialisation de la connexion WebSocket ou de l’envoi de texte.

```python
await websocket.send(json.dumps({
    "text": text,
    "generation_config": {
        # Generate audio after 50, 120, 160, and 290 characters have been sent
        "chunk_length_schedule": [50, 120, 160, 290]
    },
    "xi_api_key": ELEVENLABS_API_KEY,
}))
```

```typescript
websocket.send(
  JSON.stringify({
    text: text,
    // Generate audio after 50, 120, 160, and 290 characters have been sent
    generation_config: { chunk_length_schedule: [50, 120, 160, 290] },
    xi_api_key: ELEVENLABS_API_KEY,
  })
);
```

Si vous souhaitez forcer le renvoi immédiat de l’audio, vous pouvez utiliser `flush: true` pour vider le tampon et forcer la génération de tout texte mis en mémoire tampon. Cela peut être utile, par exemple, lorsque vous avez atteint la fin d’un document et souhaitez générer l’audio de la dernière section.

![](/docs/_fern-img/84011e01024effe1bba1556f0007c7947165a0101bce3a41f8b955d1a9788a9c.webp)

Vous pouvez le définir pour chaque message en ajoutant `flush: true` dans le message.

```python
await websocket.send(json.dumps({"text": "Generate this audio immediately.", "flush": True}))
```

```typescript
websocket.send(JSON.stringify({ text: "Generate this audio immediately.", flush: true }));
```

De plus, fermer le WebSocket force automatiquement la génération de tout texte mis en mémoire tampon.

### Paramètres de voix

Lors de l’initialisation des connexions WebSocket, vous pouvez spécifier les paramètres de voix pour les générations suivantes. Vous pouvez ainsi contrôler la vitesse, la stabilité et d’autres caractéristiques vocales de l’audio généré.

```python
await websocket.send(json.dumps({
    "text": text,
    "voice_settings": {"stability": 0.5, "similarity_boost": 0.8, "use_speaker_boost": False},
}))
```

```typescript
websocket.send(
  JSON.stringify({
    text: text,
    voice_settings: { stability: 0.5, similarity_boost: 0.8, use_speaker_boost: false },
  })
);
```

Vous pouvez les remplacer pour chaque message en spécifiant des `voice_settings` différents dans le message.

### Dictionnaires de prononciation

Vous pouvez utiliser des dictionnaires de prononciation pour contrôler la prononciation de mots ou d’expressions spécifiques. Ils permettent de veiller à la prononciation correcte de certains mots ou d’accentuer certains mots ou expressions.

Contrairement à `voice_settings` et `generation_config`, les dictionnaires de prononciation doivent être spécifiés dans le message « Initialize Connection ». Consultez le [Guide de l’API](/docs/fr/api-reference/text-to-speech/v-1-text-to-speech-voice-id-stream-input#send.Initialize%20Connection.pronunciation_dictionary_locators) pour en savoir plus.

> **Tip**
>
> Lorsque vous utilisez des dictionnaires de prononciation basés sur des phonèmes avec des WebSocket, vous devez ajouter `enable_ssml_parsing=true` comme paramètre de requête à l’URI WebSocket. Par exemple :
>
> ```
> wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input?model_id={model_id}&enable_ssml_parsing=true
> ```

## Bonnes pratiques

* Nous vous conseillons d’utiliser le paramètre par défaut de `chunk_length_schedule` dans `generation_config`.
* Pour développer une application d’agent conversationnel en temps réel, nous vous recommandons d’utiliser `flush: true` avec le texte à la fin du tour de conversation afin d’assurer une génération audio rapide.
* Si le paramètre par défaut n’offre pas une latence optimale pour votre cas d’utilisation, vous pouvez modifier `chunk_length_schedule`. Gardez toutefois à l’esprit que cette réduction de la latence peut se faire au détriment de la qualité.

## Conseils

* La connexion WebSocket se ferme automatiquement après 20 secondes d’inactivité. Pour la maintenir ouverte, vous pouvez envoyer un seul caractère espace `" "`. Cette chaîne doit inclure un espace, car l’envoi d’une chaîne entièrement vide, `""`, ferme le WebSocket.
* Envoyez une chaîne vide pour fermer la connexion WebSocket après l’envoi du dernier message texte.
* Vous pouvez utiliser `alignment` pour obtenir les horodatages au niveau des mots pour chaque mot du texte. Cela peut être utile pour synchroniser l’audio avec le texte dans une vidéo ou pour d’autres applications nécessitant une synchronisation précise. Consultez le [Guide de l’API](/docs/fr/api-reference/text-to-speech/v-1-text-to-speech-voice-id-stream-input#receive.Audio%20Output.alignment) pour en savoir plus.

## Étapes suivantes

#### [Streaming TTS](/docs/fr/eleven-api/guides/how-to/text-to-speech/streaming)

Utilisez le streaming HTTP lorsque le texte d’entrée est disponible à l’avance plutôt que généré en temps réel.

#### [Optimisation de la latence](/docs/fr/eleven-api/guides/how-to/best-practices/latency-optimization)

Réduisez le délai avant le premier audio grâce au choix du modèle, de la voix et au routage géographique.