> 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.

# Dialoge in Echtzeit streamen

Der Text to Dialogue-WebSocket (`/v1/text-to-dialogue/stream-input`) hält eine einzelne Verbindung offen, während Sie Dialogzeilen senden und base64-kodierte Audio-Chunks empfangen. Er ist nur für **Eleven v3**- und **Eleven v4**-Dialogmodelle vorgesehen (`model_id` muss mit `eleven_v3` oder `eleven_v4` beginnen).

> **Note**
>
> Dieser Leitfaden behandelt den **Text to Dialogue**-WebSocket. Für **Flash**, **Multilingual v2** oder andere
> Nicht-v3-TTS-Modelle verwenden Sie den [Echtzeit-TTS- WebSocket](/docs/de/eleven-api/guides/how-to/websockets/realtime-tts). Eine Gegenüberstellung
> beider Protokolle finden Sie unter [Text to Speech vs. Text to Dialogue- WebSockets](/docs/de/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets).

## Voraussetzungen

* Ein ElevenLabs-Konto mit einem API-Schlüssel ([Authentifizierung](/docs/de/api-reference/authentication)).
* Der API-Schlüssel muss über Berechtigungen für `Text to Speech` verfügen.
* Python oder Node.js ist auf Ihrem Computer installiert.

## Einrichtung

**`Python`**

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

**`TypeScript`**

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

Erstellen Sie eine `.env`-Datei:

**`.env`**

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

