语音生成
使用 POST /v1/audio/speech 生成音频。请求遵循 OpenAI Speech JSON 协议,成功响应是音频字节而不是 JSON。
请求
地址:https://api.inoneapi.com/v1/audio/speech。密钥仅放在服务端。公开模型必须存在音频映射,不回退其他 API 类型。示例 model 为占位符,请替换成控制台可用模型。
| 参数 | 类型 | 详细说明 |
|---|---|---|
| model | string | 必填公共模型 ID,网关替换为上游模型 ID。 |
| input | string | 必填非空文本,网关不自动截断、分段、拼接或转换 SSML。 |
| voice | string/object | 必填非空音色名,或 {"id":"voice_123"} 自定义音色对象;需要模型和账号支持。音色名并非跨服务商通用。 |
| instructions | string | 可选语气、情绪和风格提示,仅支持的模型有效,不是 input 的替代字段。 |
| response_format | string | 默认 mp3;固定格式 Base64 映射只接受其配置格式。不是 url、base64 或 json。 |
| speed | number | 0.25–4;省略时由上游决定默认值,上游可能有更严格限制。 |
| stream_format | string | 默认 audio;sse 只用于支持 SSE 的原生渠道。HTTP 分块音频不等于 SSE。 |
必填字段为 model、input、voice;可选字段为 instructions、response_format(mp3、opus、aac、flac、wav、pcm)、speed(0.25–4)和 stream_format(audio 或 sse)。不要发送 Chat 风格的 stream 字段。音色、输入长度和格式能力取决于模型。
curl --fail-with-body https://api.inoneapi.com/v1/audio/speech \
-H "Authorization: Bearer $INONEAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "provider/speech-model","input": "你好。","voice": "alloy","response_format": "mp3"}' \
--output speech.mp3cURL 必须检查退出码:--fail-with-body 仍可能把错误 JSON 写入 speech.mp3。不要把错误响应当音频播放。成功响应不要调用 response.json()。JavaScript 和 TypeScript 示例会完整缓冲文件,大文件宜使用流式保存;Python 示例会分块保存,非 2xx 会抛出 HTTPError。
响应、流式与错误
成功时不要调用 response.json()。JavaScript 保存字节示例:
import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.inoneapi.com/v1/audio/speech", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INONEAPI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "provider/speech-model",
input: "你好。",
voice: "alloy",
response_format: "mp3"
})
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
await writeFile("speech.mp3", Buffer.from(await response.arrayBuffer()));
Python 分块保存,非 2xx 会抛出 HTTPError:
import json, os, urllib.request
request = urllib.request.Request(
"https://api.inoneapi.com/v1/audio/speech",
data=json.dumps({
"model": "provider/speech-model",
"input": "你好。",
"voice": "alloy",
"response_format": "mp3",
}).encode(),
headers={
"Authorization": "Bearer " + os.environ["INONEAPI_API_KEY"],
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request, timeout=180) as response:
with open("speech.mp3", "wb") as output:
while chunk := response.read(65536):
output.write(chunk)
cURL 必须检查退出码:--fail-with-body 仍可能把错误 JSON 写入 speech.mp3。不要把错误响应当音频播放。JavaScript 例完整缓冲文件,大文件宜使用流式保存。
| 格式 | MIME 与使用要求 |
|---|---|
| mp3 | audio/mpeg,默认格式。 |
| opus | audio/ogg;Base64 DSL 声明 opus 要求上游实际返回 Ogg Opus。 |
| aac | audio/aac,实际封装和终端支持取决于服务商。 |
| flac | audio/flac,无损,文件可能更大。 |
| wav | audio/wav,包含容器头,采样参数以实际音频为准。 |
| pcm | application/octet-stream,无容器头;必须确认采样率、位深、声道和端序。 |
原生保留 MIME 和字节。Base64 DSL 声明 MIME,但不转码或验证编码真实性。默认 audio 路径可能先缓冲部分响应,不保证逐字节即时转发。
原生 SSE 示例:
curl -N https://api.inoneapi.com/v1/audio/speech \
-H "Authorization: Bearer $INONEAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"provider/speech-model","input":"Hello!","voice":"alloy","stream_format":"sse"}'
SSE 使用 text/event-stream;按服务商规范解析音频事件与片段,不能把整个 SSE 文本保存成 MP3。DSL 返回 400 PROTOCOL_STREAM_UNSUPPORTED。
| 错误 | 排查 |
|---|---|
| 400 INVALID_REQUEST_BODY | 必填值、类型、speed 范围、格式枚举错误,或错误使用 stream。 |
| 400 PROTOCOL_TRANSFORM_FAILED | 必填映射值缺失或未知枚举。 |
| 400 AUDIO_FORMAT_UNSUPPORTED | response_format 与固定格式不符;省略时按 mp3。 |
| 401/403 | 检查密钥、权限和模型限制。 |
| 429 | 遵循 Retry-After,检查预算与限流。 |
| 502 PROTOCOL_RESPONSE_TRANSFORM_FAILED | 上游 JSON/Base64/路径无效或缓冲超限。 |
上游错误不执行成功音频转换。超时可能已经生成和收费,不应无限重试。排障保留 X-Gateway-Trace-ID,不记录密钥和敏感朗读文本。明确告知使用者音频由 AI 生成。此端点不提供转写、翻译、Realtime、URL 下载、转码或任务轮询。
响应 MIME 通常为 audio/mpeg、audio/ogg、audio/aac、audio/flac、audio/wav 或 application/octet-stream(PCM)。PCM 没有 WAV 头,不能仅通过改扩展名播放。原生服务商支持时可使用 stream_format=sse;DSL 转换和 Base64 音频提取不支持 SSE。400 表示参数或映射错误,429 应遵循 Retry-After,502 表示响应转换失败或超出默认 32 MiB 缓冲区。
管理员配置
在映射管理中选择“音频 API”,配置 audio_path。原生模式默认开启;关闭后填写 request DSL 和可选 audio_response。完整 schema、AI 生成规范、四方向 fixture、异常矩阵、计量和能力边界见 docs/audio-protocol-dsl.md 与 docs/audio-protocol-dsl.schema.json。
测试按钮仅校验配置结构并生成示意 cURL,不调用真实上游。原生保存 {"version":1};音频不使用通用 response/retrieve JSON 转换阶段。
计量与计费使用独立 metering_config/billing_config。Base64 模式读取原始上游 JSON usage,不读解码字节。原生二进制通常没有 JSON usage;缺失计量不代表免费。当前计量 DSL 不计算字符串长度或音频时长,按字符/秒收费需可靠计量来源或专门适配器。响应缓冲限制包含 JSON 与 Base64 开销,并发内存还需考虑解码后的字节。