关于 video-gen
video-gen 是通过 ListenHub CLI 创建和编辑 AI 视频的 Agent 技能。它根据需求使用 HappyHorse、SeeDance 或 PixVerse,并支持 PixVerse 独有的口型同步及广告或宣传视频生成。
主要功能
- 01文本生成视频和图像生成视频
- 02使用参考图像与视频
- 03通过 HappyHorse 编辑视频
- 04PixVerse 口型同步与风格转换
- 05以 JSON 输出异步生成任务
适用场景
- 01根据文本提示生成视频片段
- 02为静态图像或参考素材制作动画
- 03编辑现有视频
- 04将视频口型与音频或 TTS 同步
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marswaveai/ skills --skill video-gen安装后在 Claude Code 中输入/video-gen确认已加载。
附带文件references/happyhorse-api.mdreferences/pixverse-api.md
详细介绍
适用场景
- 用户想根据文本描述生成 AI 视频
- 用户想为静态图片制作动画(首帧)
- 用户有参考图片来引导视频生成
- 用户想编辑现有视频(更改风格、背景等)
- 用户想让视频与音频或 TTS 对口型(仅限 PixVerse)——“对口型”“口型同步”
- 用户想制作营销广告/宣传混剪视频(PixVerse Agent)
- 用户说“生成视频”“做视频”“video generation”“text to video”“视频编辑”“pixverse”“口型”
不适用场景
- 用户想制作带旁白和 AI 视觉素材的解说视频(使用
/explainer) - 用户想将音频/视频转录为文本(使用
/asr) - 用户想生成图片(使用
/image-gen)
用途
使用 ListenHub CLI 生成 AI 视频。支持三个模型系列:
- HappyHorse(默认)——文本生成视频、图片生成视频、参考图片生成视频、视频编辑
- SeeDance——文本生成视频、帧模式(首帧 + 尾帧)、参考模式(图片、视频、音频)
- PixVerse——通过 Agent API 提供九种原子能力(text_to_video、image_to_video、transition、multi_transition、fusion、restyle、mimic、lip_sync、agent)。唯一支持口型同步的系列。仅限 OpenAPI,基于 URL/ID,并使用自己的
pixverseCLI 命名空间。
硬性约束
- 始终按照
shared/cli-authentication.md检查 CLI 身份验证 - 遵循
shared/cli-patterns.md中的 CLI 执行、错误和交互模式 - 进行任何交互前,始终按照
shared/config-pattern.md读取配置 - 遵循
shared/output-mode.md展示结果——download模式会将{slug}.mp4保存到当前工作目录,并按照shared/config-pattern.md§ Artifact Naming 进行去重 - 创建视频时始终使用
--no-wait --json——生成需要几分钟 - 绝不使用
eval执行 CLI 命令——始终直接调用listenhub video ...,并正确处理引号
模型对比
| 功能 | HappyHorse(默认) | SeeDance | PixVerse |
|---|---|---|---|
| 文本生成视频 | ✅ | ✅ | ✅ (text_to_video) |
| 图片生成视频(首帧) | ✅ | ✅(+ 尾帧) | ✅ (image_to_video) |
| 参考图片 | ✅(1–9 张,使用 [Image N] 提示词语法) | ✅ | ✅(fusion,使用 @refName 语法) |
| 转场(首帧→尾帧) | ❌ | ✅(帧模式) | ✅(transition / multi_transition) |
| 视频编辑 | ✅ | ❌ | ❌ |
| 风格重塑 | ❌ | ❌ | ✅ (restyle) |
| 动作模仿(动作迁移) | ❌ | ❌ | ✅ (mimic,固定为 720p) |
| 口型同步 | ❌ | ❌ | ✅ (lip_sync,音频或 TTS) |
| 营销 Agent(广告/宣传) | ❌ | ❌ | ✅ (agent: ad_master / promo_mix) |
| 参考视频 | ❌(改用视频编辑) | ✅ | ✅(mimic / lip_sync 来源) |
| 参考音频 | ❌ | ✅ | ✅(lip_sync) |
| 分辨率/画质 | 720p、1080p | 480p、720p、1080p | 360p、540p、720p、1080p |
| 时长范围 | 3–15 秒 | 4–15 秒 | 1–60 秒(agent:20/30/60) |
| 宽高比 | 16:9、9:16、1:1、4:3、3:4、4:5、5:4 | 16:9、9:16、1:1、4:3、3:4、21:9 | 9:16、16:9、1:1、4:3、3:4 |
| 提示词长度 | ≤2500 中文 / ≤5000 非中文 | ≤500 | ≤2048 |
| 速率限制 | 5 RPM | 5 RPM | 5 RPM |
| CLI 命名空间 | … video create | … video create | … video pixverse generate(仅限 OpenAPI) |
口型同步仅限 PixVerse——HappyHorse 和 SeeDance 均不支持。Mimic、restyle、fusion、transition 和营销 Agent 也都是 PixVerse 独有功能。
步骤 -1:CLI 身份验证检查 + 视频命令门控
遵循 shared/cli-authentication.md § 身份验证检查。如果 CLI 未安装或未登录,则自动安装并自动登录——绝不要求用户手动运行命令。
完成标准身份验证检查后,确认 video 子命令可用:
if ! listenhub video --help &>/dev/null; then
npm install -g @marswave/listenhub-cli@latest
if ! listenhub video --help &>/dev/null; then
echo "VIDEO_COMMAND_UNAVAILABLE"
fi
fi
如果出现 VIDEO_COMMAND_UNAVAILABLE:停止并告知用户:
video-gen 需要 listenhub-cli 的最新版本,当前已安装版本不包含 video 命令,请等待新版发布。
身份验证模式检测
CLI 支持两种身份验证模式。检测当前启用的是哪一种:
# Check if OpenAPI key is configured
OPENAPI_STATUS=$(listenhub openapi config show --json 2>/dev/null)
HAS_OPENAPI=$(echo "$OPENAPI_STATUS" | jq -r '.source // empty')
# Check if internal auth is active
AUTH=$(listenhub auth status --json 2>/dev/null)
HAS_INTERNAL=$(echo "$AUTH" | jq -r '.authenticated // false')
优先级: 如果两种模式都已配置,优先使用内部身份验证(功能更丰富)。设置一个会话变量:
if [ "$HAS_INTERNAL" = "true" ]; then
CMD_PREFIX="listenhub video"
elif [ -n "$HAS_OPENAPI" ]; then
CMD_PREFIX="listenhub openapi video"
else
# Neither configured — trigger internal auth login
listenhub auth login
CMD_PREFIX="listenhub video"
fi
后续所有命令都使用 $CMD_PREFIX,而不是硬编码的 listenhub video。两种模式的标志和 JSON 输出格式相同。
OpenAPI 专属说明:
- OpenAPI 模式需要 API Key(
lh_sk_...),通过listenhub openapi config set-key或环境变量LISTENHUB_API_KEY配置 - OpenAPI 模式不支持
--audio-setting标志(视频编辑的音频控制尚未开放) - 标准的
listenhub openapi video create接受本地图片、视频、音频路径或 URL。创建任务前,CLI 会上传本地文件;本地图片还会自动附带宽度、高度和大小元数据。 - 远程 Seedance 图片 URL 仍需显式提供
--*-meta值,因为 CLI 不会下载远程资源来推断尺寸。 - PixVerse 仅支持 OpenAPI——它位于
listenhub openapi video pixverse下,没有对应的内部身份验证版本。如果用户想使用 PixVerse(口型/mimic/restyle/fusion/transition/agent),但只配置了内部身份验证,请提示他们先配置 OpenAPI 密钥。 - PixVerse 媒体输入仍基于 URL/ID。不要向
listenhub openapi video pixverse generate传入本地路径;请让用户提供公开 URL 或先前的 PixVerse 任务/视频 ID。
步骤 0:配置设置
遵循 shared/config-pattern.md 步骤 0(零问题启动)。
如果文件不存在——静默创建并填入默认值,然后继续:
mkdir -p ".listenhub/video-gen"
echo '{"outputMode":"inline"}' > ".listenhub/video-gen/config.json"
CONFIG_PATH=".listenhub/video-gen/config.json"
CONFIG=$(cat "$CONFIG_PATH")
会话默认值(除非用户重新配置,否则不会持久化):
- 模型:
happyhorse - 分辨率:
1080p - 比例:
16:9 - 时长:
5
不要询问任何设置问题。 直接进入交互流程。
如果文件存在——静默读取配置并继续:
CONFIG_PATH=".listenhub/video-gen/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/video-gen/config.json"
CONFIG=$(cat "$CONFIG_PATH")
设置流程(仅在用户主动要求重新配置时运行)
仅当用户明确要求重新配置时运行。显示当前设置:
当前配置 (video-gen):
输出方式: {outputMode}
然后询问:
- 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:收集提示词
询问用户视频描述。如果用户尚未提供:
描述你想要生成的视频内容。
自由文本输入。按原样使用——除非用户请求帮助,否则不要修改提示词。
步骤 2:模式路由
Question: "你有参考素材想提供吗?"
Options:
- "没有,纯文字生成" — Text-to-video mode, skip to Step 4
- "有图片,想做首帧动画" — Image-to-video (first-frame) → Step 3a
- "有参考图片(风格/角色参考)" — Reference-image mode → Step 3b
- "有视频,想编辑/修改" — Video-edit mode → Step 3c
- "有视频,想做口型同步" — Lip-sync mode (PixVerse only) → Step 3d
如果用户提到 PixVerse 专属功能(口型/lip sync、模仿/mimic、restyle/风格化、融合/fusion、过渡/transition、广告/promo agent),则路由到 PixVerse 并选择匹配的 --capability——参见步骤 4(PixVerse)和 references/pixverse-api.md。
步骤 3a:图生视频(首帧)
-
first-frame(必需):询问图片路径或 URL。
- 支持格式:jpg、jpeg、png、webp
- 本地图片文件最大 10MB
- 图片:宽度和高度 ≥ 300px,比例介于 1:2.5 和 2.5:1 之间
- 本地图片:CLI 会自动填充 Seedance 元数据。远程 Seedance 图片 URL 需要
--first-frame-meta WIDTHxHEIGHT[:SIZE]。
-
last-frame(可选,仅 SeeDance):如果模型是 SeeDance,询问是否有末帧图片。
Question: "有尾帧图片吗?(仅 SeeDance 支持)"
Options:
- "没有,只用首帧" — Skip last-frame
- "有" — Collect last-frame path/URL
收集完毕后,继续步骤 4。
注意: HappyHorse 的 i2v 模式没有 ratio 参数——比例由输入图片决定。SeeDance 仍接受 --ratio。
步骤 3b:参考图模式
收集参考图(需要 1–9 张图片)。
询问图片路径/URL:
- 支持的格式:jpg、jpeg、png、webp
- 本地图片文件最大 10MB
- HappyHorse:建议短边 ≥ 400px
- 本地图片:CLI 会自动填充 Seedance 元数据。远程 Seedance 图片 URL 需要提供匹配的
--reference-image-meta WIDTHxHEIGHT[:SIZE]值。
**HappyHorse 提示词语法:**提供多张参考图时,用户可以在提示词中使用 [Image 1]、[Image 2] 等来引用特定图片。请告知用户此功能。
SeeDance 其他参考素材(仅当模型为 SeeDance 时):
- reference-video(可选,最多 3 个):mp4、mov,最大 50MB
- reference-audio(可选,最多 3 个):mp3、wav,最大 20MB(必须与图片或视频配对)
- reference-video 必须提供元数据:为每个视频提供
--reference-video-meta WIDTHxHEIGHT[:DURATION[:FPS[:SIZE]]]。
收集完成后,继续步骤 4。
步骤 3c:视频编辑模式(仅限 HappyHorse)
如果模型是 SeeDance,告知用户:“视频编辑仅 HappyHorse 模型支持,已自动切换。”并将模型设为 happyhorse。
-
video(必需):询问视频路径或 URL。
- 支持的格式:mp4、mov(建议使用 H.264)
- 时长:3–60s(输出最长为 15s)
- 最大 100MB,短边 ≥ 360px,长边 ≤ 4096px
- 仅支持 URL(不支持 base64)
-
reference-image(可选,0–5 张):询问是否有用于编辑的参考图。
-
audio-setting:
Question: "音频如何处理?"
Options:
- "自动(模型决定)" — audio_setting: auto
- "保留原声" — audio_setting: origin
收集完成后,继续步骤 4。
**注意:**视频编辑没有 ratio 或 duration 参数,输出与输入视频一致。
步骤 3d:口型同步模式(仅限 PixVerse)
口型同步仅在 PixVerse 上可用(--capability lip_sync)。如果用户使用 HappyHorse/SeeDance,告知用户:“口型同步仅 PixVerse 模型支持,已自动切换。”并使用步骤 4 中的 PixVerse 命令模板。
-
source video(必需):用于驱动口型的视频。收集以下任意一项:
--source-video-id <id>— PixVerse 视频 ID,或--source-task-id <id>— 可复用的先前已成功 PixVerse 任务。
(仅 OpenAPI 支持;源视频必须已存在于 PixVerse 上。)
-
audio source — 询问用户选择哪种驱动方式:
Question: "口型用什么驱动?"
Options:
- "用一段音频文件" — Collect 1 audio URL → --audio <url>
- "用文字转语音 (TTS)" — Collect speaker + content → --pixverse-json '{"tts":{...}}'
- **音频文件:**收集一个公开音频 URL →
--audio <url>(最多 1 个),音频时长须为 5–60s。 - **TTS:**收集说话人 ID 和要朗读的文本,使用嵌套 JSON(不要使用
--lip-sync-*flag,详见references/pixverse-api.md§ lip_sync):--pixverse-json '{"tts":{"speakerId":"<id>","content":"<text>"}}'
不要混用音频和 TTS — 选择一种(同时提供两者会被契约拒绝)。
收集完成后,继续步骤 4(使用 PixVerse lip_sync 模板)。
步骤 4:可选参数调整
读取会话默认值并展示。根据模式调整显示内容:
适用于文生视频和参考图模式:
Question: "要调整生成参数吗?当前默认配置:\n 模型: happyhorse\n 分辨率: 1080p\n 比例: 16:9\n 时长: 5 秒"
Options:
- "用默认,直接生成" — Proceed to Step 5
- "我要调整参数" — Ask each parameter below
适用于图生视频(首帧)模式:
Question: "要调整生成参数吗?当前默认配置:\n 模型: happyhorse\n 分辨率: 1080p\n 时长: 5 秒"
Options:
- "用默认,直接生成" — Proceed to Step 5
- "我要调整参数" — Ask each parameter below
**适用于视频编辑模式:**完全跳过步骤 4 — 没有可调整的生成参数(只有分辨率)。
**如果要调整,**逐项询问参数:
模型:
Question: "模型?"
Options:
- "happyhorse(推荐)" — Higher quality, video-edit support
- "doubao-seedance-2-pro" — SeeDance pro, supports last-frame & audio ref
- "doubao-seedance-2-fast" — SeeDance fast
- "pixverse" — PixVerse: 口型同步/模仿/风格化/融合/过渡/广告 agent (OpenAPI only)
如果用户选择 pixverse,切换到下方的 PixVerse 命令模板 — PixVerse 使用独立的 … video pixverse generate 命名空间、显式的 --capability,以及 --quality/--aspect-ratio,而不是 --resolution/--ratio。参见“PixVerse 命令模板”和 references/pixverse-api.md。
分辨率:
Question: "分辨率?"
Options:
- "1080p(推荐)" — High quality (default for HappyHorse)
- "720p" — Standard quality
- "480p" — Low quality (SeeDance only)
限制:如果用户选择 480p 且模型为 happyhorse,告知用户“HappyHorse 不支持 480p,已切换为 720p。”
限制:如果用户选择 1080p 且模型为 doubao-seedance-2-fast,则静默升级到 doubao-seedance-2-pro,并告知用户“1080p 需要使用 pro 模型,已自动切换。”
宽高比(i2v 或视频编辑模式下不显示):
Question: "画面比例?"
Options:
- "16:9" — Landscape, widescreen
- "9:16" — Portrait, phone screen
- "1:1" — Square
- "Other" — 4:3, 3:4, 4:5, 5:4 (4:5/5:4 HappyHorse only)
时长:
Question: "时长?"
Options:
- "5 秒(推荐)" — Standard
- "8 秒" — Medium
- "10 秒" — Long
- "Other" — Custom (HappyHorse: 3–15, SeeDance: 4–15)
Seed(可选):只有当用户提到想复现某个结果时才询问。否则跳过。
步骤 5:费用估算 + 执行确认
构建并运行估算命令(不使用 eval,直接调用):
ESTIMATE=$($CMD_PREFIX estimate \
--model "happyhorse" \
--resolution "1080p" \
--duration 5 \
--ratio "16:9" \
--json 2>/tmp/lh-err)
EXIT_CODE=$?
对于 视频编辑模式,添加 --has-video-input 和 --input-video-duration:
- 如果用户提供了 URL:询问时长
- 本地文件:尽可能使用 ffprobe 检测:
如果 ffprobe 不可用或检测失败,则跳过估算,并在摘要中显示“预估不可用”。INPUT_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "/path/to/ref.mp4" 2>/dev/null | cut -d. -f1)
ESTIMATE=$($CMD_PREFIX estimate \
--model "happyhorse" \
--resolution "1080p" \
--has-video-input \
--input-video-duration "$INPUT_DUR" \
--json 2>/tmp/lh-err)
EXIT_CODE=$?
解析估算结果:
if [ $EXIT_CODE -eq 0 ]; then
TOKENS=$(echo "$ESTIMATE" | jq -r '.tokens // empty')
CREDITS=$(echo "$ESTIMATE" | jq -r '.credits // empty')
else
TOKENS=""
CREDITS=""
fi
rm -f /tmp/lh-err
展示确认摘要:
Ready to generate video:
Prompt: {prompt text}
模式: {纯文字 / 首帧动画 / 参考图 / 视频编辑}
模型: {model}
分辨率: {resolution}
比例: {ratio or "跟随输入"}
时长: {duration} 秒 {or "跟随输入"}
素材: {无 / first-frame: path / references: N 个 / video: path}
预估费用: {tokens} tokens / {credits} credits ← or "预估不可用" if estimate failed
确认生成?
等待用户明确确认后再执行。
执行与轮询
提交(前台)
直接调用 $CMD_PREFIX create,绝不要使用 eval 构建命令字符串。将实际收集到的值代入命令。$CMD_PREFIX 为 listenhub video(内部认证)或 listenhub openapi video(API Key 认证),由步骤 -1 决定。
文本转视频:
RESULT=$($CMD_PREFIX create \
--prompt "用户的视频描述" \
--model "happyhorse" \
--resolution "1080p" \
--ratio "16:9" \
--duration 5 \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
图片转视频(首帧):
RESULT=$($CMD_PREFIX create \
--prompt "用户的视频描述" \
--model "happyhorse" \
--resolution "1080p" \
--duration 5 \
--first-frame "/path/to/first.png" \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
参考图片模式:
RESULT=$($CMD_PREFIX create \
--prompt "[Image 1]中的角色在城市中行走" \
--model "happyhorse" \
--resolution "1080p" \
--ratio "16:9" \
--duration 5 \
--reference-image "/path/to/ref1.png" \
--reference-image "/path/to/ref2.png" \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
视频编辑模式(HappyHorse):
RESULT=$($CMD_PREFIX create \
--prompt "将背景替换为星空" \
--model "happyhorse" \
--resolution "1080p" \
--reference-video "/path/to/input.mp4" \
--audio-setting "origin" \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
SeeDance 帧模式(可选最后一帧):
RESULT=$($CMD_PREFIX create \
--prompt "用户的视频描述" \
--model "doubao-seedance-2-pro" \
--resolution "720p" \
--ratio "16:9" \
--duration 8 \
--first-frame "/path/to/first.png" \
--last-frame "/path/to/last.png" \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
SeeDance 参考模式(图片、视频、音频):
RESULT=$($CMD_PREFIX create \
--prompt "保持参考视频的运镜和色调风格" \
--model "doubao-seedance-2-pro" \
--resolution "720p" \
--ratio "16:9" \
--duration 5 \
--reference-video "/path/to/ref.mp4" \
--reference-image "/path/to/ref.png" \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
PixVerse 命令模板
PixVerse 使用自己的命名空间和显式的 --capability。它仅支持 OpenAPI,因此 $CMD_PREFIX 必须是 listenhub openapi video——调用 … pixverse generate(而非 … create)。PixVerse 的媒体输入必须是公开 URL 或先前的 PixVerse 任务/视频 ID;此处不要传入本地文件路径。画质使用 --quality(360p/540p/720p/1080p),比例使用 --aspect-ratio(9:16/16:9/1:1/4:3/3:4);此处没有 --resolution/--ratio。
text_to_video:
RESULT=$(listenhub openapi video pixverse generate \
--capability text_to_video \
--model pixverse \
--prompt "赛博朋克城市夜景" \
--quality 720p \
--aspect-ratio 16:9 \
--duration 5 \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
image_to_video:
RESULT=$(listenhub openapi video pixverse generate \
--capability image_to_video \
--model pixverse \
--prompt "让画面里的人物自然走动" \
--image "https://example.com/scene.png" \
--quality 720p \
--aspect-ratio 16:9 \
--duration 5 \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
**lip_sync(音频文件):**源视频 + 1 个音频 URL。
RESULT=$(listenhub openapi video pixverse generate \
--capability lip_sync \
--source-video-id "abc123" \
--audio "https://example.com/voice.mp3" \
--quality 720p \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
**lip_sync(TTS):**源视频 + 嵌套的 tts(不要同时传入 --audio)。TTS 必须通过 --pixverse-json 中的嵌套 tts 传入,不要使用 --lip-sync-tts/--lip-sync-speaker-id/--lip-sync-content(这三个 flag 映射到 lipSyncTts*,校验器/provider 不识别,会拒绝请求——上游 listenhub-cli #250 中的 flag→字段映射错误)。
RESULT=$(listenhub openapi video pixverse generate \
--capability lip_sync \
--source-task-id "task_xyz" \
--pixverse-json '{"tts":{"speakerId":"speaker_01","content":"大家好,欢迎来到本期节目"}}' \
--quality 720p \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
mimic:1 张图片 + 1 个视频,画质固定为 720p。
RESULT=$(listenhub openapi video pixverse generate \
--capability mimic \
--image "https://example.com/subject.png" \
--video "https://example.com/motion.mp4" \
--quality 720p \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
**agent(ad_master / promo_mix):**画质仅支持 720p/1080p;时长仅支持 20/30/60;promo_mix 需要 ≥4 张图片。
RESULT=$(listenhub openapi video pixverse generate \
--capability agent \
--agent-type promo_mix \
--prompt "为这款耳机做一支 30 秒带货短片" \
--image "https://example.com/p1.png" \
--image "https://example.com/p2.png" \
--image "https://example.com/p3.png" \
--image "https://example.com/p4.png" \
--quality 1080p \
--duration 30 \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
**fusion:**参考图片通过嵌套的 imageReferences 传入(不要使用顶层 --image,否则会因契约 any.invalid 而被拒绝);提示词必须为每个 refName 写入 @refName。type 取值为 subject/background,refName 须匹配 /^[A-Za-z][A-Za-z0-9_]{0,31}$/。
RESULT=$(listenhub openapi video pixverse generate \
--capability fusion \
--prompt "让 @cat 在 @city 的街道上奔跑" \
--pixverse-json '{"imageReferences":[{"type":"subject","imageUrl":"https://example.com/cat.png","refName":"cat"},{"type":"background","imageUrl":"https://example.com/city.png","refName":"city"}]}' \
--quality 720p \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
**multi_transition:**关键帧通过嵌套的 multiTransition 传入(2–7 个 {imageUrl,duration,prompt};不要使用顶层 --image),默认画质为 360p。
RESULT=$(listenhub openapi video pixverse generate \
--capability multi_transition \
--pixverse-json '{"multiTransition":[{"imageUrl":"https://example.com/k1.png","duration":3,"prompt":"清晨的城市"},{"imageUrl":"https://example.com/k2.png","duration":3,"prompt":"正午的广场"},{"imageUrl":"https://example.com/k3.png","duration":3,"prompt":"夜晚的霓虹"}]}' \
--quality 360p \
--no-wait --json 2>/tmp/lh-err)
EXIT_CODE=$?
PixVerse 能力约束(提交前必须遵守):
mimic——画质固定为 720p(其他值会被拒绝);需要 1 张图片 + 1 个视频,运动源视频时长为 5–30s。agent——画质仅支持 720p/1080p,时长仅支持 20/30/60;promo_mix需要 ≥4 张图片。multi_transition——关键帧通过--pixverse-json中的multiTransition[]传入(2–7 个),顶层--image必须为空;默认画质为 360p。fusion——参考图片通过--pixverse-json中的imageReferences[]传入(1–8 个),顶层--image必须为空;提示词必须为每个refName写入@refName。lip_sync——源视频(--source-video-id/--source-task-id)+ 以下二选一:1 个--audio(5–60s)或嵌套的tts(--pixverse-json '{"tts":{...}}',不要使用--lip-sync-*flag);两者不能同时提供。restyle——--source-video-id(或--source-task-id)+--restyle-id。
PixVerse 估算(匹配生成能力 + 画质/时长):
ESTIMATE=$(listenhub openapi video pixverse estimate \
--capability text_to_video \
--model pixverse \
--quality 720p \
--duration 5 \
--json 2>/tmp/lh-err)
EXIT_CODE=$?
对于 agent,添加 --agent-type ad_master(或 promo_mix)。
仅在需要时使用的 flag:
--no-generate-audio——仅当用户关闭音频时使用(仅限 SeeDance)--seed 12345——仅当用户指定 seed 时使用--audio-setting origin——视频编辑模式下保留原始音频--input-video-duration N——与--reference-video一起使用时必需(2-15s)
错误检查:
if [ $EXIT_CODE -ne 0 ]; then
ERROR=$(cat /tmp/lh-err)
case $EXIT_CODE in
2) echo "Auth error" ;;
*) echo "Error: $ERROR" ;;
esac
rm -f /tmp/lh-err
# Handle error per shared/cli-patterns.md
fi
rm -f /tmp/lh-err
TASK_ID=$(echo "$RESULT" | jq -r '.taskId')
告知用户任务已提交:“任务已提交,ID: {TASK_ID},正在生成中…”
轮询(后台)
使用 run_in_background: true 和 timeout: 1260000(21 分钟)运行:
TASK_ID="{taskId from above}"
for i in $(seq 1 120); do
RESULT=$($CMD_PREFIX get "$TASK_ID" --json 2>/dev/null)
STATUS=$(echo "$RESULT" | jq -r '.status')
case "$STATUS" in
success) echo "$RESULT"; exit 0 ;;
failed) echo "FAILED: $RESULT" >&2; exit 1 ;;
*) sleep 10 ;;
esac
done
echo "TIMEOUT" >&2; exit 2
状态流转:pending → generating → uploading → success | failed
结果展示
成功时,解析结果(注意:get 返回 .id,而不是 .taskId):
VIDEO_URL=$(echo "$RESULT" | jq -r '.videoUrl')
DURATION=$(echo "$RESULT" | jq -r '.duration')
RESOLUTION=$(echo "$RESULT" | jq -r '.resolution')
RATIO=$(echo "$RESULT" | jq -r '.ratio')
SEED=$(echo "$RESULT" | jq -r '.seed')
CREDITS=$(echo "$RESULT" | jq -r '.creditCharged')
从配置中读取 OUTPUT_MODE。按照 shared/output-mode.md 中的行为说明执行。
inline 或 both:显示视频 URL 和元数据。
展示:
视频已生成!
URL: {videoUrl}
时长: {duration}s
分辨率: {resolution}
比例: {ratio}
Seed: {seed}
消耗: {creditCharged} credits
download 或 both:根据 shared/config-pattern.md § Artifact Naming 中的规则,使用基于主题的 slug 保存到当前工作目录:
SLUG="{topic-slug}" # e.g. "赛博朋克城市夜景"
NAME="${SLUG}.mp4"
BASE="${NAME%.*}"; EXT="${NAME##*.}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$VIDEO_URL"
展示:
已保存到当前目录:
{NAME}
失败时:显示错误,并建议检查提示词或参数。
超时时:告知用户稍后查询:
生成超时。你可以稍后用
listenhub video get {taskId} --json(或listenhub openapi video get {taskId} --json)查询结果。
查询历史任务
用户可以请求查询之前的任务或列出最近的任务:
# Get a specific task
$CMD_PREFIX get "{taskId}" --json
# List recent tasks
$CMD_PREFIX list --json
使用与上文成功输出相同的格式展示结果。
错误处理
沿用 shared/cli-patterns.md 中的标准错误代码:
| Code | 含义 | 操作 |
|---|---|---|
| 0 | 成功 | 解析 JSON 输出 |
| 1 | 一般错误 | 向用户显示 stderr |
| 2 | 认证错误 | 内部:通过 listenhub auth login 重新登录。OpenAPI:通过 listenhub openapi config show 检查 API Key |
| 3 | 超时 | 建议稍后查询任务状态 |
API 参考
- CLI 身份验证:
shared/cli-authentication.md - CLI 执行模式:
shared/cli-patterns.md - 配置模式:
shared/config-pattern.md - 输出模式:
shared/output-mode.md - HappyHorse API:
references/happyhorse-api.md - PixVerse API:
references/pixverse-api.md
可组合性
| 方向 | 描述 |
|---|---|
listenhub router → video-gen | 用户通过 /listenhub 提及视频生成时进行路由 |
listenhub-cli router → video-gen | 通过 /listenhub-cli 进行相同的路由 |
video-gen → (none) | 独立的终端技能,没有下游依赖 |
示例
文本生成视频(HappyHorse)
“帮我生成一个视频:赛博朋克城市夜景”
listenhub video create \
--prompt "赛博朋克城市夜景" \
--model "happyhorse" \
--resolution "1080p" \
--ratio "16:9" \
--duration 5 \
--no-wait --json
图片生成视频(HappyHorse)
“把这张图片变成动画视频” + 提供图片路径
listenhub video create \
--prompt "将静态场景转化为流畅动画" \
--model "happyhorse" \
--resolution "1080p" \
--duration 5 \
--first-frame "/path/to/scene.png" \
--no-wait --json
参考图模式(HappyHorse)
“参考这两张图片的风格,生成一段视频”
listenhub video create \
--prompt "[Image 1]中的角色在[Image 2]的场景中漫步" \
--model "happyhorse" \
--resolution "1080p" \
--ratio "16:9" \
--duration 5 \
--reference-image "/path/to/character.png" \
--reference-image "/path/to/scene.png" \
--no-wait --json
视频编辑(HappyHorse)
“把这个视频的背景换成星空”
listenhub video create \
--prompt "将背景替换为深邃的星空,保持人物动作不变" \
--model "happyhorse" \
--resolution "1080p" \
--reference-video "/path/to/input.mp4" \
--audio-setting "origin" \
--no-wait --json
SeeDance 首尾帧模式
“用首帧和尾帧生成过渡动画”
listenhub video create \
--prompt "从白天自然过渡到夜晚" \
--model "doubao-seedance-2-pro" \
--resolution "720p" \
--ratio "16:9" \
--duration 8 \
--first-frame "/path/to/day.png" \
--last-frame "/path/to/night.png" \
--no-wait --json
文本生成视频(PixVerse)
“用 pixverse 生成一个视频:海边日落延时”
listenhub openapi video pixverse generate \
--capability text_to_video \
--model pixverse \
--prompt "海边日落延时,云层快速移动" \
--quality 720p \
--aspect-ratio 16:9 \
--duration 5 \
--no-wait --json
口型同步(PixVerse,TTS)
“把这个视频做口型同步,让人物说这段话”
listenhub openapi video pixverse generate \
--capability lip_sync \
--source-video-id "abc123" \
--pixverse-json '{"tts":{"speakerId":"speaker_01","content":"大家好,欢迎来到本期节目"}}' \
--quality 720p \
--no-wait --json
口型同步(PixVerse,音频文件)
“用这段音频给视频对口型”
listenhub openapi video pixverse generate \
--capability lip_sync \
--source-task-id "task_xyz" \
--audio "https://example.com/voice.mp3" \
--quality 720p \
--no-wait --json