首页
/ OpenMontage 镜头规划 IR(shot-plan.json):连接 Director 与 Builder 的统一镜头契约详解

OpenMontage 镜头规划 IR(shot-plan.json):连接 Director 与 Builder 的统一镜头契约详解

2026-09-08 14:01:24作者:伍霜盼Ellen

导读

在 OpenMontage 的 motion-graphics 技能体系(设计驱动的短片镜头制作流水线)中,shot-plan IRDirector(导演智能体)与 Builder(构建智能体)之间唯一的传令契约:一次任务只对应一个文件 shot-plan.json,所有创意决策与构建指令都在该文件内序列化。本文将完整拆解这份 IR 的字段语义、各动画类别的 content 数据形状、可复用的「复用优先」构建约定,并结合仓库源码说明它在 plan → source → design → build → render → verify 全流程中如何流转,帮助你读懂、编写和消费这份镜头计划文件。

一、这份 IR 在流水线中的位置

1.1 一个技能、两段式导演

参考 .agents/skills/motion-graphics/agents/director.md,Motion-Graphics Director 围绕素材采购节点被切成两段:

  • Part 1(plan,素材采购前):做两类关键决策 —— 是否需要进行搜索走哪个类别,并输出一份 DRAFT shot-plan.json(envelope + 已选表单类别或搜索意图 + asset_needs + 一段镜头 brief)。
  • Part 2(design,素材采购后):围绕已解析到的真实素材设计镜头,挑选目录 block 与动效规则,最终确定 content.block + content.customize 及各类别专属 content,输出 FINAL shot-plan.json

而 Builder 智能体则只消费这份文件:.agents/skills/motion-graphics/agents/builder.md 开篇即声明「把 shot-plan.json 变成一份可渲染的 HyperFrames composition」。

1.2 流水线的其余环节

参考 .agents/skills/motion-graphics/SKILL.md,完整流程为:

