Resemble AI
Text-to-speech with Resemble AI: ResembleAITTSService streams audio and word timestamps over WebSocket.
Overview
ResembleAITTSService keeps one WebSocket open to Resemble AI's streaming endpoint and sends each sentence as a JSON request. Audio comes back as base64 JSON frames, which the service buffers (a one-second jitter buffer first, then 2208-byte frames) so playback survives Resemble's bursty delivery.
Upstream page
Pipecat's documentation for the same service.
Source
packages/resembleai/src/tts.ts.
Resemble AI docs
The streaming WebSocket reference.
Installation
bun add @pipedog/resembleaiimport { ResembleAITTSService } from "@pipedog/resembleai/tts";Prerequisites
- A Resemble AI account on a plan that includes the WebSocket API, an API key, and the UUID of a voice.
- Pass the key as
apiKey. The examples read it fromRESEMBLE_API_KEY.
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new ResembleAITTSService.Settings({...})
(ResembleAITTSSettings). Any setting you leave out keeps the default below.
| Setting | Type | Default | Description |
|---|---|---|---|
voice | string | null | null | UUID of the voice (voice_uuid). |
model | string | null | null | Not used. |
language | Language | null | null | Not used. |
Usage
import { ResembleAITTSService } from "@pipedog/resembleai/tts";
const tts = new ResembleAITTSService({
apiKey: process.env.RESEMBLE_API_KEY ?? "",
// Resemble's WebSocket reference lists the project as required.
projectUuid: process.env.RESEMBLE_PROJECT_UUID ?? null,
settings: new ResembleAITTSService.Settings({ voice: "your-voice-uuid" }),
});Event handlers
| Event | Description |
|---|---|
on_connected | The WebSocket connected. |
on_disconnected | The WebSocket closed. |
on_connection_error | The connection failed. |
Notes
- The sample rate defaults to 22050 Hz (8000, 16000, 22050, 32000 and 44100 work),
precisiontoPCM_16andoutputFormattowav. Audio is requested without a WAV header. - Word timestamps come from Resemble's per-character timings, so each pushed "word" is one character.
- A 401 or 403 error from Resemble closes the connection and opens a new one.
- Resemble doesn't acknowledge the WebSocket closing handshake, so the service doesn't wait for one.
projectUuidis not an upstream option. Resemble's reference listsproject_uuidas required, but upstream never sends it, so the service sends it only when you set it.
Runtime notes
- The WebSocket opens through the core
websocketConnect, with the key in anAuthorizationheader (throughfetchon Cloudflare Workers), so it works on Bun, Node, Deno and Cloudflare Workers. - The deprecated
voiceIdoption is not ported. Usesettings. - Tested against a local WebSocket server, not against Resemble AI itself.
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/resembleai/package.json: ✅ means the compat smoke test passes on that runtime.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).