Skip to content
Markdown · 适合发给 AI

音频生成 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能力音频格式价格
Googlegemini-3.8-flash-tts文字转语音、自然语言控制语气、单人配音 / 双人对话WAV / PCM¥0.30/次
Googlelyria-3.5根据音乐描述与歌词生成纯音乐或歌曲MP3¥0.30/次
Googlelyria-3-pro-preview高质量版音乐生成,与 3.5 使用相同参数MP3¥0.30/次
Sunosuno-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 页面。

参数类型必填说明
modelstring是使用上表中的完整 ID,大小写及后缀须准确。
messagesobject[]是本站示例使用一条 user 消息;实际以最后一条 user 消息中的文本作为音频输入,不把整段对话当作脚本。
messages[0].rolestring是单消息示例固定 user。
messages[0].contentstring是非空文本。TTS 填朗读文本 / 对话剧本及语气;Lyria 填音乐描述,可在同一文本中附上歌词。
streamboolean否建议明确传 false,等待完整 JSON;也支持 true 的 SSE。不是字符串 "false" / "true"。
output_formatstring否url(默认)返回音频临时链接;base64 返回音频 Data URI;both 同时返回两者。只控制交付方式,不改变音频编码。Chat 返回 JSON 或 SSE,不直接返回二进制音频。
temperaturenumber否网关 Chat 接受 0–2;音频说明也列为可选。不传时使用服务端默认,文档未明确音频默认值,也不承诺调整后必然产生某种音频效果。
stream_options.include_usageboolean否通用 Chat 流式选项,设为 true 可请求末尾用量块;仅在 stream: true 时发送。是否返回以实际响应为准,不改变按次公开售价。
audioobjectTTS 可选仅 TTS 用于选择音色和 WAV / PCM,详见配音页面。Lyria 不需要发送。
speakersobject[]双人 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.completion JSON。
  • 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.contentSSE 分片中的正文增量,累积后按同样规则解析。
choices[].finish_reasonstop 为正常结束;其他原因或缺失需结合错误及原始响应判断。
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 属性中的 &amp; 要还原为 &,保留完整签名查询参数。不要把返回 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 导出可能较大,原始响应保留完整内容。

知梦 API · 图像、视频与音乐生成接口文档