解说视频
将任意内容转化为带有 AI 生成画面和语音旁白的解说视频。
解说视频可以将文本或 URL 内容转化为带有画面和旁白的可视化内容,支持两种模式:
info(默认) | story | |
|---|---|---|
| 定位 | 知识讲解、产品介绍 | 故事讲述、案例分享 |
| 图片风格 | 信息图、插画、数据可视化 | 故事场景插画 |
| 首页 | 杂志式封面 | 故事封面 |
mode 参数可选,默认为 info。
创建单集
POST /v1/storybook/episodes
创建一个解说视频单集,自动生成 AI 画面与语音旁白。
sources 最多 1 项,speakers 最多 1 项。
Info 模式(默认):
curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{"type": "url", "content": "https://example.com/article"}
],
"speakers": [
{"speakerId": "CN-Man-Beijing-V2"}
],
"language": "zh",
"mode": "info"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/storybook/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' }],
speakers: [{ speakerId: 'CN-Man-Beijing-V2' }],
language: 'zh',
mode: 'info',
}),
});
const data = await response.json();
console.log(data);import os, requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/storybook/episodes',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'sources': [{'type': 'url', 'content': 'https://example.com/article'}],
'speakers': [{'speakerId': 'CN-Man-Beijing-V2'}],
'language': 'zh',
'mode': 'info',
}
)
print(response.json())Story 模式:
curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{"type": "text", "content": "一家小创业公司如何成长为全球平台的创业故事..."}
],
"speakers": [
{"speakerId": "CN-Man-Beijing-V2"}
],
"language": "zh",
"mode": "story"
}'const response = await fetch('https://api.marswave.ai/openapi/v1/storybook/episodes', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sources: [{ type: 'text', content: '一家小创业公司如何成长为全球平台的创业故事...' }],
speakers: [{ speakerId: 'CN-Man-Beijing-V2' }],
language: 'zh',
mode: 'story',
}),
});
const data = await response.json();
console.log(data);import os, requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/storybook/episodes',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'sources': [{'type': 'text', 'content': '一家小创业公司如何成长为全球平台的创业故事...'}],
'speakers': [{'speakerId': 'CN-Man-Beijing-V2'}],
'language': 'zh',
'mode': 'story',
}
)
print(response.json())响应:
{
"code": 0,
"message": "",
"data": {
"episodeId": "{episodeId}"
}
}请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| sources | array(1) | 是 | 内容来源,最多 1 个 |
| sources[].type | string | 是 | "text" 或 "url" |
| sources[].content | string | 是 | 文本内容或 URL |
| sources[].uri | string | 否 | 来源 URI |
| sources[].metadata | object | 否 | 来源元数据 |
| speakers | array(1) | 是 | 语音配置,最多 1 个 |
| speakers[].speakerId | string | 是 | 说话人 ID(参见音色列表) |
| language | string | 否 | 语言代码(如 "zh"、"en") |
| mode | string | 否 | "info"(默认)或 "story" |
| style | string | 否 | 视觉风格 ID |
查询单集状态
GET /v1/storybook/episodes/{episodeId}
用返回的 episodeId 轮询查询,直到 processStatus 为 success。
curl "https://api.marswave.ai/openapi/v1/storybook/episodes/{episodeId}" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"const response = await fetch(
`https://api.marswave.ai/openapi/v1/storybook/episodes/${episodeId}`,
{ headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` } }
);
const data = await response.json();
console.log('状态:', data.data.processStatus);import os, requests
response = requests.get(
f'https://api.marswave.ai/openapi/v1/storybook/episodes/{episode_id}',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
data = response.json()
print('状态:', data['data']['processStatus'])响应(processStatus 为 success 时):
{
"code": 0,
"message": "",
"data": {
"episodeId": "{episodeId}",
"createdAt": 1700000000,
"mode": "info",
"processStatus": "success",
"credits": 30,
"title": "AI 如何改变世界",
"cover": "https://assets.listenhub.ai/covers/{episodeId}.png",
"audioUrl": "https://assets.listenhub.ai/storybook/{episodeId}.mp3",
"audioDuration": 180,
"videoUrl": "",
"videoStatus": "not_generated",
"pages": [
{
"text": "人工智能已经深刻改变了全球各行各业...",
"pageNumber": 1,
"imageUrl": "https://assets.listenhub.ai/pages/{episodeId}-1.png",
"audioTimestamp": 0
},
{
"text": "从医疗到金融,AI 的应用场景持续扩大...",
"pageNumber": 2,
"imageUrl": "https://assets.listenhub.ai/pages/{episodeId}-2.png",
"audioTimestamp": 25.3
}
]
}
}图片 + 旁白素材:pages[] 中的 imageUrl(AI 生成图片)和 text(旁白文本)可作为独立素材使用,无需生成视频即可下载使用。
processStatus 状态
| 值 | 含义 |
|---|---|
pending | 处理中 |
success | 生成完成 |
fail | 生成失败(查看 failCode) |
videoStatus 状态
| 值 | 含义 |
|---|---|
not_generated | 未触发视频生成 |
pending | 视频生成中 |
success | 视频就绪(videoUrl 可用) |
fail | 视频生成失败 |
生成通常需要 2–5 分钟。推荐轮询策略:等待 60 秒后开始,每 10 秒查询一次。
生成视频
POST /v1/storybook/episodes/{episodeId}/video
为已完成的单集触发视频生成,processStatus 必须为 success。
必须等待 processStatus 为 success 后才能调用此接口。
curl -X POST "https://api.marswave.ai/openapi/v1/storybook/episodes/{episodeId}/video" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"const response = await fetch(
`https://api.marswave.ai/openapi/v1/storybook/episodes/${episodeId}/video`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.LISTENHUB_API_KEY}` },
}
);
console.log(await response.json());import os, requests
response = requests.post(
f'https://api.marswave.ai/openapi/v1/storybook/episodes/{episode_id}/video',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'}
)
print(response.json())响应:
{
"code": 0,
"message": "",
"data": {
"success": true
}
}触发后,继续轮询 GET /v1/storybook/episodes/{episodeId},等待 videoStatus 为 success。
完整工作流
创建单集
调用 POST /v1/storybook/episodes,传入内容来源、音色和模式(info 或 story),保存返回的 episodeId。
轮询等待完成
轮询 GET /v1/storybook/episodes/{episodeId}(初始等待 60 秒,之后每 10 秒查询),直到 processStatus 为 success。
使用素材(可选)
pages[] 数组包含每页的 AI 生成图片(imageUrl)和旁白文本(text),可直接使用,无需生成视频。
生成视频
调用 POST /v1/storybook/episodes/{episodeId}/video,将各页合成为带旁白的视频。
轮询视频状态
继续轮询直到 videoStatus 为 success,videoUrl 即为下载链接。