mcpField
V
vox-director

vox-director

github.com/alisa0808创意与媒体2.5k204 次安装3 周前更新
代码仓库

关于 vox-director

Vox Director 是一项技能,可将主题、讲解视频或照片制作成带旁白的纸张拼贴风格视频。它指导节拍规划、视觉生成、动画、音频和 ffmpeg 合成,使用 Atlas Cloud 与本地工具。

主要功能

  1. 01从主题规划视频节拍
  2. 02生成拼贴海报并制作动画
  3. 03支持讲解视频和照片输入
  4. 04制作旁白、音乐与字幕
  5. 05使用 ffmpeg 合成视频

适用场景

  1. 01根据主题制作解说视频
  2. 02将讲解者素材改编为拼贴视频
  3. 03围绕产品照片制作拼贴广告
  4. 04制作带字幕的短视频

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alisa0808/vox-director --skill vox-director

安装后在 Claude Code 中输入/vox-director确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.gitignore
LICENSE
AGENTS.md
SKILL.zh.md
README.zh.md
package.json
llms.txt
examples/
cr7-act.elements_spec.json
money-15s.beats.json
ronaldo-9x16-kling.beats.json
money-60s-9x16-english.beats.json
tang-30s.beats.json
references/
beat-layer.md
local-engine.md
prompt-guide.md
models-and-gotchas.md
host-mode.md
voices.md
scripts/
aroll_assemble.py
assemble.py
audio.py
aroll_clips.py
asr_beats.py
atlas_cloud.py
croll_keyframes.py
confetti.py
kenburns.py
clips.py
host.py

详细介绍

Vox Director

将一句话主题转化为完整的 Vox 风格剪贴纸拼贴视频:一段大胆有力、带旁白的讲解视频/广告,每个节拍都是一张鲜活起来的撕纸拼贴海报,并配有配音、音乐和字幕。使用 一个 Atlas Cloud API 密钥 + 本地 ffmpeg 运行。

这种风格是 Vox 讲解视频和 Stav Zilber / rom1trs 等创作者推广的现代编辑风纸张拼贴:手工剪裁的纸片、撕裂边缘、胶带、半色调网点、报纸剪报,每个节拍采用醒目的纯色,并配以大型剪贴风标题。

核心理念(请先阅读)

Vox 拼贴风格和拼贴动画是两个不同的步骤:

  1. 风格诞生于 IMAGE 步骤。 每个节拍都是由文生图模型制作的完整拼贴海报。所有拼贴元素(撕纸、剪贴图、半色调网点、醒目色彩、标题文字)都体现在这张图里。如果图片不是丰富的拼贴风格,后续步骤都无法补救。
  2. 动画之后添加。 默认情况下,AI 视频模型会为整张海报制作动画(“活海报”路径——简单、自动化)。如需戏剧性的逐块拼合效果,可将海报切分成多个部分,再由本地关键帧引擎驱动(高级路径)。

一切都取决于提示词。编写任何图像或视频提示词之前,请先阅读 references/prompt-guide.md——其中包含精确的提示词结构,决定成品看起来是“真正的 Vox 拼贴”还是“会动的 PowerPoint”。

