API 文档文字转语音实时文字转语音
实时文字转语音 v1
维护仍使用已冻结 Realtime TTS WebSocket v1 协议的客户端。
Realtime TTS v1 是为现有客户端保留的冻结兼容协议。新接入应使用上级 v3 协议。不要只修改 URL 就把 v1 客户端当作已升级;v2、v3 的事件和请求字段均不相同。
接口与子协议
| 项目 | 值 |
|---|---|
| WebSocket | wss://realtime.fishaudio.org/v1/tts/live |
| 子协议 | realtime.tts.msgpack.v1 |
| 消息编码 | MessagePack 二进制帧 |
服务端应用应在 WebSocket 握手时鉴权:
Authorization: Bearer FISHAUDIO_API_KEY
Sec-WebSocket-Protocol: realtime.tts.msgpack.v1不要把凭证放入 URL,也不要把长期 API Key 下发到浏览器。
事件流程
连接 → authenticated → start → ready
→ text → flush → audio(一个或多个)→ usage
→ [text → flush → audio → usage] → stop → finish所有应用层消息都必须编码成 MessagePack Map。一个连接对应一个会话;每次 flush 生成当前缓冲文本,在 stop 前可以继续提交多个分段。
客户端事件
| 事件 | 必填字段 | 说明 |
|---|---|---|
start | event、request | 收到 authenticated 后启动会话。 |
text | event、text | 向当前分段追加非空 UTF-8 文本。 |
flush | event | 生成缓冲分段;空分段会被拒绝。 |
stop | event | 生成剩余文本、结束会话并返回 finish。 |
ping | event | 可带 timestamp,服务端返回 pong。 |
每个事件都可以携带最长 128 字符的可选 request_id。
start.request 字段
| 字段 | 必填 | 约束 |
|---|---|---|
model_id | 是 | v1 客户端使用的公开音色/模型 UUID。 |
engine_model_id | 否 | 已分配时使用的旧引擎选择器。 |
format | 否 | mp3、wav、pcm 或 opus,默认 mp3。 |
speed | 否 | 0.5 到 2。 |
volume | 否 | 0 到 10。 |
language | 否 | 1–32 字符的语言提示。 |
chunk_length | 否 | 100 到 300 的整数。 |
latency | 否 | normal 或 balanced。 |
兼容别名 modelId、engineModelId 也可使用;未知字段会被拒绝。
服务端事件
客户端应处理 authenticated、ready、audio、usage、pong、warning、finish 和 error。音频二进制位于 audio.data;usage 返回分段用量和剩余额度,finish.units 返回本次会话接受的总用量。
import { decode, encode } from '@msgpack/msgpack';
import WebSocket from 'ws';
const ws = new WebSocket('wss://realtime.fishaudio.org/v1/tts/live', 'realtime.tts.msgpack.v1', {
headers: { Authorization: `Bearer ${process.env.FISHAUDIO_API_KEY}` },
});
ws.on('message', (raw) => {
const message = decode(raw);
if (message.event === 'authenticated') {
ws.send(encode({ event: 'start', request: { model_id: '公开音色 UUID', format: 'mp3' } }));
} else if (message.event === 'ready') {
ws.send(encode({ event: 'text', text: '你好,这是 Realtime TTS v1。' }));
ws.send(encode({ event: 'flush' }));
ws.send(encode({ event: 'stop' }));
} else if (message.event === 'audio') {
// 将 message.data 追加到输出流。
} else if (message.event === 'error') {
console.error(message.code, message.message, message.retryable);
}
});计费与错误
系统按成功接受的 flush 分段结算。分段在提交前生成失败时会退还预留额度。收到音频后不要盲目重试;v1 不提供持久请求重放或分段幂等协议。
协议错误通过 error 返回 code、message、retryable,随后关闭 WebSocket。常见错误包括 invalid_message、empty_segment、segment_too_large、model_not_found 和 insufficient_quota。
如需 camelCase 字段、供应商无关的模型切换、浏览器票据和持久恢复,请迁移到实时文字转语音 v3。