API 参考
文本转语音
将文本转为自然语音。三种接口覆盖从低延迟单音色到 AI 智能润色的全场景需求。
ListenHub 提供三种文本转语音接口,适用于不同场景:
| 接口 | 特点 | 响应方式 | 适用场景 |
|---|---|---|---|
/v1/tts | 单音色,低延迟 | 同步,返回 MP3 二进制流 | 实时播放、语音通知 |
/v1/speech | 多音色脚本,同步返回 | 同步,返回 JSON(含 audioUrl) | 有声书、广播剧、对话音频 |
/v1/flow-speech/episodes | AI 润色/原文直转,支持 URL | 异步,返回 episodeId 后轮询 | 文章朗读、Newsletter 语音版 |
单音色 TTS
POST /v1/tts
低延迟单音色文本转语音,返回流式二进制音频(MP3)。适合实时播放和应用内语音功能。
curl -X POST "https://api.marswave.ai/openapi/v1/tts" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": "你好,欢迎使用 ListenHub 文本转语音服务。",
"voice": "CN-Man-Beijing-V2"
}' \
--output output.mp3const response = await fetch('https://api.marswave.ai/openapi/v1/tts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
input: '你好,欢迎使用 ListenHub 文本转语音服务。',
voice: 'CN-Man-Beijing-V2',
}),
});
const blob = await response.blob();
// 保存或播放音频 blobimport os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/tts',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'input': '你好,欢迎使用 ListenHub 文本转语音服务。',
'voice': 'CN-Man-Beijing-V2',
},
stream=True
)
with open('output.mp3', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
input | string | 是 | 要转换的文本 |
voice | string | 是 | 音色 ID(即 speakerId) |
model | string | 否 | 模型名称,默认 flowtts |
响应为流式二进制 MP3 音频,不是 JSON。HTTP 客户端需使用流式方式处理响应。出错时返回 JSON 错误对象。
多角色脚本转语音
POST /v1/speech
使用预先准备好的脚本生成多角色语音,每行台词可以指定不同的音色。同步返回音频 URL。
curl -X POST "https://api.marswave.ai/openapi/v1/speech" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scripts": [
{
"content": "大家好,欢迎收听今天的节目",
"speakerId": "CN-Man-Beijing-V2"
},
{
"content": "今天我们要聊一个有趣的话题",
"speakerId": "chat-girl-105-cn"
},
{
"content": "是的,让我们开始吧",
"speakerId": "CN-Man-Beijing-V2"
}
]
}'const response = await fetch('https://api.marswave.ai/openapi/v1/speech', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
scripts: [
{ content: '大家好,欢迎收听今天的节目', speakerId: 'CN-Man-Beijing-V2' },
{ content: '今天我们要聊一个有趣的话题', speakerId: 'chat-girl-105-cn' },
{ content: '是的,让我们开始吧', speakerId: 'CN-Man-Beijing-V2' },
],
}),
});
const data = await response.json();
console.log(data.data.audioUrl);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/speech',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'scripts': [
{'content': '大家好,欢迎收听今天的节目', 'speakerId': 'CN-Man-Beijing-V2'},
{'content': '今天我们要聊一个有趣的话题', 'speakerId': 'chat-girl-105-cn'},
{'content': '是的,让我们开始吧', 'speakerId': 'CN-Man-Beijing-V2'},
]
}
)
data = response.json()
print(data['data']['audioUrl'])请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
scripts | array | 是 | 脚本数组 |
scripts[].content | string | 是 | 台词文本 |
scripts[].speakerId | string | 是 | 音色 ID |
title | string | 否 | 自定义标题(不提供则自动生成) |
响应示例:
{
"code": 0,
"message": "",
"data": {
"audioUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/example.mp3",
"audioDuration": 12500,
"subtitlesUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/example.srt",
"taskId": "1eed39d387a046c0a1213e6b8f139d77",
"credits": 12
}
}响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
audioUrl | string | MP3 音频文件 URL |
audioDuration | integer | 音频时长(毫秒) |
subtitlesUrl | string | SRT 字幕文件 URL |
taskId | string | 任务 ID |
credits | integer | 实际消耗的积分 |
长文本转语音
POST /v1/flow-speech/episodes
将文本或 URL 内容转为语音,支持 AI 润色和原文直转两种模式。异步任务——提交请求后轮询获取结果。单次内容至少 10 个字符。
Smart 模式(AI 润色)
自动修正语法、排版和标点后再合成:
curl -X POST "https://api.marswave.ai/openapi/v1/flow-speech/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{
"type": "text",
"content": "欢迎使用ListenHub音频生成服务这是一段测试文本会自动修复错别字和标点符号"
}
],
"speakers": [
{"speakerId": "chat-girl-105-cn"}
],
"language": "zh",
"mode": "smart"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/flow-speech/episodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sources: [
{
type: 'text',
content: '欢迎使用ListenHub音频生成服务这是一段测试文本会自动修复错别字和标点符号',
},
],
speakers: [{ speakerId: 'chat-girl-105-cn' }],
language: 'zh',
mode: 'smart',
}),
});
const data = await response.json();
console.log('Episode ID:', data.data.episodeId);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/flow-speech/episodes',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'sources': [
{
'type': 'text',
'content': '欢迎使用ListenHub音频生成服务这是一段测试文本会自动修复错别字和标点符号',
}
],
'speakers': [{'speakerId': 'chat-girl-105-cn'}],
'language': 'zh',
'mode': 'smart',
}
)
data = response.json()
print('Episode ID:', data['data']['episodeId'])Direct 模式(原文直转)
不修改内容,原文直接转为语音:
curl -X POST "https://api.marswave.ai/openapi/v1/flow-speech/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{
"type": "text",
"content": "欢迎使用 ListenHub 音频生成服务。这是一段已经完善的文本,将直接转换为语音。"
}
],
"speakers": [
{"speakerId": "CN-Man-Beijing-V2"}
],
"language": "zh",
"mode": "direct"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/flow-speech/episodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sources: [
{
type: 'text',
content: '欢迎使用 ListenHub 音频生成服务。这是一段已经完善的文本,将直接转换为语音。',
},
],
speakers: [{ speakerId: 'CN-Man-Beijing-V2' }],
language: 'zh',
mode: 'direct',
}),
});
const data = await response.json();
console.log('Episode ID:', data.data.episodeId);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/flow-speech/episodes',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'sources': [
{
'type': 'text',
'content': '欢迎使用 ListenHub 音频生成服务。这是一段已经完善的文本,将直接转换为语音。',
}
],
'speakers': [{'speakerId': 'CN-Man-Beijing-V2'}],
'language': 'zh',
'mode': 'direct',
}
)
data = response.json()
print('Episode ID:', data['data']['episodeId'])从 URL 读取内容
curl -X POST "https://api.marswave.ai/openapi/v1/flow-speech/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{
"type": "url",
"content": "https://example.com/article.html"
}
],
"speakers": [
{"speakerId": "chat-girl-105-cn"}
],
"language": "zh",
"mode": "smart"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/flow-speech/episodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sources: [{ type: 'url', content: 'https://example.com/article.html' }],
speakers: [{ speakerId: 'chat-girl-105-cn' }],
language: 'zh',
mode: 'smart',
}),
});
const data = await response.json();
console.log('Episode ID:', data.data.episodeId);import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/flow-speech/episodes',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'sources': [{'type': 'url', 'content': 'https://example.com/article.html'}],
'speakers': [{'speakerId': 'chat-girl-105-cn'}],
'language': 'zh',
'mode': 'smart',
}
)
data = response.json()
print('Episode ID:', data['data']['episodeId'])请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
sources | array | 是 | 内容来源,最多 1 项 |
sources[].type | string | 是 | text 或 url |
sources[].content | string | 是 | 文本内容或 URL |
speakers | array | 是 | 音色列表,1-2 个 |
speakers[].speakerId | string | 是 | 音色 ID |
language | string | 否 | 语言:en、zh、ja |
mode | string | 否 | smart(AI 润色)或 direct(原文直转) |
查询结果
GET /v1/flow-speech/episodes/{episodeId}
使用返回的 episodeId 轮询状态,直到 processStatus 为 success:
curl -X GET "https://api.marswave.ai/openapi/v1/flow-speech/episodes/{episodeId}" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"const response = await fetch(
`https://api.marswave.ai/openapi/v1/flow-speech/episodes/${episodeId}`,
{
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
}
);
const data = await response.json();
console.log('状态:', data.data.processStatus);
console.log('音频地址:', data.data.audioUrl);import os
import requests
response = requests.get(
f'https://api.marswave.ai/openapi/v1/flow-speech/episodes/{episode_id}',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
data = response.json()
print('状态:', data['data']['processStatus'])
print('音频地址:', data['data']['audioUrl'])生成完成时的响应(processStatus: "success"):
{
"code": 0,
"message": "",
"data": {
"episodeId": "{episodeId}",
"processStatus": "success",
"credits": 18,
"title": "文章标题",
"audioUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/{episodeId}.mp3",
"audioStreamUrl": "https://assets.listenhub.ai/listenhub-public-prod/podcast/{episodeId}.m3u8",
"scripts": "完整的朗读脚本文本..."
}
}长文本转语音通常在 1-2 分钟内完成。推荐轮询策略:创建后等待 30 秒,之后每 10 秒查询一次。若生成失败,processStatus 为 failed,failCode 说明失败原因。