Wählen Sie eine **Stimm-ID** aus der [Stimmbibliothek](https://elevenlabs.io/voice-library). Die folgenden Beispiele verwenden `eleven_v4_turbo`, das **eine** registrierte Stimme pro Verbindung erlaubt.

## WebSocket öffnen

Stellen Sie eine Verbindung zu `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input` mit Abfrageparametern wie `model_id` und `output_format` her. Sie können den API-Schlüssel im Header `xi-api-key` oder in der ersten JSON-Nachricht senden (hier im Body gezeigt, um ein einheitliches Muster über alle Sprachen hinweg zu verwenden).

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

```python text-to-dialogue-websocket.py
import asyncio
import base64
import json
import os

from dotenv import load_dotenv
import websockets

load_dotenv()
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
VOICE_ID = "21m00Tcm4TlvDq8ikWAM"
MODEL_ID = "eleven_v4_turbo"

URI = (
    "wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input"
    f"?model_id={MODEL_ID}&output_format=mp3_44100_128"
)
```

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

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

dotenv.config();
const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;
const voiceId = "21m00Tcm4TlvDq8ikWAM";
const modelId = "eleven_v4_turbo";

const uri = `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input?model_id=${modelId}&output_format=mp3_44100_128`;
const websocket = new WebSocket(uri);

const outputDir = "./output";
try {
  fs.accessSync(outputDir, fs.constants.R_OK | fs.constants.W_OK);
} catch {
  fs.mkdirSync(outputDir);
}
const writeStream = fs.createWriteStream(`${outputDir}/dialogue-ws.mp3`, { flags: "a" });
```

## Stimmen registrieren und Text streamen

Senden Sie eine **erste Nachricht**, die `voices` (erforderlich) und `xi_api_key` enthält, falls Sie den Header `xi-api-key` nicht gesetzt haben. Senden Sie dann einen oder mehrere Frames mit `inputs`: Jedes Element enthält `text`, `voice_id` und optional `new_turn`.

Der Server puffert Text, bis genügend Kontext vorhanden ist (etwa **40 Zeichen** und **8 Wörter**), und gibt dann `audio`-Chunks aus. Antwortfelder verwenden **snake_case** (zum Beispiel `is_final`).

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

```python text-to-dialogue-websocket.py
async def stream_dialogue():
    async with websockets.connect(URI) as websocket:
        await websocket.send(
            json.dumps(
                {
                    "voices": [VOICE_ID],
                    "xi_api_key": ELEVENLABS_API_KEY,
                }
            )
        )

        line = (
            "This is a longer line of dialogue used to exceed the minimum buffer so the model "
            "starts generating streamed audio for the registered voice. "
        )
        await websocket.send(
            json.dumps(
                {
                    "inputs": [
                        {"text": line, "voice_id": VOICE_ID, "new_turn": False},
                    ],
                }
            )
        )

        await websocket.send(json.dumps({"close_socket": True}))

        os.makedirs("output", exist_ok=True)
        out_path = "output/dialogue-ws.mp3"
        with open(out_path, "wb") as audio_file:
            while True:
                raw = await websocket.recv()
                msg = json.loads(raw)
                if msg.get("error"):
                    raise RuntimeError(msg)
                if msg.get("audio"):
                    audio_file.write(base64.b64decode(msg["audio"]))
                if msg.get("is_final"):
                    break
        print(f"Wrote {out_path}")


asyncio.run(stream_dialogue())
```

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

```typescript text-to-dialogue-websocket.ts
websocket.on("open", () => {
  websocket.send(
    JSON.stringify({
      voices: [voiceId],
      xi_api_key: ELEVENLABS_API_KEY,
    })
  );

  const line =
    "This is a longer line of dialogue used to exceed the minimum buffer so the model starts generating streamed audio for the registered voice. ";

  websocket.send(
    JSON.stringify({
      inputs: [{ text: line, voice_id: voiceId, new_turn: false }],
    })
  );

  websocket.send(JSON.stringify({ close_socket: true }));
});

websocket.on("message", (data) => {
  const msg = JSON.parse(data.toString());
  if (msg.error) {
    console.error(msg);
    return;
  }
  if (msg.audio) {
    writeToLocal(msg.audio, writeStream);
  }
});

function writeToLocal(base64str: string, stream: fs.WriteStream) {
  stream.write(Buffer.from(base64str, "base64"));
}

websocket.on("close", () => {
  writeStream.end();
});
```

`close_socket` gibt gepufferten Text aus, sendet verbleibendes Audio und anschließend einen finalen Frame mit `is_final: true`, bevor die Verbindung geschlossen wird. Um die **Verbindung zwischen Zeilen offen zu halten**, lassen Sie `close_socket` weg, bis die Sitzung endet. Verwenden Sie `flush`, um Audio für kürzere Puffer zu erzwingen, ohne die Verbindung zu schließen.

## Skript ausführen

**`Python`**

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

**`TypeScript`**

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

Sie sollten eine MP3-Datei unter `output/` erhalten (Dateiname wie im obigen Beispiel).

## Hinweise zum Verhalten

### Pufferung

Anders als `chunk_length_schedule` beim TTS-WebSocket verwendet das Dialog-Streaming einen **festen Serverschwellenwert** (Zeichen- und Wortanzahl), bevor das erste Teil-Audio gesendet wird. Wenn Sie kurze Zeilen senden und Verzögerungen hören, bündeln Sie etwas mehr Text pro `inputs`-Frame oder senden Sie `flush: true`, um die Generierung ohne Schließen des Sockets zu erzwingen.

### Sprecherwechsel und Stimmen

Setzen Sie `new_turn: true`, wenn ein Sprecher seinen Beitrag beendet, damit die Prosodie sauber zurückgesetzt wird. Ein Wechsel von `voice_id` zwischen `inputs`-Einträgen startet ebenfalls einen neuen Beitrag. Mit `eleven_v4_turbo` registrieren Sie **genau eine** Stimme in `voices`; `eleven_v4` unterstützt bis zu **10** registrierte Stimmen.

### Inaktivität

Wenn der Server **20 Sekunden lang keine Client-Nachricht empfängt**, wird die Verbindung beendet. Senden Sie `{"keep_alive": true}`, um den Timer zurückzusetzen, ohne Audio zu synthetisieren.

### Parallelität

Jede offene Verbindung hält eine Dialogsitzung, solange sie geöffnet bleibt. Sie stammt aus einem dedizierten Pool, der von der standardmäßigen Parallelitätsgrenze Ihres Plans getrennt ist. Über die Verbindung generiertes Audio zählt nicht zur Standardparallelität. Weitere Informationen finden Sie unter [Text to Dialogue-Parallelität](/docs/de/overview/models#text-to-dialogue-concurrency).

### Alignment

Fügen Sie der Abfragezeichenfolge `sync_alignment=true` hinzu, um bei Verfügbarkeit `alignment`-Objekte (Timing-Arrays in snake_case) für Chunks zu erhalten. Siehe [API-Referenz](/docs/de/api-reference/text-to-dialogue/ttd-websocket).

## Nächste Schritte

#### [TTS- vs. TTD-WebSockets](/docs/de/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets)

Wählen Sie den passenden WebSocket und vergleichen Sie Nachrichtenstrukturen.

#### [Text to Dialogue-WebSocket (API)](/docs/de/api-reference/text-to-dialogue/ttd-websocket)

Abfrageparameter, Nachrichtenschemas und Beispiele.

#### [Dialog streamen (HTTP)](/docs/de/api-reference/text-to-dialogue/stream)

Wenn der vollständige Anfrage-Text ohne WebSocket verfügbar ist.

#### [Echtzeit-TTS-WebSocket](/docs/de/eleven-api/guides/how-to/websockets/realtime-tts)

Non-v3-Streaming mit einer Stimme über WebSockets.