语音合成
把文字转换为自然语音,例如朗读 Chatbot 的回答。
| 方式 | 请求 | 输入 | 输出 |
|---|---|---|---|
| 整段 | POST https://api.deepseek.com/v1/tools/tts | JSON 请求体中的完整文本 | 在响应体中流式返回音频 |
| 流式 | WebSocket wss://api.deepseek.com/v1/tools/tts | 分段发送的文本,例如模型仍在生成时 | 音频帧 |
音色
voice_id | 音色 |
|---|---|
stella | 海星,女声,默认 |
tide | 暗潮,男声 |
语种
普通话(zh)、粤语(yue)、英语(en)、日语(ja)、韩语(ko)、马来语(ms)、阿拉伯语(ar)、印尼语(id)、泰语(th)、越南语(vi)。
没有语种参数,语种根据文本自动识别。
整段合成
以 JSON 发送文本:
| 字段 | 是否必填 | 说明 |
|---|---|---|
text | 是 | 要朗读的文本,不能为空,最多 10,000 个 计费字符。请求体最大 64 KiB |
voice_id | 否 | stella(默认)或 tide |
format | 否 | wav(默认)或 pcm |
filter_markdown | 否 | 朗读前是否去掉 Markdown 格式,默认为 true |
curl https://api.deepseek.com/v1/tools/tts \
-H "Authorization: Bearer <DeepSeek API Key>" \
-H "Content-Type: application/json" \
-d '{"text": "你好,我是 DeepSeek。", "voice_id": "stella"}' \
--output speech.wav
音频边合成边返回,单次请求最多返回 30 分钟的音频。wav 返回 audio/wav;pcm 返回 24 kHz、16 位、单声道的原始 PCM。
| 状态码 | 原因 |
|---|---|
400 | 没有可朗读的文本,或文本未通过内容审核(Content Exists Risk) |
429 | 账号同时进行的请求数超过上限 |
503 | 服务繁忙,请稍后重试 |
504 | 合成超时 |
如果音频已经开始返回后合成失败,响应会中途断开,请把提前结束的响应视为失败。
不支持调节语速,也不支持中断后续传。
WebSocket 流式合成
- 连接
wss://api.deepseek.com/v1/tools/tts,可选查询参数:voice_id、format(默认pcm,也可以是opus)、filter_markdown。opus返回不带容器的 Opus 数据包,不能直接保存为 Ogg 文件。 - 鉴权有两种方式:带上请求头
Authorization: Bearer <API Key>;或者通过 WebSocket 子协议传入,即Sec-WebSocket-Protocol: tts, bearer.<API Key>。 - 以 JSON 文本消息发送文字:
{"event": "text", "text": "..."},最后一段之后发送{"event": "finish_text"}。 - 音频通过二进制消息下发。会话以文本消息
{"event": "finish", "code": "...", "message": "..."}结束,code为success或错误码,例如invalid_input、content_filter、input_timeout、service_error。
限制:60 秒内没有收到文字时会话结束;单次会话最长 30 分钟;单次会话的文字最多 10,000 个计费字符、64 KiB。服务端每 25 秒发送一次 WebSocket ping。
Python 示例,使用 websockets 包:
# Set DEEPSEEK_API_KEY to your API key before running this example.
# Requires the websockets package, version 14 or later.
import asyncio
import json
import os
import websockets
async def main():
url = "wss://api.deepseek.com/v1/tools/tts?voice_id=stella&format=pcm"
headers = {"Authorization": f"Bearer {os.environ['DEEPSEEK_API_KEY']}"}
async with websockets.connect(url, additional_headers=headers) as ws:
for chunk in ["Hello ", "from ", "DeepSeek."]:
await ws.send(json.dumps({"event": "text", "text": chunk}))
await ws.send(json.dumps({"event": "finish_text"}))
with open("speech.pcm", "wb") as f:
async for message in ws:
if isinstance(message, bytes):
f.write(message) # raw 16-bit signed mono PCM at 24 kHz
continue
finish = json.loads(message)
if finish["code"] != "success":
raise RuntimeError(f"{finish['code']}: {finish['message']}")
break
asyncio.run(main())
计费
| 计费单位 | 刊例价 | 限时折扣价(5 折) |
|---|---|---|
| 每 10,000 字符 | 3 元 | 1.5 元 |
汉字算 2 个字符,英文字母、数字、空格等其他字符算 1 个。
限速
每个账号最多同时进行 50 个请求,超过返回 429。