外观
音频生成 API
知梦 API 提供 Google 的 Gemini TTS 配音及 Lyria 音乐模型,以及 Suno 公司的音乐模型,全部使用 Chat Completions 协议。TTS / Lyria 为 ¥0.30/次,Suno V6 Mini 为 ¥0.60/次。直接使用完整模型 ID,不配置模型别名。
Google 的三个音频模型支持 URL、Base64 或两者同时返回:通过 output_format 选择 url(Chat 默认)、base64 或 both;Suno 使用非流式 Chat,返回 M4A 音频链接,可传 instrumental、n、duration;后两者不保证实际条数和时长,详见 Suno 接入。
| 提供方 | 模型 ID | 能力 | 音频格式 | 价格 |
|---|---|---|---|---|
gemini-3.8-flash-tts | 文字转语音、自然语言控制语气、单人配音 / 双人对话 | WAV / PCM | ¥0.30/次 | |
lyria-3.5 | 根据音乐描述与歌词生成纯音乐或歌曲 | MP3 | ¥0.30/次 | |
lyria-3-pro-preview | 高质量版音乐生成,与 3.5 使用相同参数 | MP3 | ¥0.30/次 | |
| Suno | suno-v6-mini | 音乐生成,非流式 Chat,可有多版本 | M4A 链接 | ¥0.60/次 |
TTS 完整参数 · Lyria 完整参数 · Suno 完整参数 · 在线调试
地址、鉴权与计费
http
POST https://api.zmoapi.cn/v1/chat/completions
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json兼容客户端 Base URL 为 https://api.zmoapi.cn/v1。使用知梦 API 密钥,确认有目标模型权限。请求为 UTF-8 JSON,密钥放在服务端环境变量,不写进公开网页或代码仓库。
上述四个模型均按次调用计价,不按生成时长、音频文件大小或 Chat 的 usage Token 数计算公开售价。TTS 不同音色及单人 / 双人模式均为 ¥0.30/次,Lyria 为 ¥0.30/次,Suno V6 Mini 为 ¥0.60/次。失败、断连或超时后的最终结算以平台消费记录为准,不因客户端未收到响应就判断未执行。
Chat 通用参数
参数范围:下表为 TTS / Lyria 的已接入参数。Suno 使用 model、messages(role: "user"、非空 content)、stream: false,可选传 instrumental、n、duration;不要照搬 output_format、audio、speakers、temperature、stream_options;完整说明见 Suno 页面。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 使用上表中的完整 ID,大小写及后缀须准确。 |
messages | object[] | 是 | 本站示例使用一条 user 消息;实际以最后一条 user 消息中的文本作为音频输入,不把整段对话当作脚本。 |
messages[0].role | string | 是 | 单消息示例固定 user。 |
messages[0].content | string | 是 | 非空文本。TTS 填朗读文本 / 对话剧本及语气;Lyria 填音乐描述,可在同一文本中附上歌词。 |
stream | boolean | 否 | 建议明确传 false,等待完整 JSON;也支持 true 的 SSE。不是字符串 "false" / "true"。 |
output_format | string | 否 | url(默认)返回音频临时链接;base64 返回音频 Data URI;both 同时返回两者。只控制交付方式,不改变音频编码。Chat 返回 JSON 或 SSE,不直接返回二进制音频。 |
temperature | number | 否 | 网关 Chat 接受 0–2;音频说明也列为可选。不传时使用服务端默认,文档未明确音频默认值,也不承诺调整后必然产生某种音频效果。 |
stream_options.include_usage | boolean | 否 | 通用 Chat 流式选项,设为 true 可请求末尾用量块;仅在 stream: true 时发送。是否返回以实际响应为准,不改变按次公开售价。 |
audio | object | TTS 可选 | 仅 TTS 用于选择音色和 WAV / PCM,详见配音页面。Lyria 不需要发送。 |
speakers | object[] | 双人 TTS 需要 | 两位说话人的 name / voice,与消息里的角色标记对应。 |
音乐描述与歌词、配音语气都可以放在消息正文;不要把其他接口的顶层 prompt、input、lyrics、instructions、voice、音频编码字符串 response_format 搬入本页 Chat 请求。Chat 的 TTS 音色 / 编码使用 audio.voice / audio.format。
普通聊天参数如 max_tokens、top_p、n、seed、工具调用和惩罚系数,不代表这些音频模型提供相应能力;本站音频示例与调试台只发送本页确认的参数。TTS / Lyria 没有可指定的音频秒数参数;Suno 可传期望 duration,但不保证生效。参考音频上传、声音克隆及任务查询未在本文接入。
同步与流式
以下 SSE 行为适用于 TTS / Lyria;Suno 当前使用 stream: false 的非流式调用。
音频是生成完成后一次交付;无需查询任务,返回 id 用于排查,不作为异步轮询 ID。
stream: false:保持连接等待,返回完整chat.completionJSON。stream: true:按 SSE 接收 Chat 分片,完整音频通常在最后的delta.content中返回。先累积所有delta.content,再提取音频链接或 Data URI;不能假定一个 SSE 分片就是完整 HTML 标签。- 正常结束看
finish_reason: "stop",标准 Chat SSE 最后为data: [DONE]。不要把 HTTP 200、收到部分 Base64 或连接突然关闭直接视为成功。 - 流式返回 HTTP 200 后,失败可能表现为正文
错误: ...、错误事件或流中断。非流式错误通常使用 4xx / 5xx;均需检查内容。
客户端读取超时建议 至少 180 秒;TTS 一句话约 3–5 秒、Lyria 一首约 20–60 秒仅为参考,不是服务完成时间保证。流式也不是边生成边播放。本站调试台默认非流式,允许切换 SSE,并在流结束后展示结果。
返回结果与解析
以下 URL / Base64 包装为 TTS / Lyria 的 Chat 约定,Suno 的返回说明见 Suno 页面。
URL 模式下的 Chat 响应结构如下;示例链接不可直接使用:
json
{
"id": "chatcmpl_example",
"object": "chat.completion",
"model": "gemini-3.8-flash-tts",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "<audio controls src=\"https://example.com/speech.wav\"></audio>"
},
"finish_reason": "stop"
}]
}| 字段 | 说明 |
|---|---|
id | 响应标识,保留供排查;不要据此轮询。 |
model | 服务端返回的模型 ID。 |
choices[].message.content | 非流式结果正文,包含 <audio ... src="...">;音乐还可能在标签前附带结构 / 歌词文本。不是音频文件本身。 |
choices[].delta.content | SSE 分片中的正文增量,累积后按同样规则解析。 |
choices[].finish_reason | stop 为正常结束;其他原因或缺失需结合错误及原始响应判断。 |
usage | 可能返回的 Chat 用量信息,不据此把公开音频售价改为 Token 计价。 |
output_format 的三种返回方式
| 请求值 | Chat 正文中的结果 | 保存方法 |
|---|---|---|
url(默认) | 一段 <audio>,src 是临时 HTTP(S) 音频链接 | 使用完整链接下载,不附加知梦 API Key。 |
base64 | 一段 <audio>,src 是 data:audio/...;base64,... | 去掉 Data URI 前缀,解码后保存文件。 |
both | 两段 <audio>:先 URL,再 Base64 | 两者是同一份音频的两种交付方式,不是两个生成版本。任选一种保存即可。 |
例如,TTS 的 both 正文形如(省略号不是完整 Base64):
html
<audio controls src="https://example.com/speech.wav"></audio>
<audio controls src="data:audio/wav;base64,..."></audio>Lyria 使用相同结构,链接扩展名为 .mp3,Data URI 的 MIME 为 audio/mpeg。both 的 Base64 使响应体变大,但公开价格仍为 ¥0.30/次。
提取音频标签的 src,只接受合法 HTTP(S) 链接或音频 Data URI;HTML 属性中的 & 要还原为 &,保留完整签名查询参数。不要把返回 HTML 直接插入网页。专用音频接口的 data[].b64_audio 与 Chat 正文中的 Data URI 是不同包装,不要混读。
WAV / MP3 可按浏览器支持情况试听;裸 PCM 缺少文件头,通常不能直接用浏览器播放器试听。调试台会提供 PCM 下载,格式为 16bit / 24kHz / 单声道,字节序等未明确的细节以实际文件为准。
URL 是临时文件链接,生成后及时下载,不承诺固定有效期、刷新方式或永久保留。Base64 数据已包含音频内容,可在本地解码保存;both 可在链接失效后使用已经收到的完整 Base64。没有固定音频时长保证。
Python:非流式调用与获取结果
python
import base64
import os
import re
from pathlib import Path
from html.parser import HTMLParser
from urllib.parse import urlsplit
import requests
OUTPUT_FORMAT = "url" # url / base64 / both
class AudioSources(HTMLParser):
def __init__(self):
super().__init__(convert_charrefs=True)
self.urls = []
self.clips = []
def handle_starttag(self, tag, attrs):
if tag not in ("audio", "source"):
return
src = dict(attrs).get("src", "")
parsed = urlsplit(src)
if parsed.scheme in ("http", "https") and parsed.hostname and not parsed.username and not parsed.password:
if src not in self.urls:
self.urls.append(src)
return
match = re.fullmatch(r"data:audio/(?:wav|x-wav|mpeg|mp3|pcm|l16)(?:;[a-z0-9_=.-]+)*;base64,([A-Za-z0-9+/=\s]+)", src, re.I)
if match:
encoded = re.sub(r"\s+", "", match.group(1))
self.clips.append(base64.b64decode(encoded, validate=True))
response = requests.post(
"https://api.zmoapi.cn/v1/chat/completions",
headers={"Authorization": "Bearer " + os.environ["ZHIMENG_API_KEY"]},
json={
"model": "lyria-3.5",
"messages": [{"role": "user", "content": "轻柔钢琴纯音乐,不要人声"}],
"stream": False,
"output_format": OUTPUT_FORMAT,
},
timeout=(10, 180),
)
response.raise_for_status()
result = response.json()
if result.get("error"):
raise RuntimeError(result["error"])
parser = AudioSources()
for choice in result.get("choices", []):
if choice.get("finish_reason") != "stop":
raise RuntimeError("音频响应未正常结束")
content = (choice.get("message") or {}).get("content", "")
if content.lstrip().lower().startswith(("错误:", "错误:", "error:")):
raise RuntimeError(content)
parser.feed(content)
if not parser.urls and not parser.clips:
raise RuntimeError("没有音频,请查看原始响应和消费记录")
# both 包含同一音频的两种表示;有 Base64 时直接保存,不重复下载 URL。
if parser.clips:
for index, audio_bytes in enumerate(parser.clips, 1):
Path(f"song-{index}.mp3").write_bytes(audio_bytes)
else:
for index, url in enumerate(parser.urls, 1):
# 独立下载,不携带知梦 API Key,完整保留签名查询参数。
with requests.get(url, stream=True, timeout=(10, 180)) as audio:
audio.raise_for_status()
with Path(f"song-{index}.mp3").open("wb") as file:
for chunk in audio.iter_content(65536):
file.write(chunk)请求超时不代表服务端没有执行;不要为收费生成请求开启无条件自动重试。Python 的读取超时与连接超时是客户端设置,不是平台 SLA。
错误与调试
| 情况 | 处理 |
|---|---|
| 400 | 检查模型 ID、消息文本、音色名、TTS 音频格式、说话人配置和返回的上游原因。 |
| 401 / 403 | 检查知梦 API 密钥、余额、分组及模型权限。 |
| 429 | 等待后再人工确认是否重试,避免重复提交风暴。 |
| 5xx / 断连 / 超时 | 保留响应 ID 和消费记录,先确认任务是否执行;不要盲目重复生成。 |
| HTTP 200 但正文为“错误: …” | 仍是失败,流式尤其要检查正文;不能只看状态码。 |
没有音频或 finish_reason 非 stop | 检查完整 JSON / SSE Raw,不当作生成成功。 |
| 有音频但不能试听 | URL 检查链接是否仍有效;Base64 检查数据完整性及 MIME;裸 PCM 通常不能直接在浏览器播放。 |
调试台支持四个音频模型,默认非流式。TTS / Lyria 可选 url / base64 / both,TTS 支持音色和双人剧本;both 合并为一项音频,同时提供链接和 Base64 的复制 / 下载入口;Suno 支持纯音乐偏好、n 和期望时长,解析全部 M4A 链接并按 URL 去重;导出调试信息会隐藏 API Key。Base64 导出可能较大,原始响应保留完整内容。