ListenHubSDKs & CLI
CLI

CLI サンプル

listenhub CLI による一発生成、バッチループ、音声の書き出し、CI パイプラインを、そのままコピーして使える shell レシピ集。

実際に動く shell レシピ集です。CLI のインストールと認証さえ済んでいれば、どれもそのまま実行できます。ほとんどの例は API キー(listenhub openapi)ネームスペースを使います。スクリプトと CI にはこちらが適しているからです。ただし、ローカルファイルのアップロードに依存するレシピ(カバー音声、参照画像)は、その機能がある OAuth ネームスペースを使います。各レシピには必要な認証モードを明記しています。

始める前に:

  • インストール:npm install -g @marswave/listenhub-cli(Node.js >= 20 が必要)。
  • openapi のレシピでは、LISTENHUB_API_KEY を設定する(CLI はこちらを先に読み取ります)か、listenhub openapi config set-key を実行します。認証 を参照してください。
  • OAuth のレシピでは、listenhub auth login を一度実行します。

--json / -j は機械可読な出力を stdout に出し、エラーと進捗スピナーは stderr に流します。この分離があるおかげで jq へのパイプが安全に使えます。終了コードは 0 成功、1 エラー、2 認証、3 タイムアウト。スクリプトでは $? で分岐してください。

1. ポッドキャストを一発生成

トピックを送信し、エピソードが完成するまでブロックして待ちます。コマンドはデフォルトで 10 秒ごとにポーリングし、--timeout(デフォルト 300)まで待ってから、完成したエピソードを出力します。

export LISTENHUB_API_KEY="lh_sk_..."

# Pick a voice once, copy its ID
listenhub openapi speakers list --language en

listenhub openapi podcast create \
  --query "AI agent trends in 2026" \
  --speaker-id <speaker-id> \
  --mode quick

--speaker-id は必須で、繰り返し指定できます。2 回渡せばホスト 2 人のエピソードになります。内容の根拠を与えるには、--query の代わりに、あるいは --query に加えて --source-url--source-text(どちらも繰り返し指定可能)を使います。

2. bash ループでのバッチ生成

ファイルからトピックを読み込み、それぞれを --no-wait(ID をすぐ返す)で投げ、jqepisodeId を取り出してから、2 周目で ID をポーリングします。こうすると送信が速く保たれ、時間のかかる生成ステップと切り離せます。

#!/usr/bin/env bash
set -euo pipefail

SPEAKER_ID="<speaker-id>"
ids=()

# Submit every topic, collect episode IDs
while IFS= read -r topic; do
  [ -z "$topic" ] && continue
  id=$(listenhub openapi podcast create \
        --query "$topic" \
        --speaker-id "$SPEAKER_ID" \
        --mode quick \
        --no-wait --json | jq -r '.episodeId')
  echo "submitted: $topic -> $id"
  ids+=("$id")
done < topics.txt

# Poll each episode until it leaves the running state
for id in "${ids[@]}"; do
  while :; do
    status=$(listenhub openapi podcast get "$id" --json | jq -r '.processStatus')
    case "$status" in
      success) echo "$id done"; break ;;
      failed)  echo "$id failed" >&2; break ;;
      *)       sleep 10 ;;
    esac
  done
done

終了状態では processStatussuccessfailed になります。それ以外の値はまだ実行中という意味です。topics.txt は 1 行 1 トピックです。

3. テキスト読み上げを音声ファイルに保存

openapi tts はバイナリ音声をそのままディスクへストリーミングします。ポーリングも --json も不要です。openapi speakers list で音声 ID を調べてから、MP3 を書き出します:

VOICE=$(listenhub openapi speakers list --language en --json | jq -r '.[0].speakerId')

listenhub openapi tts \
  --text "Hello from ListenHub" \
  --voice "$VOICE" \
  --output hello.mp3
# ✓ Audio saved: /abs/path/hello.mp3 (42.3KB)

--formatmp3(デフォルト)、opusaacflacwavpcm を受け付けます。ローカルファイルではなく音声 URL がほしい場合(audioUrl を含む JSON が返ります)は、openapi speech --script "..." --speaker-id "$VOICE" -j を使います。

4. 参照トラックから音楽を生成

既存のトラックからカバーを生成するにはローカルファイルのアップロードが必要で、この機能は OAuth ネームスペースにあります。listenhub music cover はローカルパスを自動検出して検証し、クラウドストレージへアップロードしたうえで、ジョブを送信してポーリングします。

# OAuth: run `listenhub auth login` first
listenhub music cover \
  --audio ./original.mp3 \
  --style "lo-fi" \
  --title "My Cover" \
  --json

