OpenMontage music-to-video 运动基元目录(motion-primitive catalog):面向节拍锚点的 free-compose 微动作速查与组合语法
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
导读
本文解析 OpenMontage 仓库中 music-to-video 技能的references/motion-primitive-catalog.md(运动基元目录)——它是技能体系里"原子动作层"的完整菜单。当某个帧内小组(group)没有现成模板可套用时,编排者(orchestrator)可以直接按"锚点 + 最佳时长 + 动作语义"三要素命名一组运动基元(primitive)来自由编排(free-compose)。读完本文你将掌握:46 个运动基元的全量清单与适用锚点、贯穿所有基元的时序与延迟铁律(0ms 硬击、提前 40–190ms 落地、300–500ms 缓动入场、800–2000ms 宏观构建等)、把基元组合成一个"一个主导系统 + 最多一层纹理"的构图语法,以及这些规则如何在仓库的 GSAP/HyperFrames 参考实现与 STORYBOARD 规划格式中落地。
一、运动基元在 music-to-video 工作流中的定位
music-to-video 技能(SKILL.md)是一个"一曲一视频"的节拍同步工作流:先由唯一的节拍分析器 analyze-beatgrid.py 生成audiomap.json,再切帧、写 STORYBOARD、逐帧派发子代理构图、最后装配渲染。每一帧(frame)内可再拆出多个小组(group),每个小组在 Step 3(planning)时只能选择三种处理方式之一:
- 匹配模板(template):从 template-catalog.md 中挑选整帧级成套方案;
- 自由编排(free-compose):从运动基元目录命名一组 L0 原子动作;
- 素材处理(asset):按 montage.md 处理用户提供的图片/视频。
运动基元目录正是第 2 种方式的"选菜单"。从目录结构看,它被明确标注为L0 目录实现(atomic layer),而模板目录则是建立在 L0 之上的 L1 成套实现:
原子层(atomic layer)的语义是:一个锚点 → 一个微动作(one anchor → one micro-move)。当没有模板能覆盖某个小组时,就通过命名这里的基元来做 free-compose——扫描每个基元的锚点 anchor+最佳时长 best span+动作效果 what it does,然后挑出能承载该小组的最小动作集合。
规划阶段的决策权划分是:编排者决定WHAT(选哪些模板/基元、写什么文案、绑到哪个真实音频锚点秒),frame-worker 子代理决定HOW(微时序、布局、命名空间等实现细节)。这一点在 planning.md 中写得很明确——storyboard 里绝不出现毫秒级 tween。因此这份目录是编排者唯一需要背诵的"动作词汇表"。
二、先看懂三个扫描维度
使用这份目录之前,需要理解每个基元行的三个列字段,它们是"扫描-挑选"协议:
| 字段 | 含义 | 读法 |
|---|---|---|
| id | 基元唯一标识,如hypercut-whip | 直接写进 free-compose 的primitives列表,如primitives: [hypercut-whip, content-swap] |
| anchor | 该动作应该骑乘(ride)的音频锚点类型 | 用audiomap.json里真实的 beat / onset / drop 秒数替代示例时刻 |
| best span | 动作活跃窗口的建议时长 | 不是"可以把一个基元抻满整帧"的许可证,而是"活跃运动"的窗口 |
目录中反复出现的锚点词汇,对应analyze-beatgrid.py产出的audiomap.json字段,含义对照如下:
- beat / downbeat:节拍网格中的击拍/强拍下拍;
beat_cut节奏型下才可信; - hard_stop:音乐骤停,是"锁死"类动作的首选落地锚点;
- drop / surge / crash / kick / snare:能量相位中的重音类锚点(DROP/SURGE 是
key_moments级别); - onset:瞬态起始点,带有
onset_rate密度信息; - roll / build:滚奏/渐强——天然的"累积容器";
- phrase / section_start / section change / reveal / transition / accent / texture / hold / energy / silence:乐句、段落切换、揭示点、重音、氛围停留等结构性锚点。
当某个锚点带有→箭头(如roll → downbeat、onsets → downbeat、roll → downbeat),表示该基元是一个"先累积、后在目标锚点上锁定/收束"的两段式动作。
三、通用时序与延迟铁律(适用于所有基元)
目录开头给出了一套所有基元都必须遵守的时序法则,这也是与"配乐背景跑马灯"最根本的区别——这里运动本身即是打击乐。共六条:
3.1 硬击点必须是 0ms:缓动会杀死它
Cuts、调色板翻转(palette flips)、内容交换(content swaps)、冻结(freezes)都通过tl.set(...)实现——没有时长、没有缓动。"打击乐就是动作本身",一旦给硬击加上缓动,它就失去了击打感。
仓库实现中,hard-cut 参考实现 就是这条规则的直译:它预构建 N 个全帧面板(背景色+词),然后仅用tl.set()在每拍处瞬时切换可见面板,注释里写得很直白——"Sample-accurate 0ms cuts … tl.set has no duration and no ease — brutal instant switching":
for (let i = 1; i < N; i++) { const t = i * STEP; // STEP = 0.28s,即一个 beat 间隔 tl.set("#p" + (i - 1), { opacity: 0 }, t); // 藏起上一块 tl.set("#p" + i, { opacity: 1 }, t); // 同帧秒显出下一块 }3.2 提前锚点、迟滞响应:40–190ms 提前落地,0–45ms 跟随响应
动作分为两类,时序方向相反:
- 落点型动作(必须在拍上"落地"的,如覆盖全帧的划像 wipe、卡住的计数、两块碰撞):提前约 40–190ms 启动,使其恰好在该锚点处完成,即"lead the anchor"(提前量带动动作落在拍上);
- 反应型入场(因击打而"出现"的元素):在锚点之后 0–45ms触发。
这个"早到/晚到"的二分法保证观众感知到的因果链是"动作打中节拍",而非"动作碰巧跟在节拍后"。
3.3 缓动入场 300–500ms,宏观构建 800–2000ms
动作时长分两档:
- 缓动入场(eased entrances):scale punch、滑动、镜头推进等,300–500ms;
- 宏观构建(macro builds):跨越整个 roll / 静默段的累积动作,800–2000ms。
参考实现中可观察到典型取值:如 kinetic-letter-in 使用duration: 0.55(约 550ms)+back.out(2)的每个字母入场、stagger: 0.045错峰,随后 0.6s 的字距展开——正是"缓动入场"档位;counting-punch 的计数主过程duration: 1.15则落在"宏观构建"档。
3.4 每小节配额(per-bar caps)
克制是配乐的常识,具体三条配额:
- 每个击打点只累积一个元素(是"累积"不是"爆发");
- 镜头运动每个乐句至多一次,绝不在每个拍上都动;
- 高密度翻转/strobe 系统连续运行不超过 2–3 秒。
3.5 张力构建必须锁死(tension-builds lock)
计数、顺序构建、形变等"张力型"基元必须在某个强拍(downbeat)或 hard_stop 上"解决/收束",绝不允许在小节中途拖尾散掉。这条规则与锚点列中大量roll → downbeat、roll → hard_stop的形态一一对应。
3.6 best span 指的是"活跃运动",不是拉伸许可证
目录给出的 span 指引不是允许把一个基元拉长覆盖整帧。若自由编排的小组实际时长超过了清单 span:
- 增加一个 hold(驻留)或 bed(衬底);
- 追加下一个基元;
- 或者在下个音乐锚点处把帧再切分出一个新小组。
四、全量目录:46 个运动基元
原目录共收录 46 个基元,下表完整保留其 id、锚点、最佳时长与效果描述(best span 中的 "in" 指入场,如0ms in表示该动作的入场是 0ms 硬切):
| id | anchor | best span | what it does |
|---|---|---|---|
hypercut-whip | beat / hard_stop | 0.18-0.45s | 帧与帧之间的快速 whip-pan 硬切 |
kinetic-letter-in | downbeat / phrase | 0.4-1.2s | 逐字母动能入场 |
braam-punch | drop / surge | 0.2-0.9s active | 大冲击:缩放 + 重量感砸击 |
chromatic-split | snare / glitch / surge | 0.1-0.6s | 在某个词上做 RGB 通道分裂 / glitch |
mask-reveal | section_start / downbeat | 0.5-1.2s | clip-path 蒙版划像揭示 |
screen-shake | drop / crash / kick | 0.1-0.5s | 镜头/屏幕抖动 jitter |
binary-decrypt | roll / build | 0.8-2.5s | 乱码→解码(二进制→单词) |
dolly-zoom | phrase / build | 1.2-2.5s | 眩晕感 dolly-zoom(缩放 vs 透视) |
iris-open | section_start / reveal | 0.6-1.2s | 圆形 iris 打开式揭示 |
electric-arc | accent / glitch | 0.1-0.6s | 电弧 / 闪电重音 |
neon-flicker | hold / texture | 0.5-2.5s | 霓虹灯招牌闪烁 |
chrome-sweep | downbeat / reveal | 0.6-1.4s | 金属高光扫过文字 |
slot-machine-reveal | roll → downbeat | 0.8-2.0s | 老虎机式滚动-落定字符揭示 |
liquid-morph | phrase / transition | 1.0-2.5s | 液态 / blob 形变 |
gooey-metaball | build / drop | 1.5-3.0s | gooey 融合球体场 |
3d-card-flip | downbeat / swap | 0.8-1.6s | 3D 卡片翻转(rotateY) |
crash-zoom-in | drop / surge | 0.2-0.8s | 猛烈 crash 推近 |
spotlight-sweep | reveal / hold | 0.8-2.0s | 聚光灯 / 渐变扫过文字 |
outline-to-fill | downbeat / reveal | 0.8-1.8s | 描边轮廓 → 实色填充 |
counting-punch | roll → downbeat | 1.0-2.5s | 数字计数并在落定时击打锁死 |
particle-burst | drop / crash | 0.2-1.2s | 粒子爆炸迸发 |
radial-burst-lines | drop / surge | 0.2-0.8s | 放射状速度线迸发 |
pixel-dissolve | transition / hard_stop | 0.5-1.5s | 像素化溶解 |
datamosh-smear | glitch / transition | 0.4-1.2s | datamosh / 运动涂抹 |
text-wave-distort | hold / texture | 1.0-2.5s | 波浪形文字扭曲 |
bg-flow-field | energy / whole span (bed) | 4-12s bed | 生成式 curl-noise 背景衬底;可在其上自由叠加任意前景动作 |
blur-resolve | stop / final hold | 0.7-2.0s | 模糊入→清晰聚焦,切出前再模糊出 |
chromatic-pressure | snare / glitch | 0.1-0.5s | 瞬态上的 RGB 分裂 / 数字张力 |
color-grid-shuffle | onset | 0ms hits; ≤2s run | 网格单元按每次 onset 的确定性索引重着色 |
content-swap | beat | 0ms hits; ≤3s run | 堆叠节点的 0ms 交换:最常用的打击乐式动作(workhorse percussive move) |
directional-fill | beat / reveal | 0.3-1.0s each | 方向性划像填充(scaleX)横扫各小节 |
flash-cut | drop / crash | 0-0.6s | 全帧闪光遮蔽词 / 颜色状态变化 |
freeze-hold | hard_stop | 0ms in; 0.5-2s | 冻结运动系统并驻留 |
hard-cut | beat / hard_stop | 0ms in; 0.3-2s | 采样级精确的色块 + 词硬切 |
mosaic-pack | beat / build | 1.5-3.5s | 散落瓷砖飞入并拼装成网格 |
negative-space-hold | silence / hard_stop / final hold | 1-6s hold | 杀掉拥挤图层,在留白中驻留一个可读标记 |
overlay-pop | accent | 0.2-0.6s in | 徽章 / 下三分之一条在基底上弹入 |
palette-flip | section change | 0ms flip; 0.5-4s | 同一布局通过 0ms 调色板变量翻转"换肤" |
staggered-exit | phrase / transition | 0.4-1.2s | 有序级联清场 |
staggered-reveal | build | 0.8-2.5s | 堆叠 / 列表的有序级联入场 |
system-replace | drop / regime change | 0ms cut | 整视觉系统硬切,然后启动新系统 |
text-spectral-rays | phrase / sweep (hero text) | 2.5-5s | 字标向扫动的光标投出体积光(唯一 hero 字标专属基元) |
tile-mosaic | build / reveal | 1.5-3.5s | 网格瓷砖对角扫亮、拼装成海报 |
typewriter-reveal | roll / build | 1.0-3.0s | 字符 / 词打字机式显字(带光标) |
value-counter | roll → downbeat | 1.0-2.5s | 在强拍 / hard_stop 上锁定的计数 |
word-grid-burst | onsets → downbeat | 1.8-3.2s | 词网格随 onset 逐个揭示,在强拍上聚焦一个词 |
五、快速检索:按"在乐曲中的角色"分组
全量表是权威清单,但为了在 Step 3 现场快速缩小候选范围,可以把 46 个基元按功能角色重新映射(编组仅为检索便利,不改变上表的权威定义):
结构性大动作(structure,骑强拍/段落边界,负责"布局与切换"):system-replace、hard-cut、hypercut-whip、palette-flip、content-swap、freeze-hold、mask-reveal、iris-open、pixel-dissolve、datamosh-smear、liquid-morph、3d-card-flip、staggered-exit、staggered-reveal、mosaic-pack、tile-mosaic、negative-space-hold。
打击/冲击类(percussive,0ms 或极短,制造"击打"):content-swap、hard-cut、flash-cut、color-grid-shuffle、chromatic-pressure、chromatic-split、screen-shake、crash-zoom-in、braam-punch、particle-burst、radial-burst-lines、overlay-pop、electric-arc、hypercut-whip。
累积-落定型(accumulate-and-lock,roll/build → downbeat/hard_stop两段式):binary-decrypt、slot-machine-reveal、counting-punch、value-counter、word-grid-burst、typewriter-reveal。
揭示/揭示性渐变(reveal,缓动入场档 300–500ms 起步):kinetic-letter-in、chrome-sweep、outline-to-fill、spotlight-sweep、directional-fill、blur-resolve、mask-reveal、iris-open。
氛围 / 纹理 / 背景(hold / texture / bed,长驻留):bg-flow-field(唯一的整帧 bed)、neon-flicker、text-wave-distort、gooey-metaball、text-spectral-rays(hero 字标专用)。
镜头类(camera):dolly-zoom、screen-shake、crash-zoom-in、hypercut-whip。
六、组合语法:free-compose 的构图规则
目录的 "How to combine" 一节定义了把多个基元叠成一个小组的组合语法。直接照抄其规则如下:
6.1 一个主导系统,最多一层纹理
每个小组只有一个主导系统(dominant system);最多只能在一层结构性基元之上叠一层纹理基元。参考实现的目录布局印证了这一分层:references/motion-primitives/<id>/index.html中的每个基元都是单文件自包含的 recipe,组合时由 frame-worker 把若干 recipe fork 进同一帧、分别命名空间化。
6.2 结构上强拍,纹理上弱拍
- 结构性动作放在强拍上:cut、镜头运动、
system-replace骑乘downbeat / phrase / section_start; - 纹理性动作放在弱拍/切分音上:
content-swap、打字机字符、chromatic 重音等。
6.3 roll 是累积容器
一个 roll(滚奏段)本质上是一个"累积容器":在 roll 期间持续构建,然后在结束它的那个强拍上硬切到干净布局。所以表里累积型基元的锚点几乎都是roll → downbeat形态。
6.4drop≠downbeat,这是两个层级
- downbeat:同一 regime(视觉体制)内部的一次切换;
- drop:一次 regime 切换(
system-replace、整体清空、元素数量级跳变)。
两者不混用,因为它们的构图代价完全不同。
6.5 让静默做减法
用negative-space-hold让静默移除密度——silence / hard_stop 时主动杀掉拥挤图层,只留一个可读标记在空场中,而不是让画面继续"填空"。
6.6 背景衬底是"图层"而不是"动作"
bg-flow-field这类 bed 属于图层而非动作:同一时刻只能有一个 bed,且永远放在前景基元之下("one bed at a time, under foreground primitives")。
6.7 hero 字标的排他性
text-spectral-rays是 hero 字标(主字标)的专属待遇:一旦使用它,就不要再在同一画面上叠加同一个词的另一个可见副本。
七、在代码层落地:参考实现与子代理契约
这份目录不是纸面清单——仓库在 references/motion-primitives/ 下为 46 个条目中的 37 个提供了可运行的 HTML 参考实现(如hypercut-whip/、bg-flow-field/、counting-punch/等各自是一个<id>/index.html),并共享一个 vendored 的 gsap.min.js。每个实现都是 1920×1080、注册window.__timelines["main"]暂停时间线的标准 HyperFrames 组合,可直接在浏览器打开预览。
以三个实现为例看时序规则如何在代码中兑现:
1)hard-cut/index.html —— 0ms 硬击预构建全帧面板数组(背景色/前景色/词三数组,WORDS = ["CUT","NOW","HARD","SNAP","STOP","GO","CUT"]),STEP = 0.28s即一个拍间隔。切换只发生在tl.set()上,tl.set无 duration、无 ease——对应 3.1 的"缓动杀死硬击"。帧尾还带"回卷"逻辑(把末面板切回首面板),保证循环重入时颜色与词与起点一致。
2)kinetic-letter-in/index.html —— 300–500ms 缓动入场把单词拆成<span class="char">,用tl.from(".char", { y: 80, opacity: 0, stagger: 0.045, ease: "back.out(2)", duration: 0.55 }, 0.05)逐字母弹入,再以power2.out做 0.6s 字距展开——时值落在目录给定的缓动入场档。
3)counting-punch/index.html —— 累积-落定-锁死用一个 tween 驱动计数器对象在duration: 1.15(expo.out)内滚到目标值12847,数字每变一帧触发一次 1.045 的微缩放 tick;在落定时刻(t=1.3s)先power4.out冲到 scale 1.12,再以elastic.out(1, 0.55)弹回 1.0,同时下划线expo.out画线、caption 淡入。整个"构建→落定 punch→弹性锁死"正是roll → downbeat锚点与"tension-builds lock"规则的一次完整演示。
frame-worker 的实际装配契约在 sub-agents/frame-worker.md 中定义:子代理拿到 storyboard 里该帧的free_design块后,把材料 fork 进本帧文件,把所有锚点换算为帧内本地时间(local_t = track_t − span_sec[0]),用一个暂停的gsap.timeline({paused:true})在window.__timelines["<frame_id>"]上同步注册,并用tl.set(group,{autoAlpha:1/0}, start/end)的 0ms 交换实现帧内 group→group 切点;frame-worker 不运行hyperframesCLI(那是装配后项目上 Step 6 的事)。另外目录里注明"GSAP 由宿主加载,帧文件不再自带<script>",但单个参考 recipe 为了独立预览仍自带 gsap 引用,fork 进帧文件时需要按 worker 契约删除该行。
八、STORYBOARD 中的实际写法
Step 3 规划时,free-compose 组在 storyboard 中写成free_design块。综合 planning.md 定义的字段,典型形态如下(字段格式示意,实际以该技能规划的 storyboard-format 为准):
### Groups - group: g1 free_design: dominant_system: hard-cut # 一个主导系统 primitives: [content-swap, chromatic-split] # 一层结构 + 一层纹理 density_topology: 2-region # 密度拓扑:如"双区域/单焦点/满帧" anchors: # audiomap.json 的真实秒数 - { beat: 12.30, role: hard-cut } - { onset: 12.86, role: content-swap } copy: ["CUT", "NOW", "HARD"]编排者只写"选了什么 + 内容 + 真实锚点秒 + 累积/错峰意图",微时序完全留给 frame-worker。完成后运行 validate-plan.mjs 校验:凡是硬错误(时长不匹配、帧未铺满音轨、缺少src)都会以✗报出并需清零,warning 则尽力而为。
九、组合时的常见误区对照
把前文的规则浓缩成一份快速自检清单,供 Step 3/4 时对照:
- 把硬击加了缓动→ 打击感消失。检查
content-swap、hard-cut、palette-flip、freeze-hold是否仍是 0ms。 - 让落点型动作在拍后才启动→ 永远感觉慢半拍。wipe、锁数值、碰撞类动作要提前 40–190ms。
- 一个基元拉满整帧→ span 是"活跃运动"窗口,超了就加 hold/bed/下个基元,或在下一锚点切帧。
- 每拍都推镜头→ 违反"镜头每乐句至多一次"。
- 张力构建在中途散掉→ counting/morph/顺序构建必须落在 downbeat 或 hard_stop 上。
- drop 和 downbeat 混为一谈→ downbeat 是体制内切换,drop 是 regime 级更换。
- 叠了两个 bed 或两套主导系统→ 每帧一个主导系统 + 至多一层纹理 + 至多一个 bed。
- 在
text-spectral-rays上再叠同词副本→ hero 字标排他。
十、小结
motion-primitive-catalog 是 music-to-video 技能"自由编排层"的动作语法书:46 个原子动作覆盖了从 0ms 打击乐式硬切(hard-cut、content-swap)到秒级宏观构建(binary-decrypt、value-counter、word-grid-burst)再到长驻留氛围层(bg-flow-field、negative-space-hold)的全部语义;而锚点列(beat / drop / roll→downbeat / hard_stop / silence…)让每个动作都能被绑定到audiomap.json的真实时间轴上。配合 37 份可运行参考实现、free_design规划格式与 frame-worker 的装配契约,编排者可以在"没有模板兜底"时依然用最小动作集合精确承载任意小组的画面意图——这正是这套"以音乐为主干"(music-grounded)工作流能在零素材前提下产出节拍级同步视频的关键设计。
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考