Communitygithub.com

syahdestiny/soundtrack

该技能用于当用户要求“为动画添加音乐”、“用代码创作音乐”、“合成配乐”、“为剪辑创作合适的背景音乐”、“让音乐与视频同步”、“检查音频是否与画面匹配”,或者“音乐太突然/吓人”。它涵盖基于代码合成、内置于动画页面中的乐谱(通过 Web Audio API,离线渲染为 WAV)、AI 生成或用户提供的音乐,以及一项自动检查功能,确保剪辑落在节拍上,且没有刺耳的音量突变。

soundtrack 是什么?

Soundtrack 技能是一个专门为动画电影生成和同步配乐的工具,主要面向希望用代码合成音乐而非依赖现有曲库的开发者。它通过 `window.SCORE` 函数利用 Web Audio API 在浏览器中实时合成音乐,并使用 `OfflineAudioContext` 离线渲染为 WAV 文件,随后通过 `render.mjs` 将其复用进 MP4 视频。核心功能包括一个“节拍图”系统,确保每个场景剪辑都落在强拍上,并通过和声变化(而非音量突增)来标记剪辑,避免惊吓效果。此外,它还包含一个 `sync-check` 脚本,用于检查音频与视频的同步性,检测节拍偏移(超过 100ms)和音量惊吓(超过 +6 dB)。该技能也支持 AI 生成的音乐(如通过 Lyria)或用户提供的音频轨道,并提供了相应的处理方式。其局限性在于,对于逼真的人声、管弦乐和复杂的音乐风格,推荐使用 AI 或真实音频轨道。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/syahdestiny/skill-motion-javascript/tree/HEAD/skills/soundtrack

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

soundtrack 是做什么的?

为这部影片谱写配乐

一部电影的配乐是为该电影量身定制的:它使用独立的乐器、节奏与和声,基于 Web Audio,从零开始编写在 window.SCORE = ac => { … } 中(振荡器、噪声、滤波器、包络、延迟:只要是乐曲需要的)。鼓点、律动或音乐盒基底都以同样的方式为这部影片编写:没有两部电影会因为共享模板而听起来相同。templates/groove.js 和 templates/score.js 是两个现成的乐谱,仅在用户要求时使用;每个文件都记录了其选项。

render.mjs(来自 javascript-animation 技能)使用 OfflineAudioContext 离线渲染 window.SCORE,写入 <out>.wav 并将其复用进 MP4;页面内的实时预览在点击时也会播放相同的乐谱。

不要预先让用户选择音乐源。在交付时,用一行提醒用户 AI 生成的音乐或他们自己的曲目同样有效。

音乐如何跟随画面

  • 节拍图。每个场景获得整数个小节(每个场景的速度可以灵活调整),这样每个剪辑都会落在强拍上。
  • 用和声而非音量标记剪辑。每个场景回归到属和弦,剪辑点落在主和弦上。在剪辑点上的强音(同时出现的贝斯和明亮的钟声)会被视为跳跃惊吓:用户反映 +7 到 +10 dB 的跳跃令人不适;+3 到 +5 dB 结合和弦变化则读作干净的剪辑。
  • 如果开场小节是第一个剪辑前的唯一小节,则不要使其稀疏;稀疏的前奏随后紧跟饱满的织体本身就是一种惊吓。
  • 不要在剪辑点的强拍上添加额外的重音。即使是正常的强拍重音(更响的贝斯加第一个音符)也会使短片段超过 +6 dB,因为前一拍正在衰减。和弦变化就足够了。
  • 场景内硬剪辑也要计数。同样将它们放入 window.CUES 中,以便获得相同的强拍。
  • 给眼睛一个可以抓住的参照。没有打击乐的连奏音乐没有可供剪辑落点的重音。有了稳定的律动,重音就成为节奏的一部分,不会造成惊吓(检查会与最近几秒的音量比较,而不是与一个孤立的安静时刻比较)。
  • 逐个或逐两个引入声部。在安静前奏后同时引入底鼓和贝斯测量到 +11 dB(惊吓);隔一小节引入,只有 +3.5 dB。
  • 使用间奏。在强拍前完全静音一个小节,是短视频中最有力的节拍。sync-check 接受将无声剪辑视为落在节拍上。

其他音源(仅在用户要求时使用)

  • AI 生成的音乐(例如通过 OpenRouter 的 Lyria):参见 references/ai-music.md。
  • 用户自己的音频轨道:使用 ffmpeg 将其复用。

对于无法控制的音乐,方向相反:画面跟随音乐。渲染、复用、运行检查,然后根据报告的偏移量移动页面 SCENES 表中的场景边界并重新渲染。这个过程代价很低,因为每个场景函数接收的是局部时间(从自身起点开始为 0),正如 starter 代码所写:移动边界永远不会触及场景代码。

总是要检查

node scripts/sync-check.mjs piece.mp4 --cues-file piece.cues.json   # 检查声明的 CUES(推荐)
node scripts/sync-check.mjs piece.mp4                       # 备用方案:检测画面中的剪辑(快速的摄像机运动可能被误判为剪辑)

对于每个事件,它会输出到最近强音频起点的偏移量以及进入该起点的音量跳变。如果出现 OFF-BEAT(超过 ±100 ms,约 3 帧)或 STARTLE(超过前 1 秒 +6 dB),则检查失败。开头一秒和最后淡出被跳过(没有“之前”片段可比较;淡出不是剪辑)。“强”意味着在 ±2 秒范围内的起点中显著,因此安静段落中的重音仍然有效;进入静音的剪辑算作落在节拍上;从间奏后返回的音乐与最近 4 秒的典型音量比较。没有音频流的视频会被相应报告。将所有剪辑点以及任何希望检查的场景内事件(镜头内部的硬剪辑、笑话的冲击点)放入 window.CUES 中。修正并重新运行直到通过,或直到每个剩余的 STARTLE 都是你能够命名的故意设计的标志性音效(喜剧冲击是为了突出;摇篮曲剪辑则不是)。

局限性

代码合成:音乐盒、类钢琴拨奏、铺垫、铃铛、柔和打击乐效果良好。逼真的人声、管弦乐和特定风格的音乐制作则不适合;请为这些场景使用 AI 音乐或真实音频轨道。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能