OpenAI
Text-to-speech with OpenAITTSService, streaming 24 kHz PCM from OpenAI's speech API.
Overview
OpenAITTSService: sends each sentence to OpenAI's speech API (audio.speech) and streams the reply back as raw 24 kHz PCM. Supports thegpt-4o-mini-ttsinstructions and speed controls.
Upstream page
Pipecat's documentation for the same service.
Source
packages/openai/src/tts.ts.
OpenAI docs
Models, voices and instructions.
Installation
bun add @pipedog/openaiimport { OpenAITTSService } from "@pipedog/openai/tts";Prerequisites
- An OpenAI account and an API key from the OpenAI dashboard.
- Pass the key as
apiKey. If you leave it out, the OpenAI SDK readsOPENAI_API_KEY. The examples read it fromOPENAI_API_KEY.
OpenAITTSService
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new OpenAITTSService.Settings({...})
(OpenAITTSSettings). Any setting you leave out keeps the default below.
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "gpt-4o-mini-tts" | Speech model. |
voice | string | "alloy" | One of alloy, ash, ballad, cedar, coral, echo, fable, marin, nova, onyx, sage, shimmer, verse. |
language | null | null | Not used by this service. |
instructions | string | null | null | How the voice should speak (tone, pace, accent). |
speed | number | null | null | Speed, 0.25 to 4.0. null leaves OpenAI's default (1.0). |
Usage
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { OpenAITTSService } from "@pipedog/openai/tts";
const tts = new OpenAITTSService({
apiKey: process.env.OPENAI_API_KEY ?? "",
sampleRate: 24000,
settings: new OpenAITTSService.Settings({
model: "gpt-4o-mini-tts",
voice: "marin",
instructions: "Speak in a calm, friendly tone.",
}),
});Change the voice or speed mid-call with a TTSUpdateSettingsFrame:
const update = new TTSUpdateSettingsFrame({
delta: new OpenAITTSService.Settings({ voice: "cedar", speed: 1.2 }),
});Event handlers
| Event | Description |
|---|---|
on_tts_request | A synthesis request is about to be made. |
This comes from the TTSService base class.
Notes
- Requests
response_format: "pcm"and emitsTTSAudioRawFrames (mono,chunkSizebytes each) betweenTTSStartedFrameandTTSStoppedFrame. - OpenAI only returns 24 kHz audio. Set
sampleRate: 24000(or a 24 kHz pipeline output rate); any other rate logs a warning, and the frames are still labelled with that rate. - An unknown voice, or a request OpenAI rejects, produces an
ErrorFrameinstead of audio. httpClientreplaces the SDK'sfetch, for example to set a longer request timeout.
Runtime notes
| 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/openai/package.json: ✅ means the compat smoke test passes on that runtime.
- The client is the
openaiJS SDK overfetch. The audio is read from the response body stream, so it works on Bun, Node, Deno and Cloudflare Workers. httpClienttakes afetchfunction where upstream takes an httpx client.- The deprecated
OpenAITTSService.InputParamsand thevoice,model,instructions,speedandparamsconstructor options are not ported. Usesettings.
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).