OpenMontage music-to-video 运动基元目录(motion-primitive catalog):面向节拍锚点的 free-compose 微动作速查与组合语法
2026/9/9 13:26:14 网站建设 项目流程

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)时只能选择三种处理方式之一:

  1. 匹配模板(template):从 template-catalog.md 中挑选整帧级成套方案;
  2. 自由编排(free-compose):从运动基元目录命名一组 L0 原子动作;
  3. 素材处理(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 → downbeatonsets → downbeatroll → 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 → downbeatroll → hard_stop的形态一一对应。

3.6 best span 指的是"活跃运动",不是拉伸许可证

目录给出的 span 指引不是允许把一个基元拉长覆盖整帧。若自由编排的小组实际时长超过了清单 span:

  • 增加一个 hold(驻留)或 bed(衬底);
  • 追加下一个基元;
  • 或者在下个音乐锚点处把帧再切分出一个新小组。

四、全量目录:46 个运动基元

原目录共收录 46 个基元,下表完整保留其 id、锚点、最佳时长与效果描述(best span 中的 "in" 指入场,如0ms in表示该动作的入场是 0ms 硬切):

idanchorbest spanwhat it does
hypercut-whipbeat / hard_stop0.18-0.45s帧与帧之间的快速 whip-pan 硬切
kinetic-letter-indownbeat / phrase0.4-1.2s逐字母动能入场
braam-punchdrop / surge0.2-0.9s active大冲击:缩放 + 重量感砸击
chromatic-splitsnare / glitch / surge0.1-0.6s在某个词上做 RGB 通道分裂 / glitch
mask-revealsection_start / downbeat0.5-1.2sclip-path 蒙版划像揭示
screen-shakedrop / crash / kick0.1-0.5s镜头/屏幕抖动 jitter
binary-decryptroll / build0.8-2.5s乱码→解码(二进制→单词)
dolly-zoomphrase / build1.2-2.5s眩晕感 dolly-zoom(缩放 vs 透视)
iris-opensection_start / reveal0.6-1.2s圆形 iris 打开式揭示
electric-arcaccent / glitch0.1-0.6s电弧 / 闪电重音
neon-flickerhold / texture0.5-2.5s霓虹灯招牌闪烁
chrome-sweepdownbeat / reveal0.6-1.4s金属高光扫过文字
slot-machine-revealroll → downbeat0.8-2.0s老虎机式滚动-落定字符揭示
liquid-morphphrase / transition1.0-2.5s液态 / blob 形变
gooey-metaballbuild / drop1.5-3.0sgooey 融合球体场
3d-card-flipdownbeat / swap0.8-1.6s3D 卡片翻转(rotateY)
crash-zoom-indrop / surge0.2-0.8s猛烈 crash 推近
spotlight-sweepreveal / hold0.8-2.0s聚光灯 / 渐变扫过文字
outline-to-filldownbeat / reveal0.8-1.8s描边轮廓 → 实色填充
counting-punchroll → downbeat1.0-2.5s数字计数并在落定时击打锁死
particle-burstdrop / crash0.2-1.2s粒子爆炸迸发
radial-burst-linesdrop / surge0.2-0.8s放射状速度线迸发
pixel-dissolvetransition / hard_stop0.5-1.5s像素化溶解
datamosh-smearglitch / transition0.4-1.2sdatamosh / 运动涂抹
text-wave-distorthold / texture1.0-2.5s波浪形文字扭曲
bg-flow-fieldenergy / whole span (bed)4-12s bed生成式 curl-noise 背景衬底;可在其上自由叠加任意前景动作
blur-resolvestop / final hold0.7-2.0s模糊入→清晰聚焦,切出前再模糊出
chromatic-pressuresnare / glitch0.1-0.5s瞬态上的 RGB 分裂 / 数字张力
color-grid-shuffleonset0ms hits; ≤2s run网格单元按每次 onset 的确定性索引重着色
content-swapbeat0ms hits; ≤3s run堆叠节点的 0ms 交换:最常用的打击乐式动作(workhorse percussive move)
directional-fillbeat / reveal0.3-1.0s each方向性划像填充(scaleX)横扫各小节
flash-cutdrop / crash0-0.6s全帧闪光遮蔽词 / 颜色状态变化
freeze-holdhard_stop0ms in; 0.5-2s冻结运动系统并驻留
hard-cutbeat / hard_stop0ms in; 0.3-2s采样级精确的色块 + 词硬切
mosaic-packbeat / build1.5-3.5s散落瓷砖飞入并拼装成网格
negative-space-holdsilence / hard_stop / final hold1-6s hold杀掉拥挤图层,在留白中驻留一个可读标记
overlay-popaccent0.2-0.6s in徽章 / 下三分之一条在基底上弹入
palette-flipsection change0ms flip; 0.5-4s同一布局通过 0ms 调色板变量翻转"换肤"
staggered-exitphrase / transition0.4-1.2s有序级联清场
staggered-revealbuild0.8-2.5s堆叠 / 列表的有序级联入场
system-replacedrop / regime change0ms cut整视觉系统硬切,然后启动新系统
text-spectral-raysphrase / sweep (hero text)2.5-5s字标向扫动的光标投出体积光(唯一 hero 字标专属基元)
tile-mosaicbuild / reveal1.5-3.5s网格瓷砖对角扫亮、拼装成海报
typewriter-revealroll / build1.0-3.0s字符 / 词打字机式显字(带光标)
value-counterroll → downbeat1.0-2.5s在强拍 / hard_stop 上锁定的计数
word-grid-burstonsets → downbeat1.8-3.2s词网格随 onset 逐个揭示,在强拍上聚焦一个词

五、快速检索:按"在乐曲中的角色"分组

全量表是权威清单,但为了在 Step 3 现场快速缩小候选范围,可以把 46 个基元按功能角色重新映射(编组仅为检索便利,不改变上表的权威定义):

结构性大动作(structure,骑强拍/段落边界,负责"布局与切换")system-replacehard-cuthypercut-whippalette-flipcontent-swapfreeze-holdmask-revealiris-openpixel-dissolvedatamosh-smearliquid-morph3d-card-flipstaggered-exitstaggered-revealmosaic-packtile-mosaicnegative-space-hold

打击/冲击类(percussive,0ms 或极短,制造"击打")content-swaphard-cutflash-cutcolor-grid-shufflechromatic-pressurechromatic-splitscreen-shakecrash-zoom-inbraam-punchparticle-burstradial-burst-linesoverlay-popelectric-archypercut-whip

累积-落定型(accumulate-and-lock,roll/build → downbeat/hard_stop两段式)binary-decryptslot-machine-revealcounting-punchvalue-counterword-grid-bursttypewriter-reveal

揭示/揭示性渐变(reveal,缓动入场档 300–500ms 起步)kinetic-letter-inchrome-sweepoutline-to-fillspotlight-sweepdirectional-fillblur-resolvemask-revealiris-open

氛围 / 纹理 / 背景(hold / texture / bed,长驻留)bg-flow-field(唯一的整帧 bed)、neon-flickertext-wave-distortgooey-metaballtext-spectral-rays(hero 字标专用)。

镜头类(camera)dolly-zoomscreen-shakecrash-zoom-inhypercut-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.4dropdownbeat,这是两个层级

  • 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.15expo.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 时对照:

  1. 把硬击加了缓动→ 打击感消失。检查content-swaphard-cutpalette-flipfreeze-hold是否仍是 0ms。
  2. 让落点型动作在拍后才启动→ 永远感觉慢半拍。wipe、锁数值、碰撞类动作要提前 40–190ms。
  3. 一个基元拉满整帧→ span 是"活跃运动"窗口,超了就加 hold/bed/下个基元,或在下一锚点切帧。
  4. 每拍都推镜头→ 违反"镜头每乐句至多一次"。
  5. 张力构建在中途散掉→ counting/morph/顺序构建必须落在 downbeat 或 hard_stop 上。
  6. drop 和 downbeat 混为一谈→ downbeat 是体制内切换,drop 是 regime 级更换。
  7. 叠了两个 bed 或两套主导系统→ 每帧一个主导系统 + 至多一层纹理 + 至多一个 bed。
  8. text-spectral-rays上再叠同词副本→ hero 字标排他。

十、小结

motion-primitive-catalog 是 music-to-video 技能"自由编排层"的动作语法书:46 个原子动作覆盖了从 0ms 打击乐式硬切(hard-cutcontent-swap)到秒级宏观构建(binary-decryptvalue-counterword-grid-burst)再到长驻留氛围层(bg-flow-fieldnegative-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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询