阶段 执行者 主产物 说明
init Bash hyperframes.json 初始化项目
plan 子智能体(Director Part 1) shot-plan.json(草稿) 决策「是否需要搜索」+ 分类 + 素材策略
source Bash(asset_needs 非空时执行 assets/ + assets/index.md 素材采购(搜索/生成/抓取)
design 子智能体(Director Part 2) shot-plan.json(终稿) 围绕已解析素材做镜头设计
build 子智能体(Builder) compositions/index.html 复用优先的组合式搭建
render Bash renders/video.mp4 HyperFrames 渲染
verify Bash 原地修复 lint / inspect / 失败则派发修复子智能体

关键点:source 阶段是条件执行的 —— 纯代码/文本类别(如 kinetic-type、大多数 charts/stat)的 asset_needs 为空数组,会直接从 plan 跳到 design。这正是 IR 中「空 asset_needs ⇒ 跳过 Step 2(source)」这一不变量在设计层面的体现。

二、IR 的整体结构:四层区块

shot-plan.json 是单一文件(位于 PROJECT_DIR 下),其结构按职责分为四层。IR 原文(.agents/skills/motion-graphics/references/shot-plan-ir.md)给出的完整骨架如下:

{
  // ── envelope(所有类别通用)──
  "category": "kinetic-type | stat | charts | logo-reveal | lower-thirds | webpage | news | tweet | asset-fusion",
  "duration_s": 6,
  "fps": 30,
  "canvas": { "w": 1080, "h": 1920, "aspect": "9:16" },
  "style": "自由形态的画面方向(氛围 / 能量 / 参考)",
  "palette": ["#…"], // 或 "derive-from-asset"
  "font": "<HF embed-list font>",
  "beats": [12, 37], // 可选的强调帧/秒
  "export": "mp4", // 或 "alpha-overlay"(透明 webm/mov)

  // ── sourcing seam(Director Part 1)—— [] 表示跳过素材阶段 ──
  "asset_needs": [
    {
      "role": "hero",
      "kind": "image|icon|logo|svg|news|web|tweet",
      "query": "…",
      "source": "…",
      "treatment": "cutout|recolor|vectorize|none",
    },
  ],

  // ── build directive(Director Part 2,复用优先)──
  "block": "<catalog block id,例如 data-chart | caption-kinetic-slam>", // 可选
  "customize": {
    /* 要改动 block 的哪些部分:data、text、palette、positions */
  },

  // ── 类别专属内容 ──
  "content": {
    /* 形状随类别而变,见下 */
  },
}

下面逐层展开讲解。

三、envelope:镜头的基础信封参数

envelope 是所有类别共用的「信封」,定义了镜头最基本的物理与风格参数,由 Director Part 1 在草稿阶段确定。参考 director.md 中 Step 3 的说明:

字段 取值 / 约束 说明
category kinetic-type / stat / charts / logo-reveal / lower-thirds / webpage / news / tweet / asset-fusion 类别是镜头类型的一等公民
duration_s 3–30 时长约束来自 skill 定位(short, ~under 10s 到约 30s)
fps 30(默认) 统一为 30fps 便于与 HyperFrames 引擎对齐
canvas {w, h, aspect},默认 1080×1920 默认竖屏 9:16;16:9 / 1:1 依据平台选择
style 自由形态字符串 描述氛围 / 能量 / 视觉参考方向
palette hex 数组,或 "derive-from-asset" 色板;asset-fusion 类通常要求从素材中取色
font HF embed-list 字体 必须是 HyperFrames 内嵌字体清单中的字体,保证确定性渲染
beats 可选的秒/帧数组 标记节拍 / 强调点,例如 [12, 37]
export mp4 / alpha-overlay alpha-overlay 表示透明背景,渲染为透明 webm/mov

其中 duration_s 有一个硬约束值得注意:在 agents/builder.md 与 SKILL 的 repair 阶段都强调 「repair 时绝不更改已固定的 duration」 —— 因为整条时间线、clip 划分与节拍设计都以此为锚。

beats 允许提前约 0.1s 营造「感知上的同步」(anticipation),这是 Director 启发式规则的一部分:「关键元素保持可读 ≥ ~0.3s;beats 可提前 ~0.1s 以获得感知同步」。

四、sourcing seam:asset_needs 素材采购缝

asset_needs 数组是 Director Part 1 与素材采购阶段(Step 2 / source)之间的接口,即原文档所称的「sourcing seam」。它的存在与否直接决定流水线是否分支。

4.1 字段语义

每个需求项包含:

字段 含义
role 素材角色(如 hero
kind image / icon / logo / svg / news / web / tweet
query 搜索词
source 来源(当由用户提供时,如 logo-reveal 的用户 logo,直接写 source
treatment 后期处理:cutout(抠图)/ recolor(换色)/ vectorize(矢量化)/ none

4.2 按类别决定素材策略

结合 director.md Step 2:

  • asset-free(asset_needs: []kinetic-type、大多数 stat / charts。内容由用户提供。
  • webpage / news / tweet:搜索真实来源(页面 / 文章 / 推文)+ 一张配图。搜索查询遵循两极查询规则:要么原子化(1–3 词、可组合:肖像、logo、物体),要么具体化(5–15 词描述一个新闻事件/推文),绝不取中间态;失败的具体查询直接丢弃而不放宽。
  • asset-fusion:搜索或生成一个 hero 素材。
  • logo-reveal:用户提供 logo(填 source)。

4.3 空数组 = 跳过整个素材阶段

IR 中明确:空 asset_needs ⇒ Step 2(source)被跳过。这也解释了 SKILL 中的运行语义:source 是 Bash 执行的 media-use 解析环节,仅当 shot-plan.json.asset_needs 非空时运行;若某个搜索/provider 不可用,类别会优雅降级为 asset-free,并在 context.log 中记录。

五、build directive:复用优先的构建指令

block + customize 是 IR 的「构建指令」部分,由 Director Part 2(design)写入。

  • block:命名的 catalog block id,例如 data-chartcaption-kinetic-slam可选项 —— 若存在命名 block,意味着 Builder 应复用 + 定制该 block,而非手工创作。
  • customize:具体改动内容(data、text、palette、positions)。

这套机制的背后逻辑(见 catalog-map.md):大多数 block 把内容/数据烘焙进自身脚本里,只有少数暴露 CSS-var params,因此复用 = npx hyperframes add <block> + 原地编辑,而非纯变量注入。手工创作仅限两种情况:(a) 目录 block 覆盖不了的空白;(b) asset-fusion 的 affordance 绑定。

典型 IR 片段:

"content": { "block": "data-chart", "customize": { "data": [...], "headline": "…", "palette": ["…"] } }

Builder 侧的操作约定(builder.md):content.blockhyperframes add(或 inline)+ 应用 content.customize;每类别的 content 按 [类别 module] 落实;解析后的素材引用冻结的项目本地路径(绝不引用远端 URL 或 prompt);export: alpha-overlay 时渲染用 --format webm(或 mov)。

5.1 类别 → block 对照(供 Director 挑选)

catalog-map.md 为 Director 提供了「类别 → 借用哪个 block → 定制什么 → 哪些空白需手写」的映射表,节选关键行:

类别 借用目录 定制点 需手写的空白
kinetic-typo 18 个 caption-* block 之一(kinetic-slam、editorial-emphasis、clip-wipe、gradient-fill、neon-glow、glitch-rgb、matrix-decode、particle-burst、weight-shift、pill-karaoke、highlight、blend-difference…) 文案、emphasis_wordsword--emphasis、色板、字体、节奏 18 个之外的新母题
charts data-chart(bar+line、staggered、值标签) 数据数组 + 标题/副标题、--bg/--text pie/donut、bar-chart-race、ring/%
stat apple-money-count(金融风:$ 计数器 + burst + SFX)或通用 stat-motion target、prefix/suffix、label、色板
brand reveal logo-outro logo 素材、tagline、URL、色板

六、per-category content:九种镜头类型的内容形状

IR 的精髓在于:content 的形状按类别变化。这是 Director 写入、Builder 读取的结构化数据。

6.1 表单类别(用户提供内容,无需搜索)

kinetic-type —— 文字即英雄:

"content": {
  "scenes": [
    { "id": "s1", "start": 0, "end": 2, "text": "…", "emphasis_words": ["…"], "emotion": "…", "motion": "slam", "beats": [] }
  ]
}

结合 kinetic-type module:文案需按意义/气息切分成场景(英文约 3–7 词、中文约 4–12 字),为每场标注 Hook → Build → Punch → Resolve 的结构标签,每场景 1–2 个 emphasis_words + emotion + motion(来自动效词表,如 slam / word_reveal)+ beatsmotion 字段的值取自共享动效词汇表 references/motion-vocabulary.md(slide_bottom / scale_punch / fade_blur / typewriter / wave / slam…),该词表同时给出每条原语的 GSAP 配方与适用气质。

stat —— 单一英雄数字:

"content": { "value": 750000000, "prefix": "$", "suffix": "", "label": "…", "ring": true }

stat module,数字约 4–6s:计数动画必须时间线驱动(用 onUpdate 写入格式化数字的代理对象,保证 seek-safe,绝不使用 setInterval/壁钟计数器),font-variant-numeric: tabular-nums,减速缓动,约 1.2–1.6s 后保持最终值;圆环用 stroke-dashoffset 与计数同步收尾,label 在数字落地之后再淡入(先数值后意义)。

charts

"content": { "type": "bar|line|pie|race|pct", "data": [], "labels": [], "headline": "…", "axes": true }

logo-reveal

"content": { "logo": "<asset path>", "tagline": "…", "url": "…" }

lower-thirds

"content": { "name": "…", "role": "…", "position": "…", "brand_colors": [] }

6.2 搜索驱动类别(真实内容动画化,RWA 路径)

webpage —— 对真实抓取的页面做步骤高亮:

"content": { "url": "…", "capture": true, "highlights": [ { "selector|region": "…", "label": "…" } ] }

news —— 文章高亮(article-highlight)。注意原文中的关键语义:

把文字以可读尺寸铺开(绝不做 zoom),然后让 marker band 原位扫过关键词

"content": { "outlet": "…", "headline": "…", "body": "…", "keyword": "…", "layout": "A|B", "logo": "…", "date": "…", "subject": "…" }

Layout A = 9:16 居中强调的纯文字;Layout B = 16:9 完整文章布局,含 logo + date + subject(人物照片需经 remove-background 抠图成透明 cutout)。详见 news module

tweet

"content": { "author": "…", "handle": "…", "avatar": "…", "text": "…", "metrics": { "likes": 1234, "retweets": 567 } }

asset-fusion —— 素材几何体"变成"图表(真正的净新增 IP):

"content": {
  "data_type": "…",
  "asset": "<path>",
  "affordance": "…",
  "element_positions": { "center":, "extent":, "safe": [], "avoid": [] },
  "derived_palette": [],
  "connectors": []
}

catalog-map.md 的 asset-fusion 逻辑:先判断数据类型、读取素材的几何 affordance(线性 → 时间线/仪表盘;体积/纹理 → 饼图;高度 → 柱状;容器 → 爆炸视图);element_positions 是对素材特征(center / extent / safe-zones / avoid-zones)的反向测量(逆向工程步骤,靠视觉完成);色板从素材取色(绝不使用通用 #FFF/#000);分两层 —— 素材为 z0 全出血层 + 数据图形按 element_positions 融合在 z1+,connectors/scribble 把数据物理性地"缝"在素材上,素材始终保持可见。

七、Invariants:IR 的三条硬性不变量

IR 在末尾给出三条约束,它们是这份契约能跨智能体稳定传输的根基:

  1. scenes(若存在)必须将 [0, duration_s] 无缝隙、无重叠地分区 —— 时间轴完整覆盖镜头时长。
  2. asset_needs ⇒ Step 2(source)被跳过 —— 布尔式的流水线分支信号。
  3. 命名了 block ⇒ Builder 复用并定制该 block,而非手工创作 —— 「复用优先」的机器可读表达。

这三条分别锁定了时间轴完整性、素材阶段的条件执行、以及构建方式的默认路径。

八、IR 在整个流程中的两次写入与一次消费

理解 IR 的关键是它何时被写、何时被读

时点 动作 写入内容
Step 1(plan) Director Part 1 写入 DRAFT envelope + 所选表单类别 搜索意图 + asset_needs + 一段镜头 brief
Step 3(design) Director Part 2 写入 FINAL content.block + content.customize + per-category content(含 element_positions、取色板等)
Step 4(build) Builder 读取 按 IR 添加并定制 block,产出 compositions/index.html

8.1 IR 校验与防错

SKILL 中提供的基础校验命令是文件非空检查:

[ -s "$PROJECT_DIR/shot-plan.json" ] && echo ok || echo missing

渲染前的完整质量门是 HyperFrames 的 lint + inspect:

(cd "$PROJECT_DIR" && npx hyperframes lint . && npx hyperframes inspect .)

而构建阶段的产出(compositions/index.html)必须遵循 Builder 契约(builder-contract.md):根 #stage 必须设了尺寸(position:relative; width; height),CSS 先排布 hero-frame 终态再 gsap.from() 入场,时间线为唯一一条 paused:true 的 GSAP timeline 并注册到 window.__timelines["<id>"]、以 tl.seek(0) 收尾、绝不对渲染关键动效调用 tl.play(),全程确定性(无 Date.now()/Math.random()/网络)。

8.2 实际例子:news 类别的 IR 如何驱动 marker-band 动画

以搜索驱动类别 news 为例看 IR 的消费链路。Director 从真实文章中抽出 keyword(1–2 词/数字/人名,作为钩子),Layout B 还需要品牌 logo、日期与人物照片,写进 asset_needs: { kind: news|web|image, query }(logo 与人物照片作为独立素材查询从 Wikimedia/simple-icons 等来源请求);人物照片在 source 阶段经 hyperframes remove-background 得到透明 cutout。随后 Builder 按 news module 实现:

  • 关键词高亮用 marker band 通过 background-size 从左往右生长(而非 transform:scaleX 横条):
.hl {
  --hlw: 0%;
  background-image: linear-gradient(var(--hl), var(--hl));
  background-repeat: no-repeat;
  background-position: 0 72%;
  background-size: var(--hlw) 64%;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

box-decoration-break: clone 让高亮带可以跨行无缝包裹(多词关键词跨 2–3 行仍连续高亮,旧 scaleX 方案做不到);GSAP 把 CSS 变量 --hlw 从 0% 补间到 100%,且必须在文字落定之后才扫上,绝不能预先应用;高亮时长随关键词长度在 ~0.5–1.5s 间缩放。这正是 IR 中 keywordlayout 字段与动效实现之间的对应关系。

8.3 参考实现位置

仓库内为各搜索驱动类别提供了可运行的参考样本(samples/),可作为 IR 语义落地的具象参照:

  • .agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html
  • news 类别的 _ref-centered-emphasis.html_ref-article-layout.html(后者为真实文章 + 真实 outlet logo + 抠图人物 + 真实故事的完整布局演示)

九、写作 / 维护 IR 的实战要点

汇总各阶段规则,当 Director 要产出合规且高质量的 IR 时需注意:

  1. 先决策是否需要搜索,再落类别:form category(kinetic-type / stat / charts / logo-reveal / lower-thirds)内容由用户供给、asset_needs: [];search-driven category(webpage / news / tweet / asset-fusion)最终由搜索返回的内容类型确认。
  2. envelope 提前锁死:时长(3–30s)、fps(30)、canvas(默认 1080×1920 竖屏)、font 必须在 HF embed-list 内、export 决定渲染格式分支。
  3. 查询两极而非中间态asset_needs[].query 要么 1–3 词原子查询、要么 5–15 词具体查询;失败的查询丢弃而不放宽。
  4. block 是承诺:一旦命名 block,Builder 就走 add + customize 的复用路径;只有 catalog 空白与 asset-fusion affordance 才允许手写。
  5. content 按类别对号入座:每种形状的字段都有明确消费方 —— 例如 kinetic-type 的 scenes 分区决定时间轴、stat 的 ring 决定是否画圆环、news 的 layout 决定 9:16 纯文字还是 16:9 带人物 cutout。
  6. 写完后自查三条不变量scenes 是否无缝分区、asset_needs 空否决定 source 是否运行、命名 block 是否走复用。

结语

shot-plan.json 不是一份「文档」,而是运动图形流水线中结构与协议本身:它把创意决策(category、style、beats、brief)、素材需求(asset_needs)、构建指令(block + customize)与类别化内容(content)统一进一个文件,使 Director 的两段式设计与 Builder 的复用优先构建可以解耦协作。读懂这份 IR 的字段与不变量,也就读懂了 OpenMontage 设计驱动短片如何从一句需求稳定地产出可渲染、可验证、确定性的运动图形。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391