前置条件(请检查,不要跳过)

  • echo "${ATLASCLOUD_API_KEY:+set}" — 如果输出为空,请告知用户设置该值(在 https://www.atlascloud.ai/console/api-keys 获取),然后停止。
  • command -v ffmpeg ffprobe — 用于合成所必需(macOS 上可运行 brew install ffmpeg 安装)。
  • python3 -c "import PIL" — Pillow,用于字幕/水印叠加。

标准工作流(主题 → 影片)

这是默认且自动化程度最高的路径。每个阶段都由一个脚本完成,所有内容由每个项目目录 out/<project>/ 下的单个 beats.json 驱动。

  1. 主题 → 节拍图。 首先阅读 references/beat-layer.md(故事层),并选择适合主题的叙事 arc(历史主题用 timeline,广告用 pas / bab,讲解视频用 how_it_works,转变主题用 man_in_hole,……)。然后按照该叙事弧编写 out/<project>/beats.json:beat-1 标题必须是 ≤3s 的钩子;根据时长设定节拍数量(30s→6–8 个,60s→10–12 个);每个节拍拆分成 2 个镜头(远景 + 特写),相邻节拍的每镜头 camera_move 必须各不相同(不得重复;高潮点使用 static),并设置丰富的 element_motion(见步骤 4)。每个节拍包含:narration、title_cn / title_en、scene、bg、feel、hook。此草稿是第一个强制审批关卡——生成之前先向用户展示节拍图。(步骤 4 中的画幅路由近似方案是另一个审批关卡。)示例见 examples/。

  2. 选择视觉风格(混合式——在关键帧之前完成)。 不要对所有主题都套用同一种固定风格。阅读 references/prompt-guide.md 的 §5 主题预设;选择 3–4 个适合主题时代/文化/基调的主题预设 (styles.THEME_PRESETS:american-retro、swiss-modern、punk-zine、 soviet-constructivist、wpa-propaganda、70s-groovy、chinese-ink、atomic-age、 newsprint-editorial),或者在没有合适预设时,混合提示词指南中的维度 (媒介/时代/调色板/字体/质感)来构建自定义主题。匹配主题本身,而不是语言(以中文历史为主题的英文影片也应该呈现中国风格)。主题涵盖整个视觉层(风格语言 + 调色板 + 字体 + 质感 + 氛围 + 动态)。进行多方案对比,让用户凭视觉选择——AI 提出方案,素材库设定质量底线,人类做决定。将选中的方案设为 "theme": python3 scripts/style_bakeoff.py out/<project> american-retro,swiss-modern,punk-zine,atomic-age 在 beats.json 中将选中的名称设为 "collage_style"(keyframes.py 会读取该值)。

  3. 关键帧(拼贴风格)。 python3 scripts/keyframes.py out/<project> 使用 google/nano-banana-2/text-to-image,为每个节拍/镜头生成一张拼贴海报, 并将标题文字直接融入画面。按照 references/prompt-guide.md 中的五部分结构编写 提示词。开始动画制作前,确认每张海报看起来都像一张真实的分层拼贴——此时重新生成很便宜($0.08),不妨重试,而不是花钱为效果不佳的图像制作动画。

  4. 动态效果。 python3 scripts/clips.py out/<project> 使用 google/gemini-omni-flash/image-to-video 为每张海报制作动画。两个彼此独立的维度 (参见 references/beat-layer.md §3,已在我们的技术栈中测试): • camera_move — 每个镜头使用一种运镜方式。安全/默认选项:{static, push_in, pull_out, pan, tilt, parallax}。大胆/实验性选项 {orbit, dolly_zoom, roll, whip} 可以使用,并未禁用——这些运镜可能会扭曲扁平画面,因此请搭配 constraints: loose 并重新生成。 也可以使用任何自定义短语。 • element_motion — 动态效果的核心所在;由 AI 根据场景为每个节拍编写(不是套用模板)。让动作丰富起来(让多个元素移动)——大胆尝试。在关键节拍中,偶尔让一个主视觉元素飞过画面(纸鸟/纸飞机/硬币)能带来很好的冲击力,但不要每个镜头都这样(每帧都有飞行物会显得套路化)。 motion_style = 振幅 calm | punchy | max(主题会设置默认值)。constraints = strict(默认:启用缺陷防护——平面 2D、单向运动、不变形;最适合文字清晰的解说视频)或 loose(让模型探索 3D/大胆运镜;不满意的片段重新生成)。只有带标题的镜头才会对标题文字进行严格保护(没有标题的细节镜头可以自由发挥)。对于真人/品牌徽标,Omni 和 Seedance 会拒绝生成——请设置 "video_model": "kwaivgi/kling-video-o3-pro/image-to-video"。 画幅路由(styles.resolve_video_aspect,第二个确认关卡):clips.py 会根据所选 video_model 支持的画幅比例,解析 doc["aspect"]——精确匹配优先; Omni 仅支持 16:9/9:16,Kling 参考图转视频额外支持 1:1,Kling 图像转视频/视频编辑和 Seedance 则遵循输入画面/比例参数。如果没有精确匹配,就会选择最接近的比例,但会暂停并请求你确认(确认后设置 "aspect_approx_confirmed": true),而不是悄悄重新构图——一次运行中的所有片段都使用相同的已解析画幅,确保最终视频不会混用画幅。

  5. 配音 + 音乐。 python3 scripts/audio.py out/<project> 使用 xai/tts-v1 生成统一的旁白,并通过 minimax/music-2.6 配上纯音乐背景音乐。 选择符合主题和语言的 voice_id(不要直接沿用默认值)——完整语音列表请参见 references/voices.md(按语言划分,包含 5 种多语言语音和约 66 种母语语音,并标注性别)。默认值为 leo(男性,纪录片风格)。如需使用真人本人的声音进行旁白 (例如 C-roll 照片中的演讲者或品牌声音),请将 voice.clone_ref 设置为本地音频样本——旁白会改用种子音频克隆,并采用固定说话人、录音棚级清晰度的模板,确保时长与节拍稳定(请注意:切勿在没有该固定设置的情况下,直接将种子音频用于纯旁白)。

  6. 合成。 python3 scripts/assemble.py out/<project> 使用 ffmpeg:统一所有镜头的规格并拼接,在音乐下方混入单条旁白并降低音乐音量,按节拍时间添加字幕,再添加水印。输出文件为 out/<project>/final.mp4。

  7. 验证。 无法直接读取 mp4——请将视频帧提取为 jpg 并查看: ffmpeg -ss <t> -i final.mp4 -vf "scale=640:-1,format=yuvj420p" -frames:v 1 f.jpg

节奏——镜头应持续多久

常见的错误做法是每个节拍只用一个长镜头。尤其是对于 9:16 的社交媒体短片,10s 的静态镜头看起来会像冷场。建议每隔约 4–6 秒切一次镜头:

  • 每个镜头持续 3–6s;绝不要让单个镜头超过约 7s——超过这个时长,AI 动效就没有发挥空间,画面会显得静止。
  • 每段旁白约 8–10s,因此每个节拍安排 2 个镜头(一个带标题的广角建立镜头,再接一个不带标题的细节切入镜头)。旁白在两个镜头间连续播放;画面在句子中途切换。这是提升节奏感最有效的做法。
  • 因此,一部约 60s 的短片通常是 约 6 个节拍 × 每个节拍 2 个镜头 × 每个镜头约 5s = 12 个镜头,而不是 6 × 10s。
  • 将广角关键帧复用为镜头 a;为镜头 b 生成一个更紧凑的细节场景。keyframes.py 会跳过已有 keyframe_url 的镜头,因此添加 b 镜头后重新运行时,只会生成新增镜头。

为每个节拍添加一个 shots 数组(参见架构)。为每个镜头设置各自简短的 scene 和 motion;仅在广角镜头上设置 "title": true,让标题每个节拍只显示一次。

A-roll 模式(对镜讲述 → 拼贴画面)

上述标准工作流是 B-roll:将主题转化为 AI 生成的拼贴海报,再为其添加动效。A-roll 则恰好相反——用户已有一段真实录制的对镜讲述视频(主持人面对镜头讲话),希望将视频本身转换成拼贴风格,同时保留其真实表现(面部、唇部动作、手势)。无需生成海报;“关键帧”就是主持人自己的素材。当用户提供自己或主持人讲话的视频文件,而不是一个需要从头创作的主题时,请使用 A-roll。

  1. 转录并自动分段。 python3 scripts/asr_beats.py <project_dir> <source.mp4> 使用 xai/stt-v1 处理源视频自身的音频,并在句末标点或自然停顿处切分节拍(每段绝不超过约 9.5s,低于 Omni/Kling 视频编辑每次调用 10s 的上限)。生成包含每个节拍的 start/end/text 的 beats.json——这与 B-roll 节拍图一样,是必须经过审核的关卡:先审核,然后设置 "theme"(以相同方式运行 style_bakeoff.py——主持人的片段也完全可以作为风格对比测试素材),并可选择为每个节拍填写 content_beats 字符串,作为要叠加的贴纸或印章创意,然后再进行生成。

  2. 生成。 python3 scripts/aroll_clips.py <project_dir> [only_ids] 从源视频中截取每个节拍对应的时间范围,上传并为主持人重新添加写实剪纸贴纸效果——她真实的容貌、唇部动作、视线方向和手势都会逐帧跟随源视频;只有轮廓边缘和周围环境采用纸艺拼贴风格。默认模型为 google/gemini-omni-flash/video-edit;任何被其拒绝的节拍都会自动重试 bytedance/seedance-2.0/reference-to-video(通过 beats.json 中的 video_model/video_model_fallback 设置)。绝不要要求模型重新绘制人脸,或为人脸添加半色调纹理——无论提示词措辞如何,这类请求都会被拒绝(强硬和委婉的说法都试过,均失败)。使用与 clips.py 相同的宽高比路由确认关卡。

  3. 组装。 python3 scripts/aroll_assemble.py <project_dir> 将每个生成片段与其原始节拍片段自带的音频合并(绝不使用视频模型生成的音频),这样无论哪个模型处理该节拍,都能保证唇音同步;将所有节拍统一为同一画布尺寸,再合并为 final.mp4。

C-roll 模式(单张照片 → 拼贴)

第三种输入模态——“剪贴卷轴”。A-roll 会重新设计说话人视频的风格;B-roll 会根据主题生成所有内容;C-roll 使用一张静态照片(自拍、头像卡片、产品照片),并将其锚定在拼贴世界中:主体会被抠出,作为照片风格贴纸——绝不重新绘制——再通过图像编辑模型围绕它生成每个节拍的海报,随后通过常规片段阶段为海报添加动画。用户提供一张照片和一个主题时,使用 C-roll:例如以用户自己的脸为主角的个人解说,或围绕真实产品照片制作的拼贴广告(两种场景均已验证,2026-07-17)。

  1. **节拍图。**与 B-roll 相同(references/beat-layer.md,审批关卡也相同),并在 beats.json 中添加 C-roll 字段:"mode": "croll"、"anchor_photo"、"croll_subject"(portrait | product),以及 subject_wardrobe(人像——锁定服装,否则纸娃娃身体会发生漂移)或 subject_desc(产品)。在镜头上设置 "title": false——C-roll 海报不带标题;文字应放在字幕中。如果没有单独的脚本,先转录或推导旁白,再让音频的 ASR 时间戳来定义节拍(以音频为先,类似 A-roll——而非像 B-roll 那样以文本为先)。

  2. 锚定关键帧。python3 scripts/croll_keyframes.py <project_dir> 会上传一次照片,并通过 google/nano-banana-2/edit 生成每个镜头的一张锚定海报(备用方案为 openai/gpt-image-2/edit)。人像会保留照片风格的脸部,并配上插画风格的纸娃娃身体;产品会生成像素级忠实的贴纸,标签字体保持完整。提示词中内置了以下规则(这三条都是踩过坑后才学会的):姿势和表情只作用于身体——要求眨眼会导致脸部重绘;网点效果必须限定在背景,否则会渗到皮肤上;人像服装必须明确锁定。脚本还会将 anchor_freeze 写入 beats.json。

  3. **添加动画 + 音频 + 合成。**按标准流程运行 clips.py → audio.py → assemble.py。 clips.py 会将 anchor_freeze 防护规则注入每个动态提示词——没有它,视频阶段可能会重新绘制产品标签上的文字(观察到“PARFUM”变成“PAREUM”),或改变人脸的时间位置。若要使用主体本人的声音进行旁白,请设置 voice.clone_ref(参见上文“声音 + 音乐”);根据旁白的 ASR 单词时间戳推导印章和快速缩放的时机(asr_beats.py 可用于任何音频,不限于 A-roll 素材)。

Host 模式(主持人面对镜头讲话)

当用户想让数字主持人出现在屏幕上讲述部分旁白,且只提供了该主持人的一张静态图像时使用(不是录制的视频:那属于 A-roll)。将这些节拍标记为镜头 "kind": "host";其他所有节拍保持为常规 B-roll。完整流程、规则和限制见 references/host-mode.md(使用此模式前请先阅读)。

  1. 添加 host.avatar(已完成的角色设计,绝不重新绘制),并为每个主持人节拍添加一个镜头,其中包含 "kind": "host"、仅描绘世界的 scene,以及列出每个元素并固定其形状的 element_motion。该节拍的旁白最长为 9.5 s。
  2. 先运行 audio.py,然后运行 python3 scripts/host_plates.py out/<project>:查看两张底图(纯绿色、面部完整、空白区域清晰),再开始投入视频生成。
  3. python3 scripts/host_clips.py out/<project> 会打印费用估算并停止;先向用户展示估算,然后使用 --yes 重新运行。它会分别生成主持人(Seedance)和场景(Omni),采用主持人片段自带的音频,并将两者合成。
  4. clips.py 和 keyframes.py 会跳过 host 镜头;assemble.py 绝不会拉伸它们。

用户可以使用 host.position 和 host.size 来放置主持人并调整其大小。支持 16:9 和 9:16。每秒的 Host 片段费用约为 B-roll 片段的两倍。已知问题:场景视频可能会漂移(参见参考文档);如果发生漂移,请重新生成。

beats.json 架构

{
  "project": "my-film", "topic": "...", "language": "en",
  "aspect": "9:16",                       // 16:9 | 9:16 | 1:1 | 3:4
  "style": "collage",
  "provider": "atlas_cloud",              // media backend — default; pluggable (scripts/provider.py)
  "theme": "american-retro",              // THEME_PRESET (styles.THEME_PRESETS) — the LOOK layer
  "arc": "timeline",                      // narrative arc (beat-layer.md) — the STORY skeleton
  "video_model": "google/gemini-omni-flash/image-to-video",  // Kling for real people
  "image_model": "google/nano-banana-2/text-to-image",       // keyframes; or openai/gpt-image-2/text-to-image
  "image_resolution": "1k",               // 1k (default) | 2k | 4k
  "video_resolution": "720p",             // 720p (default); Seedance also 480p/1080p (Omni is 720p-only)
  "motion_style": "punchy",               // amplitude: calm | punchy | max (theme sets a default)
  "constraints": "strict",                // strict = defect guards on | loose = let AI explore + re-roll
  "voice": {"voice_id": "leo", "language": "en", "speed": 1.0},  // pick per topic/language — see references/voices.md
                                          // + optional "clone_ref": "path/to/sample.mp3" (clone that voice via seed-audio)
                                          //   and "persona": "YouTube tutorial creator" (delivery style for cloned VO)
  "music": "epic cinematic orchestral, instrumental, no vocals",
  "mix": {"music": 0.6, "voice": 1.25},   // audio balance — optional; these are the defaults (BGM ducks under the VO)
  "caption_style": "white",               // white (default: clean white subtitle) | paper (cream cut-out collage look)
  "captions": true,                       // false = no burned-in captions (deliver clean, subtitle in post)
  "watermark": "Made with Atlas Cloud",
  "host": {"avatar": "path/to/presenter.jpg", "position": "left", "size": 0.25},   // host mode only (references/host-mode.md)
  "mode": "croll",                        // C-roll only — plus the four fields below
  "anchor_photo": "path/to/photo.png",    // C-roll: the still to anchor (person or product)
  "croll_subject": "portrait",            // C-roll: portrait | product
  "subject_wardrobe": "a cream knitted sweater and charcoal trousers",  // C-roll portrait: outfit lock
  "subject_desc": "the perfume bottle",   // C-roll product: short noun phrase for the sticker
  "beats": [
    {
      "id": 1, "title_cn": "", "title_en": "BEFORE MONEY",
      "bg": "earthy clay tan", "feel": "ancient, humble", "hook": "surprising_stat",
      "narration": "For most of history, there was no money...",
      "shots": [
        // shot_size: EST_WIDE|WIDE|MEDIUM|CLOSE|DETAIL ; camera_move: static|push_in|
        // pull_out|pan|tilt|parallax (flat-safe only) — VARY per adjacent beat, static for payoff
        {"id": "a", "dur": 5, "title": true,  "shot_size": "WIDE", "camera_move": "push_in",
         "scene": "...wide establishing collage...",
         "element_motion": "traders gesture, goat bobs, a paper bird flaps across the frame, coins scatter"},
        {"id": "b", "dur": 5, "title": false, "shot_size": "CLOSE", "camera_move": "parallax",
         "scene": "...close cut-in detail...",
         "element_motion": "the exchanged goods slide together, halftone pulses"}
      ]
    }
  ]
}

theme+arc 设定两个大层面;每个镜头的 element_motion 决定能量感(要丰富——见下文)。为保持向后兼容,仍会读取 motion/collage_style/era。

模型选择(务必实时验证 ID)

模型 ID 会变动——请先获取实时列表:GET https://api.atlascloud.ai/api/v1/models (无需身份验证;仅保留 display_console: true)。目前可用的默认值:

任务模型说明
关键帧 / 拼贴海报google/nano-banana-2/text-to-image默认;中英文文字渲染效果好;image_resolution 1k/2k/4k
关键帧(备选)openai/gpt-image-2/text-to-image通过 image_model 设置;根据宽高比和分辨率自动映射尺寸和质量
抠出元素youchuan/v8.1/remove-background仅限高级路径
动画(非真实内容)google/gemini-omni-flash/image-to-video保持文字稳定,实现分层运动
动画(真实人物 / 品牌)kwaivgi/kling-video-o3-pro/image-to-videoOmni 和 Seedance 会屏蔽名人
旁白xai/tts-v1清晰、支持多语言,使用 voice_id
音乐minimax/music-2.6is_instrumental: true

有关模型选择的完整说明以及所有 API / ffmpeg 注意事项(身份验证标头、curl 下载、无 libass 字幕、内容块等),请参阅 references/models-and-gotchas.md。 调试任何故障前请先阅读——大多数故障已有记录。

后端可插拔。 每次 API 调用都会通过一个提供方(scripts/provider.py);Atlas Cloud 是当前默认且唯一的后端。在新增其他后端后,可在 beats.json 中设置 "provider" 来路由到不同后端——阶段脚本无需更改。scripts/provider.py 的 run_jobs() 还会负责提交 / 轮询,并在任务停滞或失败时自动重新提交。

高级:元素级运动拼贴

标准路径会为整张海报制作动画(效果出色、自动化,宛如“会动的海报”)。若要制作戏剧性的碎片飞入并组装运动拼贴(类似 cr7v2),或在完全自主控制且不受内容过滤限制的情况下为真实人物制作动画,可将每张海报切分为独立元素,并使用本地关键帧引擎驱动(无需视频模型)。

请阅读 references/local-engine.md。简而言之:extract_elements.py(裁剪 + 背景移除 + 残留清理 / 擦除)→ motion.py(图层 + 关键帧,fly_in/slap/drop/pop_settle 缓动、程序化五彩纸屑 / 星芒、镜头缩放 + 抖动 + 鞭甩、帧渲染)。碎片会飞回模糊占位背景上的原始位置,因此组装后的画面会还原原始海报。

版本

  • 自动版(此技能):输入主题,输出影片,全程使用 Atlas。
  • 手动提示词包:如果用户不使用 Atlas,只需为他们生成节拍图 + 每拍的图像提示词 + 每段片段的运动提示词 + 旁白脚本,供他们粘贴到任意生成器中。创意引擎(提示词)完全相同。

评论

支持 Markdown