mcpField
V
video-gen

video-gen

github.com/marswaveai创意与媒体81328 次安装5 周前更新
代码仓库

关于 video-gen

video-gen 是通过 ListenHub CLI 创建和编辑 AI 视频的 Agent 技能。它根据需求使用 HappyHorse、SeeDance 或 PixVerse,并支持 PixVerse 独有的口型同步及广告或宣传视频生成。

主要功能

  1. 01文本生成视频和图像生成视频
  2. 02使用参考图像与视频
  3. 03通过 HappyHorse 编辑视频
  4. 04PixVerse 口型同步与风格转换
  5. 05以 JSON 输出异步生成任务

适用场景

  1. 01根据文本提示生成视频片段
  2. 02为静态图像或参考素材制作动画
  3. 03编辑现有视频
  4. 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,并使用自己的 pixverse CLI 命名空间。

硬性约束

  • 始终按照 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 ...,并正确处理引号
每个多选步骤都必须使用 AskUserQuestion 工具——不要以纯文本形式列出选项。每次只提一个问题。等待用户回答后再进入下一步。收集完所有参数后,总结所选内容并请用户确认。用户明确确认前,不要调用视频生成命令。

模型对比

功能HappyHorse(默认)SeeDancePixVerse
文本生成视频✅✅✅ (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、1080p480p、720p、1080p360p、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:416:9、9:16、1:1、4:3、3:4、21:99:16、16:9、1:1、4:3、3:4
提示词长度≤2500 中文 / ≤5000 非中文≤500≤2048
速率限制5 RPM5 RPM5 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}

然后询问:

  1. 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:图生视频(首帧)
  1. first-frame(必需):询问图片路径或 URL。

    • 支持格式:jpg、jpeg、png、webp
    • 本地图片文件最大 10MB
    • 图片:宽度和高度 ≥ 300px,比例介于 1:2.5 和 2.5:1 之间
    • 本地图片:CLI 会自动填充 Seedance 元数据。远程 Seedance 图片 URL 需要 --first-frame-meta WIDTHxHEIGHT[:SIZE]。
  2. 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。

  1. video(必需):询问视频路径或 URL。

    • 支持的格式:mp4、mov(建议使用 H.264)
    • 时长:3–60s(输出最长为 15s)
    • 最大 100MB,短边 ≥ 360px,长边 ≤ 4096px
    • 仅支持 URL(不支持 base64)
  2. reference-image(可选,0–5 张):询问是否有用于编辑的参考图。

  3. audio-setting:

Question: "音频如何处理?"
Options:
  - "自动(模型决定)" — audio_setting: auto
  - "保留原声" — audio_setting: origin

收集完成后,继续步骤 4。

**注意:**视频编辑没有 ratio 或 duration 参数,输出与输入视频一致。

步骤 3d:口型同步模式(仅限 PixVerse)

口型同步仅在 PixVerse 上可用(--capability lip_sync)。如果用户使用 HappyHorse/SeeDance,告知用户:“口型同步仅 PixVerse 模型支持,已自动切换。”并使用步骤 4 中的 PixVerse 命令模板。

  1. source video(必需):用于驱动口型的视频。收集以下任意一项:

    • --source-video-id <id> — PixVerse 视频 ID,或
    • --source-task-id <id> — 可复用的先前已成功 PixVerse 任务。

    (仅 OpenAPI 支持;源视频必须已存在于 PixVerse 上。)

  2. 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 检测:
    INPUT_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "/path/to/ref.mp4" 2>/dev/null | cut -d. -f1)
    
    如果 ffprobe 不可用或检测失败,则跳过估算,并在摘要中显示“预估不可用”。
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

评论

支持 Markdown