import asyncio
import websockets
import json
import base64
async def multi_speaker_demo():
async with websockets.connect(
"wss://api.kugelaudio.com/ws/tts/multi?api_key=YOUR_API_KEY"
) as ws:
# The first non-empty text for an ID creates its context.
await ws.send(json.dumps({
"text": "The story begins.",
"context_id": "narrator",
"voice_settings": {"voice_id": 1071},
"flush": True,
}))
await ws.send(json.dumps({
"text": "Hello, I'm the main character!",
"context_id": "character",
"voice_settings": {"voice_id": 1072},
"flush": True,
}))
# Gracefully drain and close both contexts.
await ws.send(json.dumps({"close_context": True, "context_id": "narrator"}))
await ws.send(json.dumps({"close_context": True, "context_id": "character"}))
# Receive audio from both contexts
closed = set()
async for message in ws:
data = json.loads(message)
if "audio" in data:
context_id = data["context_id"]
audio_bytes = base64.b64decode(data["audio"])
play_audio(context_id, audio_bytes)
if data.get("context_closed"):
# Per-context usage for this conversation: audio time + charge
print(f"[{data['context_id']}] usage: {data.get('usage')}")
closed.add(data["context_id"])
if len(closed) == 2:
await ws.send(json.dumps({"close_socket": True}))
if data.get("session_closed"):
break
asyncio.run(multi_speaker_demo())