Skip to main content
Multiplexing allows you to send multiple independent TTS requests over a single WebSocket connection. Each request is tracked independently using a unique identifier, allowing concurrent processing of multiple text inputs without opening multiple connections. When multiplexing is enabled, each message you send to the server must include a client_req_id field. The server will stamp all response messages (audio chunks, metadata, etc.) with the same client_req_id, allowing you to match responses to their corresponding requests. To enable multiplexing, include close_ws_on_eos: False in your setup message. This tells the server to keep the WebSocket connection open after completing individual requests.
setup = {
    "voice_id": "RI2y7oBdsQJmkgFF",
    "output_format": "wav",
    "close_ws_on_eos": False  # Enable multiplexing
}
texts = [
    "First request. Second part, last one.",
    "Second request. Second part, last one again.",
]

client = gradium.client.GradiumClient(base_url=url, api_key=api_key)
async with client.tts_realtime(send_setup_on_start=False) as stream:

    async def send_loop():
        for idx, text in enumerate(texts):
            stamp = {'client_req_id': f'req-{idx:02d}'}
            await stream.send_setup(setup | stamp)
            await stream.send_text(text, **stamp)
            await stream.send_eos(**stamp)

    async def recv_loop():
        audio = collections.defaultdict(list)
        num_eos = 0
        async for msg in stream:
            if msg["type"] == "audio":
                audio[msg.get('client_req_id')].append(msg["audio"])
            elif msg['type'] == 'end_of_stream':
                num_eos += 1
                if num_eos == len(texts):
                    break
        return audio

    _, audio = await asyncio.gather(send_loop(), recv_loop())
    audio = {k: b"".join(v) for k, v in audio.items()}