--audio は URL も受け付け、その場合はアップロードせずにそのまま渡されます。参照音声を取る完全に API キー駆動のフローがほしい場合は listenhub openapi music instrumental --reference-audio ./clip.mp3(モデルはデフォルトが適用されます)を、画像に曲を付けたい場合は listenhub openapi music soundtrack --image ./cover.png --prompt "..." を使います。

5. ローカル参照画像を使った AI 画像生成

openapi image create はローカルの参照ファイルを読み込み、base64 エンコードしてインラインで送信します。--reference は繰り返し指定でき、URL も受け付けます(URI としてそのまま渡されます)。--provider は必須です。

listenhub openapi image create \
  --prompt "a dragon in watercolor style, inspired by this sketch" \
  --provider google \
  --reference ./sketch.png \
  --ratio 16:9 \
  --json | jq -r '.imageUrl // .'

対応する参照画像の形式:.png.jpg/.jpeg.gif.webp.bmp。任意指定の --size1K2K4K--ratio16:94:31:13:49:1621:9 のいずれかです。

6. PixVerse のテキストから動画生成

PixVerse は openapi video pixverse generate から実行します。--capability は必須で、最も単純なのは text_to_video です。--language en(デフォルト)は国際版サービスに、--language zh は中国版サービスに接続します。

# Estimate credits first (never assume a fixed cost)
listenhub openapi video pixverse estimate \
  --capability text_to_video --quality 720p --duration 5

# Submit and return the task ID without waiting
listenhub openapi video pixverse generate \
  --capability text_to_video \
  --prompt "A cat playing piano on a neon stage" \
  --quality 720p \
  --aspect-ratio 16:9 \
  --duration 5 \
  --no-wait --json

--quality360p540p720p(デフォルト)、1080p--duration は 1 から 60 までの整数です(デフォルト 5)。画像・動画・音声のアセットは、末尾に任意の :<seconds> という長さのサフィックスを付けられます(例:--image https://example.com/p.jpg:3)。

7. CI パイプライン:まず送信し、ポーリングは分ける

CI では通常、1 つのコマンドが何分も接続を握り続けるのは避けたいはずです。--no-wait で送信し、ID をジョブの出力として保存して、後のステップ(または後の実行)でポーリングします。このレシピでは終了コードによる分岐も示します。

#!/usr/bin/env bash
set -euo pipefail
# LISTENHUB_API_KEY is injected from CI secrets

# --- step: submit ---
EPISODE_ID=$(listenhub openapi podcast create \
  --source-url "https://example.com/release-notes" \
  --speaker-id "$LH_SPEAKER_ID" \
  --no-wait --json | jq -r '.episodeId')
echo "episode_id=$EPISODE_ID" >> "$GITHUB_OUTPUT"

# --- step: poll with a hard cap ---
deadline=$(( $(date +%s) + 900 ))   # 15 minutes
while :; do
  status=$(listenhub openapi podcast get "$EPISODE_ID" --json | jq -r '.processStatus')
  [ "$status" = "success" ] && break
  if [ "$status" = "failed" ]; then
    echo "generation failed" >&2
    exit 1
  fi
  if [ "$(date +%s)" -ge "$deadline" ]; then
    echo "timed out waiting for $EPISODE_ID" >&2
    exit 3
  fi
  sleep 10
done

# --- step: fetch the audio URL ---
listenhub openapi podcast get "$EPISODE_ID" --json | jq -r '.audioUrl'

CI で作成コマンド 1 つにポーリングさせると(--no-wait なし)、--timeout に達した時点で 3 で終了します。ただしジョブはサーバー側で動き続けます。後のステップから復帰できるよう、ID は必ず取得しておいてください。終了コード 2 は認証情報の問題として扱い、LISTENHUB_API_KEY をローテーションするか設定し直してください。

8. バッチ実行の前にクレジットを確認する

生成はクレジットを消費します。大きなバッチを走らせる前に、残高を確認し、その作業のコストを見積もってください。

# Remaining credits and plan
listenhub openapi subscription --json | jq '{credits: .totalAvailableCredits, plan: .subscriptionPlan.name}'

# Estimate one video task before multiplying it across a batch
listenhub openapi video estimate \
  --model doubao-seedance-2-pro \
  --resolution 1080p \
  --duration 10 \
  --json | jq '{credits, tokens}'

従量課金のある製品にはすべて estimate コマンドがあります(openapi video estimateopenapi video pixverse estimate)。数値をハードコードせず、そのつど照会してください。コストはモデル、解像度、長さによって変わります。

次のステップ

このページの内容