listenhub-voice について
ListenHub-Voice-1.0 でテキストや画像から完成音声を生成するスキルです。記述した効果音、単一または複数話者の音声、参照音声の声質クローンに対応し、非同期タスクで処理します。
主な機能
- 01テキストや画像から音声を生成
- 02記述された効果音を合成
- 03単一または複数話者の対話を生成
- 04参照音声から声質をクローン
- 05音声形式と長さの目安を設定
活用シーン
- 01効果音付きの台本音声を作成
- 02参照音声ごとの声で対話を作成
- 03画像をもとに音声を生成
- 04参照音声を使って音声を生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marswaveai/ skills --skill listenhub-voiceインストール後、Claude Code で/listenhub-voiceを入力して読み込まれたか確認します。
詳細
使用する場合
- ユーザーがテキストからエンドツーエンドの音声を生成したい場合(効果音はモデルによって組み込まれます)
- ユーザーが各セリフに異なる声を割り当てた、複数の声による対話を作成したい場合
- ユーザーが参照音声クリップから声をクローンしたい場合
- ユーザーが参照画像を音声に変換したい場合(画像 → 音声)
- ユーザーがテキストの説明から効果音だけを生成したい場合
- ユーザーが「音声生成」「エンドツーエンド音声」「画像から音声」「複数の声による対話」「参照音声のクローン」「効果音」と言った場合
使用しない場合
- ユーザーが登録済みのListenHubの声を1つ使ってテキストを読み上げたいだけの場合(
/ttsを使用)— 登録済みのListenHubの話者による通常のナレーションでは、/ttsのほうがレイテンシが低くなります - ユーザーがトピックを掘り下げるポッドキャスト形式のディスカッションを希望する場合(
/podcastを使用) - ユーザーが音楽やカバー曲を希望する場合(
/musicを使用) - ユーザーが動画を希望する場合(
/video-genを使用) - ユーザーが音声/動画をテキストに書き起こしたい場合(
/asrを使用)
/ttsと/listenhub-voiceの違い:/listenhub-voiceはListenHub-Voice-1.0のエンドツーエンドモデルです —
テキストまたは画像から、効果音、複数の声による対話、参照音声による声のクローンを含められる完成済みの音声トラックを生成します。また、長さの目安を指定する任意のdurationHintも使用できます。登録済みのListenHubの声を使った通常の単一話者ナレーションには、引き続き/ttsを利用できます。
目的
ListenHub-Voice-1.0モデルでエンドツーエンドの音声を生成します。1つの非同期タスクにテキストスクリプト(および任意で声、参照画像、音声パラメーター、長さの目安)を渡すと、完成済みの音声ファイルが返されます。モード:
- 通常のテキスト/効果音 —
voicesなし、imageなし。モデルがテキストと、そこに記述された効果音を合成します。 - 単一の声 — 1項目の
voices。登録済みのListenHub話者/公式voice_type(type: speaker)または参照音声のクローン(type: reference)を指定します。 - 複数の声による対話 — 2~3項目の
voices。スクリプトでは、voices配列の順序に従い、各セリフに@音频1/@音频2のプレフィックスを付けます。複数の声によるリクエストでは、すべての項目が参照音声に対応している必要があります(公式のvoice_typeは単一の声にのみ対応します)。 - 参照音声によるクローン — クローンする声の公開音声URLを指す、
type: referenceのvoices項目。 - 画像 → 音声 —
image(URLまたはデータ)。voicesとは併用できません。
厳守事項
- 必ず
shared/cli-authentication.mdに従ってCLI認証を確認してください - CLIの実行、エラー、インタラクションのパターンについては、
shared/cli-patterns.mdに従ってください - インタラクションの前に必ず
shared/config-pattern.mdに従って設定を読み込んでください - 結果の提示には
shared/output-mode.mdに従ってください —downloadモードでは、shared/config-pattern.md§ Artifact Namingに従って重複を避けながら、{slug}.{ext}(ext =audioConfig.format:デフォルトのmp3/wav/pcm/ogg_opus)をcwdに保存します - 必ず非同期パターンを使用してください。送信すると
taskIdが返されるので、success/failedになるまでタスクエンドポイントをポーリングしてください — 1回の呼び出しで完了まで待たないでください imageとvoicesは併用できません — 1つのリクエストで両方を送信しないでください- 複数の声(
voicesの長さ > 1)の場合、すべての項目が参照音声に対応している必要があります。公式のvoice_type(type: speaker)は単一の声にのみ対応し、複数の声によるリクエストでは拒否されます - プロバイダーのルーティング情報、認証情報、内部ステータス名、DAO、MongoDB、コールバックの内部情報は決して公開しないでください。以下の公開されている3エンドポイントの仕様のみを使用してください
⚠️ CLI の状況:
listenhub-cliには、まだlistenhub-voiceサブコマンドが含まれていません。 そのため、以下の例ではすべて、Bearer API Key(lh_sk_...)を使ってcurlから OpenAPI HTTP コントラクトを直接呼び出します。listenhub-voiceCLI サブコマンドが提供されたら、 このスキルを更新して、それを優先するようにしてください(/video-genの$CMD_PREFIXパターンに倣います)。
将来の CLI サブコマンドが存在するかを検出し、存在しない場合は HTTP にフォールバックします:
if listenhub listenhub-voice --help &>/dev/null; then
LISTENHUB_VOICE_MODE="cli"
else
echo "LISTENHUB_VOICE_COMMAND_UNAVAILABLE — falling back to OpenAPI HTTP (curl)"
LISTENHUB_VOICE_MODE="http"
fi
http モードでは、OpenAPI API Key が必要です。設定または環境変数から読み取ります:
API_BASE="https://api.marswave.ai/openapi" # OpenAPI base; see shared/cli-authentication.md
API_KEY="${LISTENHUB_API_KEY:-$(listenhub openapi config show --json 2>/dev/null | jq -r '.apiKey // empty')}"
if [ -z "$API_KEY" ]; then
echo "需要 OpenAPI API Key(lh_sk_...)。请先用 listenhub openapi config set-key 配置,或设置 LISTENHUB_API_KEY 环境变量。"
fi
すべてのリクエストは Authorization: Bearer $API_KEY で認証します。
ステップ 0:設定
shared/config-pattern.md のステップ 0(質問なしでの起動)に従います。
ファイルが存在しない場合 — デフォルト設定でひそかに作成し、続行します:
mkdir -p ".listenhub/listenhub-voice"
echo '{"outputMode":"inline"}' > ".listenhub/listenhub-voice/config.json"
CONFIG_PATH=".listenhub/listenhub-voice/config.json"
CONFIG=$(cat "$CONFIG_PATH")
セッションのデフォルト設定(ユーザーが再設定しない限り保存されません):
- model:
listenhub-voice-1.0(有効な値はこれのみ) - audioConfig.format:
mp3
設定について質問しないでください。 そのままインタラクションフローに進みます。
ファイルが存在する場合 — 設定をひそかに読み取り、続行します:
CONFIG_PATH=".listenhub/listenhub-voice/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/listenhub-voice/config.json"
CONFIG=$(cat "$CONFIG_PATH")
OUTPUT_MODE=$(echo "$CONFIG" | jq -r '.outputMode // "inline"')
セットアップフロー(ユーザーが再設定を開始した場合のみ)
ユーザーが明示的に再設定を求めた場合にのみ実行します。次の項目を質問します:
- outputMode:
shared/output-mode.mdの § セットアップフローの質問に従います。
すぐに保存します:
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
インタラクションフロー
ステップ 1:テキストを収集する
合成するスクリプト/テキストをユーザーに尋ねます(必須、1400 文字以下、前後の空白を削除):
合成するテキストを入力してください(1400 字以下)。効果音が必要な場合は、テキスト内にそのまま説明を記述してください。複数の音色による会話では、各行のセリフの先頭に
@音频1/@音频2を付けて割り当てます。
自由形式のテキストです。入力されたまま使用します。ユーザーから依頼がない限り、変更しないでください。
ステップ 2:音声/入力モード
Question: "音频用什么音色 / 输入方式?"
Options:
- "无音色(纯文本 / 音效)" — No voices, no image → Step 3 (audio params)
- "单个 ListenHub 音色" — voices=[{type:speaker, id:<ListenHub 代号>}] → Step 2a
- "单个官方 voice_type" — voices=[{type:speaker, id:<voice_type>}] → Step 2a
- "多音色对白(参考音频)" — voices=2–3 项,每项 type:reference → Step 2b
- "参考音频克隆(单条)" — voices=[{type:reference, url:...}] → Step 2b
- "图片 → 音频" — image (与 voices 互斥) → Step 2c
ステップ 2a:登録済み音声 1 つ(type: speaker)
話者の id を 1 つ収集します:
- ListenHub 音声コード —
GET /v1/speakers/list(登録済みの ListenHub 話者)から取得します。ユーザーが選択できるよう、shared/speaker-selection.mdに従います。 - 公式の
voice_type— 例:zh_female_vv_uranus_bigtts。ユーザーがすでにvoice_typeを把握している場合は、そのまま使用します。サーバーが ListenHub コードと公式コードを自動判別します。
構築します:voices = [{ "type": "speaker", "id": "<id>" }]。ステップ 3 に進みます。
注意:公式の
voice_typeは単一音声専用です。複数音声(項目が 1 件を超える)のリクエストには使用できません。
ステップ 2b:参照音声(type: reference)
各参照項目には公開音声 URL(http/https)が必要です:
- 30 秒以下、10MB 以下、形式は
wav/mp3/pcm/ogg_opus
クリップ 1 つのクローン作成の場合:URL を 1 つ収集します → voices = [{ "type": "reference", "url": "..." }]。
複数音声の会話の場合:参照 URL を 2~3 個収集します(音声は合計最大 3 つ)。各項目はすべて参照音声にする必要があります(ListenHub 話者と参照音声の組み合わせも可能ですが、公式の voice_type は使用できません)。次に、voices 配列の順序に合わせて、text 内の各スクリプト行の先頭に @音频1 / @音频2 / @音频3 を付けるようユーザーに案内します(@音频1 = voices[0])。
例のように構築します:
"voices": [
{ "type": "reference", "url": "https://example.com/host.mp3" },
{ "type": "reference", "url": "https://example.com/guest.mp3" }
]
ステップ 3 に進みます。
ステップ 2c:画像から音声へ(image、voices とは併用不可)
画像を1 つ収集します。公開 URL または Base64 のどちらか一方を選択します。両方は指定できません:
- 画像は最大 1 枚、10MB 以下、形式は
jpeg/png/webp
構築します:image = { "url": "https://..." } または image = { "data": "<base64>" }。
このモードでは voices を送信しないでください。ステップ 3 に進みます。
ステップ 3:任意の音声パラメーター
Question: "要调整音频参数吗?(默认:格式 mp3,语速/音量/音调不变)"
Options:
- "用默认,跳过" — Skip, audioConfig omitted (server uses format mp3)
- "我要调整" — Ask each below
調整する場合は、1 項目ずつ質問します(すべて任意です。ユーザーが設定しない項目は省略します):
- format:
mp3(デフォルト) /wav/pcm/ogg_opus - speechRate(話速):-50 .. 100 の整数
- loudnessRate(音量):-50 .. 100 の整数
- pitchRate(音程):-12 .. 12 の整数
ユーザーが設定した項目のみで audioConfig を構築します。
ステップ 4:任意の再生時間のヒント
Question: "要指定目标时长吗?(用于积分预估并提示模型生成「约 N 秒」)"
Options:
- "不指定" — Omit durationHint
- "指定秒数" — Collect an integer in 1 .. 110
ステップ 5:料金の説明と確認
料金:実際の生成時間(秒)に応じて課金されます。1 秒あたり 0.1125 クレジットで、切り上げ、最低 1 クレジットです。 作成時には残高の事前確認のみを行い、残高は確保しません。音声生成後、実際の音声時間に応じて精算されます。
durationHintは概算に利用できます (約ceil(durationHint × 0.1125)クレジット。実際の料金は生成された音声の長さに基づきます)。 レート制限:60 秒間に最大 5 回生成できます。
概要を提示し、generate を呼び出す前に明示的な確認を待ってください。
准备生成音频:
文本: {text 摘要}
模式: {纯文本/音效 | 单音色(ListenHub/官方) | 多音色对白 | 参考音频克隆 | 图片→音频}
voices: {无 | N 项}
image: {无 | url/data}
audioConfig: {默认 mp3 | 调整后的字段}
durationHint: {无 | N 秒}
预估: 约 {ceil(durationHint×0.1125) or "未指定时长,无预估"} 积分(按实结算)
确认生成?
実行とポーリング
送信(POST /v1/listenhub-voice/generate → 202)
収集した値から JSON ボディを作成し、POST します。レスポンスは 202 で、
data.taskId と data.status = "pending" が返されます。
BODY=$(jq -n \
--arg text "$TEXT" \
'{ model: "listenhub-voice-1.0", text: $text }')
# Add voices / image / audioConfig / durationHint / watermark only if set, e.g.:
# BODY=$(echo "$BODY" | jq --argjson v "$VOICES_JSON" '. + {voices: $v}')
# BODY=$(echo "$BODY" | jq --argjson img "$IMAGE_JSON" '. + {image: $img}')
# BODY=$(echo "$BODY" | jq --argjson ac "$AUDIOCONFIG_JSON" '. + {audioConfig: $ac}')
# BODY=$(echo "$BODY" | jq --argjson dh "$DURATION_HINT" '. + {durationHint: $dh}')
RESP=$(curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "$BODY")
TASK_ID=$(echo "$RESP" | jq -r '.data.taskId // empty')
TASK_ID が空の場合は、ビジネスエラーを提示してください(data に 33xxx コードが含まれます。「エラー処理」を参照)。
それ以外の場合は、「タスクを送信しました。ID: {TASK_ID}。生成中です…」と伝えてください。
ポーリング(GET /v1/listenhub-voice/tasks/{taskId})
run_in_background: true で実行します。success または failed になるまでポーリングします。
for i in $(seq 1 120); do
RESULT=$(curl -sS "$API_BASE/v1/listenhub-voice/tasks/$TASK_ID" \
-H "Authorization: Bearer $API_KEY" | jq -c '.data')
STATUS=$(echo "$RESULT" | jq -r '.status')
case "$STATUS" in
success) echo "$RESULT"; exit 0 ;;
failed) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 5 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
ステータスの遷移:pending → generating → uploading → success | failed。
(公開されているステータスはこの 5 つのみです。ほかの内部状態を想定しないでください。)
結果の提示
success の場合は、ListenHubVoiceTask を解析します。
AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')
AUDIO_DURATION=$(echo "$RESULT" | jq -r '.audioDuration')
CREDIT_CHARGED=$(echo "$RESULT" | jq -r '.creditCharged')
設定から OUTPUT_MODE を読み取り、shared/output-mode.md に従ってください。
inline または both — 次を表示します:
音频已生成!
URL: {audioUrl}
时长: {audioDuration}s(即计费时长)
消耗: {creditCharged} 积分
download または both — shared/config-pattern.md § Artifact Naming に従い、トピックに基づくスラッグを使用して cwd に保存します(拡張子は選択された format。デフォルトは mp3)。
SLUG="{topic-slug}"
EXT="${FORMAT:-mp3}"
NAME="${SLUG}.${EXT}"
BASE="${NAME%.*}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$AUDIO_URL"
echo "已保存到当前目录:$NAME"
failed の場合:errorMessage(失敗時のみ存在)を読み取って表示し、スクリプト/音声/画像を確認して再試行するよう提案してください。
タイムアウトの場合:後で GET /v1/listenhub-voice/tasks/{taskId} を使って確認するようユーザーに伝えてください。
過去のタスクを照会する
最近のタスクを一覧表示します(ページネーション、新しい順)。
# List (page/pageSize/status/keyword all optional)
curl -sS "$API_BASE/v1/listenhub-voice/tasks?page=1&pageSize=20" \
-H "Authorization: Bearer $API_KEY" | jq '.data'
# Filter by status + fuzzy keyword on the script text (keyword ≤ 64 chars)
curl -sS "$API_BASE/v1/listenhub-voice/tasks?status=success&keyword=对白" \
-H "Authorization: Bearer $API_KEY" | jq '.data.items'
# Get one task
curl -sS "$API_BASE/v1/listenhub-voice/tasks/$TASK_ID" \
-H "Authorization: Bearer $API_KEY" | jq '.data'
一覧レスポンスの data:{ items: [ListenHubVoiceTask], page, pageSize, total }。
status フィルターで指定できる値は pending | generating | uploading | success | failed です。
API コントラクト(公開エンドポイント 3 件)
すべて Authorization: Bearer lh_sk_... が必要です。
POST /v1/listenhub-voice/generate(非同期、202 を返す)
リクエストボディ:
| フィールド | 型 | 必須 | 備考 |
|---|---|---|---|
model | string | いいえ | 列挙値:listenhub-voice-1.0 のみ(デフォルトは listenhub-voice-1.0) |
text | string | はい | 前後の空白を削除。最大 1400 文字。@音频N プレフィックスで複数音声の各行を割り当てます |
voices | array (1–3) | いいえ | 各項目は {type} と(id または url)。下記参照。image とは同時に指定できません |
image | object | いいえ | url または data(いずれか一方のみ)。最大 1 件、≤10MB、jpeg/png/webp。voices とは同時に指定できません |
audioConfig | object | いいえ | speechRate -50..100、loudnessRate -50..100、pitchRate -12..12、format mp3|wav|pcm|ogg_opus(デフォルトは mp3) |
durationHint | number | いいえ | 1..110(目標の秒数。概算およびモデルへのヒントに使用) |
watermark | boolean | いいえ | 透かしを追加 |
voices[] の項目:
{ "type": "speaker", "id": "<code>" }—idは必須です。ListenHub 音声コード(GET /v1/speakers/listから取得)または公式のvoice_typeを指定します。サーバーが自動判定します。{ "type": "reference", "url": "<http(s) url>" }—urlは必須です。公開音声で、≤30 秒、≤10MB、wav/mp3/pcm/ogg_opus に対応します。- 複数音声(項目が 1 件より多い場合):すべての項目が参照音声に対応している必要があります。公式の
voice_typeは単一音声のみです。
レスポンス 202:{ data: { taskId, status: "pending" } }。
料金:実際の音声時間に応じて 1 秒あたり 0.1125 クレジット(切り上げ、最低 1)。レート制限:60 秒あたり 5 回。
GET /v1/listenhub-voice/tasks(一覧、新しい順)
クエリ:page(デフォルト 1)、pageSize(デフォルト 20、最大 100)、
status(pending|generating|uploading|success|failed)、keyword(最大 64 文字。スクリプトテキストをあいまい検索)。
レスポンスの data:{ items: [ListenHubVoiceTask], page, pageSize, total }。
GET /v1/listenhub-voice/tasks/{taskId}(詳細、自分のタスクのみ)
レスポンスの data:単一の ListenHubVoiceTask。
ListenHubVoiceTask(リスト項目と詳細で共通の契約)
| フィールド | 備考 |
|---|---|
id | タスク ID |
status | pending → generating → uploading → success | failed |
model | listenhub-voice-1.0 |
params | サニタイズ済みの入力パラメーター(音声/画像のバイナリデータを含みません) |
audioUrl | 出力音声 URL — success の場合のみ |
audioDuration | 出力時間(秒)=課金対象の時間 |
creditCharged | 実際に課金されたクレジット数(0 = 課金なし) |
creditRefunded | 失敗時に返金されたクレジット数(精算のみ) |
errorMessage | 失敗理由 — failed の場合のみ |
createdAt / updatedAt | ミリ秒単位のタイムスタンプ |
このスキルの対象外のエンドポイント:
/v1/listenhub-voice/voicesと/v1/listenhub-voice/estimate-credits。voices[].idに指定する ListenHub 音声コードを取得するには、GET /v1/speakers/listを使用してください。
エラー処理
標準の HTTP/CLI エラーの扱いに加え、data ペイロード内にビジネスエラーが含まれます。
| コード | 意味 | 対応 |
|---|---|---|
| 0 | 成功 | JSON 出力を解析します |
| 1 | 一般エラー | stderr/レスポンス本文をユーザーに表示します |
| 2 | 認証エラー | listenhub openapi config show または LISTENHUB_API_KEY を使って API Key(lh_sk_...)を確認します |
| 3 | タイムアウト | 後でタスクのステータスを確認するよう提案します |
generate の 400 には、data にビジネスエラー(クレジット不足、レート制限、バリデーションなど)が含まれます — shared/cli-patterns.md に従い、33xxx のビジネスエラーコードを提示してください。
組み合わせ
| 方向 | 説明 |
|---|---|
listenhub ルーター → listenhub-voice | /listenhub 経由で、ユーザーがエンドツーエンド音声/音效/多音色の台詞/画像から音声への変換について言及した場合にルーティングします |
listenhub-cli ルーター → listenhub-voice | /listenhub-cli 経由で同様にルーティングします |
speakers (/v1/speakers/list) → listenhub-voice | voices[].id(type: speaker)に指定する ListenHub 音声コードの取得元です |
listenhub-voice → (none) | 独立した終端スキルで、下流への依存関係はありません |
例
すべての例では -H "Authorization: Bearer lh_sk_..." で認証します(簡潔にするため、以下では省略しています)。
単一音声のナレーション(登録済み音声)
「この ListenHub の音声で、このテキストを読み上げてください」
curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Content-Type: application/json" \
-d '{
"model": "listenhub-voice-1.0",
"text": "欢迎收听今天的节目。",
"voices": [{ "type": "speaker", "id": "<listenhub-voice-code>" }]
}'
参照音声のクローン作成
「この参照音声の声で読み上げてください」
curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Content-Type: application/json" \
-d '{
"model": "listenhub-voice-1.0",
"text": "这是用参考音频克隆出来的声音。",
"voices": [{ "type": "reference", "url": "https://example.com/voice.mp3" }]
}'
複数音声の対話(@音声N)
「2 人の対話を作ってください」
curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Content-Type: application/json" \
-d '{
"model": "listenhub-voice-1.0",
"text": "@音频1 你今天怎么样?\n@音频2 还不错,刚录完一集播客。",
"voices": [
{ "type": "reference", "url": "https://example.com/host.mp3" },
{ "type": "reference", "url": "https://example.com/guest.mp3" }
]
}'
画像 → 音声
「この画像に基づいて音声を生成してください」
curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Content-Type: application/json" \
-d '{
"model": "listenhub-voice-1.0",
"text": "为这张图片配一段氛围音频。",
"image": { "url": "https://example.com/scene.jpg" }
}'
効果音のみ
「雨と雷の効果音を生成してください」
curl -sS -X POST "$API_BASE/v1/listenhub-voice/generate" \
-H "Content-Type: application/json" \
-d '{
"model": "listenhub-voice-1.0",
"text": "持续的中雨声,远处偶尔有雷声滚过,约 15 秒。",
"durationHint": 15,
"audioConfig": { "format": "mp3" }
}'
API リファレンス
- CLI 認証:
shared/cli-authentication.md - CLI 実行パターン:
shared/cli-patterns.md - 設定パターン:
shared/config-pattern.md - 出力モード:
shared/output-mode.md - 話者の選択(ListenHub 音声コード):
shared/speaker-selection.md