Skip to main content
Stream two sentences to Coda with Protobuf messages and save the audio to output.pcm. You can run it without an audio device, then convert the file to WAV to hear it.

Prepare the client

Install uv and Python 3.11 or later. Create a Rime API key and set RIME_API_KEY in your server’s environment. Create a project and install the transport client and message definitions:
rime-api supplies generated Protobuf classes and schema files. Your application still uses a standard WebSocket client to connect, authenticate, send messages, and manage retries. The LiveKit plugin uses these same message classes.

Stream audio to a file

Save this as stream_binary.py. It connects to wss://coda.api.rime.ai/ws with rime.v1.binary and overwrites output.pcm in the current directory. The synthesis parameters and lifecycle are the same as in the JSON quickstart. The script decodes each server message as WebSocketResponse and reads its audio field. The full message includes Protobuf metadata, so it cannot go directly to a player.
The script has four functions:
  • send_sentences: sends each sentence as a text message, then sends end. To stream input over time, replace its fixed list with complete sentences from your application.
  • receive_audio: reads events until done, and writes each audio chunk. To route audio to a browser, phone system, or player, replace the await write_audio(...) call with your audio handler.
  • write_audio: writes each chunk on a worker thread. The receiver waits for each write before it reads the next message, so chunks stay in order. On cancellation, it waits for the active write before it closes the file.
  • main: connects with rime.v1.binary, waits for ready, sends start, and runs the sender and receiver together.
end and cancel are empty messages, so Protobuf does not select the payload until you mark it as set. Call request.end.SetInParent() or request.cancel.SetInParent() to select it, because a request with only a context_id sends no operation. Run the script after setting your API key:
A successful run prints a request ID and Saved output.pcm. The file contains raw mono, signed 16-bit little-endian PCM at 24 kHz, with no WAV header, and a failed run can leave a partial file. To hear the audio, convert it to WAV.

Listen to the result

Most players do not open headerless PCM. This command wraps output.pcm in a WAV header and saves output.wav, which any audio player opens:

Generate bindings for another language

The installed package includes schema/rime/text_to_speech.proto and schema/text_to_speech.asyncapi.yaml. Use the Protobuf source to generate messages for your language. The AsyncAPI file describes the JSON encoding. This command copies the installed Protobuf schema to your project:
Generate rime.WebSocketRequest and rime.WebSocketResponse with your language’s Protobuf compiler. Each WebSocket message carries one serialized message. Do not add a gRPC header, length prefix, base64 layer, or custom framing. The schema defines gRPC services too, but this WebSocket client only needs the message types. For message fields, connection reuse, cancellation, and errors, see the Coda WebSocket API reference.