CLI 示例
用于一次性生成、批量循环、导出音频以及 CI 流水线的 listenhub CLI shell 脚本示例,开箱即用。
一份可直接复制粘贴的 shell 脚本手册。只要你装好 CLI 并完成认证,每个示例都能原样运行。大多数示例使用 API key(listenhub openapi)命名空间,因为它最适合脚本和 CI;但依赖本地文件上传的示例(cover 音频、图片参考图)会改用 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;错误信息和进度 spinner 走 stderr。正是这种分离让 jq 管道得以安全工作。退出码:0 成功、1 错误、2 认证、3 超时——脚本里可根据 $? 分支处理。
1. 一次性生成播客
提交一个主题并阻塞等待,直到节目就绪。命令默认每 10 秒轮询一次,最长等到 --timeout(默认 300),然后打印完成的节目。
export LISTENHUB_API_KEY="lh_sk_..."
# 先列出可用声音,复制一个 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 为必填且可重复——传两次即生成双主持节目。用 --source-url 或 --source-text(均可重复)为内容提供素材,可替代 --query,也可与之叠加。
2. 用 bash 循环批量生成
从文件读取主题,逐条用 --no-wait(立即返回 ID)提交,用 jq 取出 episodeId,再用第二轮循环轮询这些 ID。这样提交速度很快,且与缓慢的生成步骤解耦。
#!/usr/bin/env bash
set -euo pipefail
SPEAKER_ID="<speaker-id>"
ids=()
# 提交每个主题,收集 episode ID
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
# 轮询每个节目,直到它离开运行中状态
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终态时 processStatus 为 success 或 failed,其它值表示仍在运行。topics.txt 每行一个主题。
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)--format 接受 mp3(默认)、opus、aac、flac、wav 或 pcm。若想得到音频 URL 而非本地文件(返回带 audioUrl 的 JSON),用 openapi speech --script "..." --speaker-id "$VOICE" -j。
4. 基于参考曲目生成音乐
从已有曲目生成 cover 需要本地文件上传,这一能力位于 OAuth 命名空间。listenhub music cover 会自动识别本地路径、校验、上传到云存储,然后提交任务并轮询。
# OAuth:先运行 `listenhub auth login`
listenhub music cover \
--audio ./original.mp3 \
--style "lo-fi" \
--title "My Cover" \
--json--audio 也接受 URL,此时直接透传而不上传。若想要完全由 API key 驱动、且接受参考音频的流程,使用 listenhub openapi music instrumental --reference-audio ./clip.mp3(采用默认模型),或用 listenhub openapi music soundtrack --image ./cover.png --prompt "..." 为一张图片配乐。
5. 带本地参考图的 AI 图片
openapi image create 会读取本地参考文件、做 base64 编码并以 inline 方式发送。--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。可选的 --size 为 1K、2K 或 4K;--ratio 取 16:9、4:3、1:1、3:4、9:16、21:9 之一。
6. PixVerse 文本生成视频
PixVerse 通过 openapi video pixverse generate 调用。--capability 为必填;text_to_video 是最简单的场景。--language en(默认)走国际服务,--language zh 走中国区服务。
# 先估算积分(切勿假定固定成本)
listenhub openapi video pixverse estimate \
--capability text_to_video --quality 720p --duration 5
# 提交并立即返回任务 ID,不等待
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--quality 取 360p、540p、720p(默认)或 1080p;--duration 为 1 到 60 的整数(默认 5)。image、video、audio 资源都接受可选的末尾 :<seconds> 时长后缀(例如 --image https://example.com/p.jpg:3)。
7. CI 流水线:先提交,再单独轮询
在 CI 中,你通常不希望一条命令把连接挂住好几分钟。用 --no-wait 提交,把 ID 持久化为任务输出,再在后续步骤(或后续一次运行)里轮询。本示例同时演示了如何根据退出码分支处理。
#!/usr/bin/env bash
set -euo pipefail
# LISTENHUB_API_KEY 从 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 分钟
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 里轮询(不加 --no-wait),当达到 --timeout 时它会以 3 退出——但任务在服务端仍在继续运行。务必捕获 ID,以便后续步骤能恢复它。把退出码 2 当作凭证问题处理:轮换或重新设置 LISTENHUB_API_KEY。
8. 批量任务前先查积分
生成会消耗积分。在启动大批量运行前,先读取余额并估算这批工作的成本。
# 剩余积分与套餐
listenhub openapi subscription --json | jq '{credits: .totalAvailableCredits, plan: .subscriptionPlan.name}'
# 在把一个视频任务乘以批量规模之前,先估算它的成本
listenhub openapi video estimate \
--model doubao-seedance-2-pro \
--resolution 1080p \
--duration 10 \
--json | jq '{credits, tokens}'每个有计量成本的产品都提供 estimate 命令(openapi video estimate、openapi video pixverse estimate)。去查询它,而不要写死一个数字——成本会随模型、分辨率和时长变化。