MiniMax 语音合成
通过/v1/audio/speech 接口将文本转换为自然语音。接口支持两种输出方式:
- 非流式:生成完成后返回音频文件 URL,适合配音、有声内容等场景。
- 流式:通过 SSE 持续返回音频分片,适合语音助手、实时播报等低延迟场景。
可用模型
| 模型 |
|---|
speech-2.6-hd |
speech-2.6-turbo |
speech-02-hd |
speech-02-turbo |
speech-02 |
speech-2.5-hd-preview |
speech-2.5-turbo-preview |
speech-01-hd |
非流式语音合成
只需提供模型、文本和音色。生成完成后,从响应的url 下载或播放音频。
curl --request POST \
--url https://model-api.skyengine.com.cn/v1/audio/speech \
--header 'Authorization: Bearer <API-KEY>' \
--header 'Content-Type: application/json' \
--data '{
"model": "speech-2.6-hd",
"input": "欢迎使用 ModelHub 语音合成服务。",
"voice": "male-qn-qingse",
"speed": 1.0,
"response_format": "mp3"
}'
import requests
API_KEY = "<API-KEY>"
BASE_URL = "https://model-api.skyengine.com.cn/v1"
response = requests.post(
f"{BASE_URL}/audio/speech",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "speech-2.6-hd",
"input": "欢迎使用 ModelHub 语音合成服务。",
"voice": "male-qn-qingse",
"speed": 1.0,
"response_format": "mp3",
},
timeout=120,
)
response.raise_for_status()
result = response.json()
print("音频地址:", result["url"])
print("音频时长(毫秒):", result.get("duration_ms"))
const response = await fetch("https://model-api.skyengine.com.cn/v1/audio/speech", {
method: "POST",
headers: {
"Authorization": "Bearer <API-KEY>",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "speech-2.6-hd",
input: "欢迎使用 ModelHub 语音合成服务。",
voice: "male-qn-qingse",
speed: 1.0,
response_format: "mp3"
})
});
if (!response.ok) throw new Error(await response.text());
const result = await response.json();
console.log("音频地址:", result.url);
console.log("音频时长(毫秒):", result.duration_ms);
{
"request_id": "9f72f...",
"url": "https://.../tts_xxx.mp3",
"duration_ms": 3204,
"token": 23
}
| 响应字段 | 说明 |
|---|---|
request_id | 本次语音合成请求 ID。 |
url | 生成音频的访问地址。请及时转存,不要依赖其永久有效。 |
subtitle_url | 开启字幕后返回的字幕文件地址。 |
duration_ms | 音频时长,单位为毫秒。 |
token | 本次请求计费使用的字符数。 |
流式语音合成
设置stream: true 后,接口返回 text/event-stream。每条 SSE 消息中的 audio 是 Base64 编码的 MP3 分片。
curl --no-buffer --request POST \
--url https://model-api.skyengine.com.cn/v1/audio/speech \
--header 'Authorization: Bearer <API-KEY>' \
--header 'Content-Type: application/json' \
--data '{
"model": "speech-2.6-turbo",
"input": "这是一段流式语音合成示例。",
"voice": "female-shaonv",
"response_format": "mp3",
"stream": true
}'
import base64
import json
import requests
response = requests.post(
"https://model-api.skyengine.com.cn/v1/audio/speech",
headers={"Authorization": "Bearer <API-KEY>"},
json={
"model": "speech-2.6-turbo",
"input": "这是一段流式语音合成示例。",
"voice": "female-shaonv",
"response_format": "mp3",
"stream": True,
},
stream=True,
timeout=120,
)
response.raise_for_status()
with open("speech.mp3", "wb") as audio_file:
for line in response.iter_lines(decode_unicode=True):
if not line or not line.startswith("data:"):
continue
event = json.loads(line.removeprefix("data:").strip())
if event.get("error"):
raise RuntimeError(event["error"]["message"])
if event.get("audio"):
audio_file.write(base64.b64decode(event["audio"]))
print("音频已保存为 speech.mp3")
import { createWriteStream } from "node:fs";
const response = await fetch("https://model-api.skyengine.com.cn/v1/audio/speech", {
method: "POST",
headers: {
"Authorization": "Bearer <API-KEY>",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "speech-2.6-turbo",
input: "这是一段流式语音合成示例。",
voice: "female-shaonv",
response_format: "mp3",
stream: true
})
});
if (!response.ok) throw new Error(await response.text());
const output = createWriteStream("speech.mp3");
const decoder = new TextDecoder();
let buffer = "";
for await (const chunk of response.body) {
buffer += decoder.decode(chunk, { stream: true });
const events = buffer.split("\n\n");
buffer = events.pop() ?? "";
for (const eventText of events) {
const dataLine = eventText.split("\n").find(line => line.startsWith("data:"));
if (!dataLine) continue;
const event = JSON.parse(dataLine.slice(5).trim());
if (event.error) throw new Error(event.error.message);
if (event.audio) output.write(Buffer.from(event.audio, "base64"));
}
}
output.end();
console.log("音频已保存为 speech.mp3");
data: {"audio":"<base64-audio-chunk>"}
data: {"audio":"<base64-audio-chunk>"}
data: {"token":15}
流式模式建议使用
mp3。音频分片必须按接收顺序解码并写入同一个文件。请求参数
通用参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
model | string | 是 | - | 要使用的 TTS 模型。 |
input | string | 是 | - | 需要合成的文本。 |
voice | string | 是 | - | 音色 ID。 |
speed | number | 否 | 1.0 | 语速,范围 0.5~2.0。数值越大语速越快。 |
response_format | string | 否 | mp3 | 音频格式,常用值为 mp3、wav、flac。流式模式推荐 mp3。 |
stream | boolean | 否 | false | 是否通过 SSE 流式返回音频。 |
model_extra | object | 否 | - | MiniMax 高级参数。 |
常用音色
| 音色 ID | 音色说明 |
|---|---|
male-qn-qingse | 青涩青年男声 |
male-qn-jingying | 精英青年男声 |
male-qn-badao | 霸道青年男声 |
female-shaonv | 少女音色 |
female-yujie | 御姐音色 |
female-chengshu | 成熟女性音色 |
presenter_male | 男性主持人 |
presenter_female | 女性主持人 |
audiobook_male_1 | 男性有声书音色 |
audiobook_female_1 | 女性有声书音色 |
voice。更多系统音色请参考 MiniMax 官方语音合成文档。
高级参数
高级参数统一放在model_extra 中:
{
"model_extra": {
"vol": 1.2,
"pitch": 2,
"audio_sample_rate": 32000,
"bitrate": 128000,
"language_boost": "Chinese"
}
}
| 参数 | 类型 | 说明 |
|---|---|---|
vol | number | 音量,范围 (0, 10],默认 1.0。 |
pitch | integer | 音调,范围 -12~12,默认 0。 |
audio_sample_rate | integer | 音频采样率,例如 16000、24000、32000、44100。 |
bitrate | integer | MP3 比特率,例如 128000。 |
language_boost | string | 指定语言增强,如 Chinese、English、Chinese,Yue 或 auto。 |
tone | string[] | 自定义发音词典,例如 ["行长/(hang2)(zhang3)"]。 |
timber_weights | object[] | 混合多个音色,每项包含 voice_id 和 weight。最多建议使用 4 个音色。 |
subtitle_enable | boolean | 是否生成字幕文件。 |
subtitle_type | string | 字幕粒度:sentence 或 word。 |
生成字幕
字幕文件请使用非流式模式:{
"model": "speech-2.6-hd",
"input": "这段语音会同时生成词级字幕。",
"voice": "presenter_female",
"response_format": "mp3",
"model_extra": {
"subtitle_enable": true,
"subtitle_type": "word"
}
}
subtitle_url 获取字幕文件。
指定发音
遇到多音字、专有名词或英文缩写时,可以使用tone 指定发音:
{
"model": "speech-2.6-hd",
"input": "银行行长参加会议。",
"voice": "male-qn-jingying",
"model_extra": {
"tone": ["行长/(hang2)(zhang3)"]
}
}
混合音色
使用timber_weights 混合多个系统音色:
{
"model": "speech-2.6-hd",
"input": "这是一段混合音色示例。",
"voice": "female-shaonv",
"model_extra": {
"timber_weights": [
{"voice_id": "male-qn-qingse", "weight": 50},
{"voice_id": "female-shaonv", "weight": 50}
]
}
}
设置
timber_weights 后,最终声音主要由混合音色配置决定。
