解説動画
あらゆるコンテンツを、AI が生成した画像と音声ナレーション付きの解説動画に変換します。
解説動画では、テキストや URL からナレーション付きのビジュアルコンテンツを作成できます。2 つのモードがあります:
info(デフォルト) | story | |
|---|---|---|
| 用途 | 知識解説、製品紹介 | ストーリー共有、事例紹介 |
| 画像スタイル | インフォグラフィック、イラスト、データビジュアライゼーション | ストーリーシーンのイラスト |
| 1 ページ目 | 雑誌風の表紙 | ストーリーの表紙 |
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", "uri": "https://example.com/article", "content": "https://example.com/article"}
],
"speakers": [
{"speakerId": "<SPEAKER_ID>"}
],
"language": "en",
"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', uri: 'https://example.com/article', content: 'https://example.com/article' }],
speakers: [{ speakerId: '<SPEAKER_ID>' }],
language: 'en',
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', 'uri': 'https://example.com/article', 'content': 'https://example.com/article'}],
'speakers': [{'speakerId': '<SPEAKER_ID>'}],
'language': 'en',
'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": "The founding story of a small startup that grew into a global platform..."}
],
"speakers": [
{"speakerId": "<SPEAKER_ID>"}
],
"language": "en",
"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: 'The founding story of a small startup that grew into a global platform...' }],
speakers: [{ speakerId: '<SPEAKER_ID>' }],
language: 'en',
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': 'The founding story of a small startup that grew into a global platform...'}],
'speakers': [{'speakerId': '<SPEAKER_ID>'}],
'language': 'en',
'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 | type が url の場合は必須 | ソースの URI |
| sources[].metadata | object | いいえ | ソースのメタデータ |
| speakers | array(1) | はい | 音声設定。最大 1 件。 |
| speakers[].speakerId | string | はい | 話者 ID(話者一覧 を参照) |
| language | string | いいえ | 言語コード(例:"en"、"zh") |
| 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('Status:', 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('Status:', data['data']['processStatus'])レスポンス(processStatus が success のとき):
{
"code": 0,
"message": "",
"data": {
"episodeId": "{episodeId}",
"createdAt": 1700000000,
"mode": "info",
"processStatus": "success",
"credits": 30,
"title": "How AI Is Changing the World",
"cover": "https://assets.listenhub.ai/covers/{episodeId}.png",
"audioUrl": "https://assets.listenhub.ai/storybook/{episodeId}.mp3",
"audioDuration": 180,
"videoUrl": "",
"videoStatus": "not_generated",
"pages": [
{
"text": "Artificial intelligence has transformed industries worldwide...",
"pageNumber": 1,
"imageUrl": "https://assets.listenhub.ai/pages/{episodeId}-1.png",
"audioTimestamp": 0
},
{
"text": "From healthcare to finance, AI applications continue to expand...",
"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
}
}トリガー後は、videoStatus が success になるまで GET /v1/storybook/episodes/{episodeId} をポーリングします。
完全なワークフロー
エピソードを作成する
コンテンツソース、話者、モード(info または story)を指定して POST /v1/storybook/episodes を呼び出します。返された episodeId を保存してください。
完了までポーリングする
最初に 60 秒待ってから、processStatus が success になるまで GET /v1/storybook/episodes/{episodeId} を 10 秒ごとにポーリングします。
素材を利用する(任意)
pages[] 配列には、各ページの AI 生成画像(imageUrl)とナレーション原稿(text)が含まれます。動画を生成せずに、そのまま利用できます。
動画を生成する
POST /v1/storybook/episodes/{episodeId}/video を呼び出して、各ページをナレーション付きの動画に合成します。
動画ステータスをポーリングする
videoStatus が success になるまでポーリングします。videoUrl フィールドにダウンロードリンクが入ります。