Communitygithub.com

声音与音乐同步

像专业剪辑师一样为视频配乐:将剪辑与音乐节拍对齐,在转场处放置音效,为旁白留出呼吸空间,安全使用免版税音乐,并让音乐在旁白下方自适应降低音量。在需要为视频添加音乐、音效或旁白时使用。

声音与音乐同步 是什么?

该技能是一个全面的音频后期制作指南,专注于视频声音设计中的关键环节:节拍同步、音效放置、旁白节奏和混音平衡。它明确将创意决策与执行分离——用户(或AI)做出创造性决定(如哪些节拍用于硬切、音效峰值在哪一帧、旁白从哪开始到哪结束),然后将具体数值(节拍帧、音效时间戳、音量降低水平)传递给 `remotion-compose` 和 `remotion-render` 进行实际渲染。技能提供了一个结构化工作流,包含6个步骤:选择音乐并锁定BPM、构建节拍网格、在转场处放置音效、调整旁白节奏、混音(降低音乐音量)和最终检查。还附带了两个实用的Node.js脚本:`beat_grid.js` 用于将BPM和fps转换为节拍帧编号,`mix_levels.js` 用于计算降低音量后的音乐水平和每段旁白的帧范围。此外,还包括一个音频提示表单模板,用于将所有决策记录下来,方便传递给 `remotion-compose`。最后,技能还提供了一个 `references/royalty-free-sourcing` 部分,列出了免版税音乐来源及其授权注意事项。该技能适用于Claude Code、Cursor等AI代理,与视频故事板、动态设计原则、动态排版、产品演示指导和社交视频格式化工具协同工作,用于制作专业水准的视频内容。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SkillMedev/tutorial-video-studio/tree/main/skills/sound-and-music-sync

在你喜欢的 AI 中提问

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

文档

声音与音乐同步 是做什么的?

声音是视频的一半,却经常被遗忘。一段普通的动画,如果与节拍同步剪辑且旁白清晰,看起来会很专业;而一段精美的动画,如果剪辑节奏不准、旁白被音乐淹没,看起来就会很业余。这就是音频品味层。你来决定剪辑落在哪里、音效在哪里突出、旁白如何呼吸以及混音如何平衡——然后将具体数值(节拍帧、音效时间戳、音量降低水平)传递给 remotion-compose 以加载到时间线上,以及 remotion-render 以导出。你不需要编写 <Audio> 的 JSX 或运行渲染器;你只需做出创意决策,然后交给它们处理。

该技能与运动视频导演包中的其他技能配合使用:video-storyboard 的场景列表和 motion-design-principles 的时间决策是你的输入——你需要根据已有的节拍进行配乐。如果文本根据音频动态显示,请与 kinetic-typography 同步;如果剪辑节奏服务于产品演示,请与 product-demo-director 协调;如果要剪辑垂直/社交版本,请使用 social-video-formatter 重新计算每个平台的节拍。音频混音是一个独立的层——将视觉外观(色彩校正、灯光、对比度)交给 motion-color-and-light,然后在其基础上进行配乐。

工作流

按顺序执行这些步骤。不要在剪辑与节拍锁定之前放置音效,也不要在旁白时间确定之前最终确定混音——每一步都依赖前一步。

  1. 选择音乐并锁定节奏。 选择与视频能量和长度匹配的音乐,确认其授权(参见 references/royalty-free-sourcing),并获取其 BPM。大多数免版税音乐库都会列出 BPM;如果没有,可以手动敲击或用节拍检测器计算。BPM 是所有后续工作的基础——一个节拍持续 60 / BPM 秒,在项目帧率下就是 fps * 60 / BPM 帧。

  2. 构建节拍网格并将剪辑对齐到节拍。 将节拍转换为帧编号,并将每个硬切和主要场景变化放在一个节拍上(运行下面的 beat_grid.js)。在强拍上切割——4/4拍中的第1、5、9拍——以强调重点;在任何节拍上切割以进行常规转场。如果剪辑距离节拍有两三帧的偏差,即使观众无法说出原因,也会感觉“不对”。将对齐后的帧列表作为 <Sequence from={...}> 的边界传递给 remotion-compose。

  3. 在转场处放置音效,而不是在转场之上。 音效用于让运动感觉真实。规则:音效的峰值应该与运动的峰值同时出现。呼啸声 引入 滑动效果(在切割前约 3-5 帧开始,使其尾部落在切割上);撞击声/重击声落在一张卡片“啪”地弹出的 那一帧 上;点击声/爆裂声落在 UI 元素出现的帧上;渐强音在揭示效果前的 10-20 帧内 构建,并在揭示时解决。每个转场使用一个音效——将它们叠加在一起会把点缀变成噪音。参见 references/sfx-placement。

  4. 调整旁白节奏,使其有呼吸感。 旁白决定了视频的真正节奏;视觉效果服务于旁白,而不是相反。目标是对话式的约 150 词/分钟(≈2.5 词/秒)——太快会显得匆忙,太慢则像人质视频。在关键台词前和行动号召(CTA)后留出 8-15 帧的静音节拍。为耳朵写作:短句,一个想法一句,使用缩略词。永远不要让场景在单词中间切割——将场景边界对齐到句子 之间 的间隙。先确定旁白的时间,然后拉伸或压缩场景持续时间以匹配旁白(这将成为 remotion-compose 使用的 durationInFrames)。

  5. 混音:降低音乐音量,使旁白突出。 这是最常见的音频失败。音乐和全音量的旁白在相同的频率范围内竞争,导致词语丢失。每当旁白 说话时,将音乐降低到其水平的约 25-35%,然后在间隙中恢复。运行 mix_levels.js 以获取具体的电平和时间数值。旁白目标为 -3 到 -6 dB(清晰,从不削波),降低后的音乐目标为 -18 到 -22 dB。将降低音量包络(哪些帧需要降低音量,下限水平)传递给 remotion-compose,后者通过每个 <Audio> 的 volume 回调来应用。

  6. 抽查导出结果。 在 remotion-render 生成 MP4 后,在笔记本电脑扬声器和手机扬声器上收听,而不仅仅是好的耳机——大多数观众使用的是劣质扬声器。确认:旁白的每个单词在音乐中都清晰可辨,没有音效削波或吓人一跳,剪辑感觉与节拍锁定,最响亮的时刻不产生失真。如果某个单词听不清,在该时间范围内更大幅度地降低音乐;如果音效吓人,将其降低 6 dB。

质量标准

只有满足以下所有条件,音频才算 A+ 级别:

  • 每个硬切都落在网格的节拍帧上——没有在节拍之间漂浮。
  • 每个转场音效的峰值正好在运动峰值的帧上;渐强音在揭示时解决,而不是之前或之后。
  • 旁白速率约为 140-160 wpm,在关键台词前和 CTA 后留出有意的静音;场景不在单词中间切割。
  • 在手机扬声器上,旁白在音乐中完全可懂——已验证,而非假设——因为音乐在语音下方降低到约 30%。
  • 每个转场恰好有一个音效;音乐循环或干净结束,在最后一帧没有突然中断。
  • 每个音频资产的许可证允许预期的用途(商业/付费广告/客户工作),并且已记录归属要求。

不要

  • 不要为了保留场景的“自然”长度而让剪辑偏离节拍——而是将场景拉伸或修剪到最近的节拍。
  • 不要在旁白下方以全音量运行音乐;未降低音量的音乐是旁白听起来模糊的原因。每次有人在说话时都要降低音量。
  • 不要在一个转场上叠加多个音效,或每次切割都使用相同的呼啸声——让它们变化,否则耳朵会忽略它们。
  • 不要在此处编写 <Audio> 的 JSX、设置 startFrom/volume 回调或调用渲染器——产生数值并交给 remotion-compose / remotion-render 处理。
  • 不要从 YouTube 下载、没有明确许可的“免费”网站或客户的 Spotify 获取音轨——商业用途需要真正的免版税或有授权来源。
  • 不要将整个混音标准化到尽可能大音量;留出余量,以便最响亮的撞击不会削波。
  • 不要让旁白为了适应固定时长而赶时间——重新剪辑画面以适应旁白,而不是让旁白适应画面。

计算器:节拍网格

自包含的 Node 脚本。保存为 beat_grid.js 并使用 node beat_grid.js 运行。它将 BPM 和 fps 转换为你的剪辑应落在的精确帧编号,并标记强拍。无依赖项。将打印的帧作为 <Sequence from={...}> 边界传递给 remotion-compose。

// 节拍网格。编辑输入,然后执行:node beat_grid.js
const input = {
  bpm: 120,            // 所选音乐的节奏
  fps: 30,             // 项目帧率
  durationSeconds: 12, // 视频时长
  beatsPerBar: 4,      // 4/4 拍;每 4 拍为一个强拍
}

const framesPerBeat = (input.fps * 60) / input.bpm
const totalFrames = Math.round(input.durationSeconds * input.fps)
const beats = []
for (let b = 0; ; b++) {
  const frame = Math.round(b * framesPerBeat)
  if (frame > totalFrames) break
  beats.push({ beat: b + 1, frame, downbeat: b % input.beatsPerBar === 0 })
}

console.log('每节拍帧数:', framesPerBeat.toFixed(2), '(' + (60 / input.bpm).toFixed(3) + 's each)')
console.log('在这些帧上切割(* 表示强拍,最适合硬切):')
for (const b of beats) {
  console.log('  beat ' + String(b.beat).padStart(2), '-> frame', String(b.frame).padStart(4), b.downbeat ? '*' : '')
}
console.log('仅强拍帧:', beats.filter((b) => b.downbeat).map((b) => b.frame).join(', '))

工作示例输出

使用上述输入,脚本会打印:

每节拍帧数: 15.00 (0.500s each)
在这些帧上切割(* 表示强拍,最适合硬切):
  beat  1 -> frame    0 *
  beat  2 -> frame   15 
  beat  3 -> frame   30 
  beat  4 -> frame   45 
  beat  5 -> frame   60 *
  beat  6 -> frame   75 
  beat  7 -> frame   90 
  beat  8 -> frame  105 
  beat  9 -> frame  120 *
  ...
仅强拍帧: 0, 60, 120, 180, 240, 300, 360

解释:在 120 BPM 和 30 fps 下,一个节拍恰好是 15 帧。将常规转场放在任何列出的帧上,将最硬的切割——如开头到内容的切割、CTA 揭示——放在强拍上(0, 60, 120…)。如果某个场景想运行 70 帧,将其对齐到 75 帧(节拍 6),而不是让切割漂浮在 70 帧。这些对齐后的数字正是 remotion-compose 放入 <Sequence from={...}> 的内容。

计算器:混音电平和降低音量时机

自包含的 Node 脚本。保存为 mix_levels.js 并使用 node mix_levels.js 运行。它计算降低后的音乐水平以及每段旁白的帧范围,以便你给 remotion-compose 一个具体的包络,而不是一个模糊的感觉。无依赖项。

// 混音和降低音量规划器。编辑输入,然后执行:node mix_levels.js
const input = {
  fps: 30,
  musicVolume: 0.8,       // 无人说话时音乐音量(0-1)
  duckToPercent: 0.30,    // 旁白下方音乐降低到此比例的原始音量
  voVolume: 1.0,          // 旁白音量(保持旁白为最响元素)
  duckFadeFrames: 8,      // 淡入/淡出帧数,使降低不是硬跳变
  // 旁白句子为 [开始秒数, 结束秒数];在这些时间段内降低音乐,并添加淡变边距
  voLines: [
    [0.5, 3.2],
    [4.0, 7.5],
    [8.2, 11.0],
  ],
}

const duckedLevel = +(input.musicVolume * input.duckToPercent).toFixed(3)
const toFrame = (s) => Math.round(s * input.fps)
// 参考粗略 dB:20*log10(level)
const dB = (v) => (v <= 0 ? '-inf' : (20 * Math.log10(v)).toFixed(1) + ' dB')

console.log('旁白音量:           ', input.voVolume, '(' + dB(input.voVolume) + ')  <- loudest element')
console.log('音乐(无人说话时):  ', input.musicVolume, '(' + dB(input.musicVolume) + ')')
console.log('旁白下方音乐降低至:', duckedLevel, '(' + dB(duckedLevel) + ')')
console.log('降低淡变:          ', input.duckFadeFrames, 'frames in/out')
console.log('在这些帧范围降低音乐(每侧添加 ' + input.duckFadeFrames + 'f 用于淡变):')
for (const [start, end] of input.voLines) {
  const a = toFrame(start) - input.duckFadeFrames
  const b = toFrame(end) + input.duckFadeFrames
  console.log('  VO ' + start + 's-' + end + 's  -> duck frames', Math.max(0, a), 'to', b)
}

工作示例输出

旁白音量:            1 (0.0 dB)  <- loudest element
音乐(无人说话时):   0.8 (-1.9 dB)
旁白下方音乐降低至: 0.24 (-12.4 dB)
降低淡变:           8 frames in/out
在这些帧范围降低音乐(每侧添加 8f 用于淡变):
  VO 0.5s-3.2s  -> duck frames 7 to 104
  VO 4s-7.5s    -> duck frames 112 to 233
  VO 8.2s-11s   -> duck frames 238 to 338

解释:旁白保持全音量(混音中最响的元素),音乐在间隙中运行在 0.8,在有人说话时降低到 0.24——大约三分之一——并在 8 帧内淡变,使下降不是刺耳的跳变。帧范围正是 remotion-compose 传递给音乐 <Audio> 的 volume 回调的范围:在范围外全音量,在范围内为 duckedLevel,并在淡变边距内线性渐变。这就是为什么单词保持清晰而音乐不会消失的原因。

模板:音频提示表单

复制此表单,用你的节拍网格和混音电平输出填充 FILL 字段,并将完成的表单交给 remotion-compose。这是视频中每个音频决策的唯一真实来源。

音频提示表。 [FILL: 视频名称]。fps [FILL] / [FILL] BPM / [FILL]s 总时长

音乐
  音轨:                 [FILL: 标题 + 来源]
  许可证:               [FILL: 例如 Epidemic Sound 商业 / CC0] - 归属要求: [FILL: 是/否, 文字]
  音量(无人说话时):   [FILL: 0-1]    旁白下方降低至: [FILL: 0-1] (~30%)

节拍网格(来自 beat_grid.js)- 剪辑落在此处
  强拍帧:               [FILL: 0, 60, 120, ...]
  硬切位置:            [FILL: 哪些强拍承载主要切割]

音效(每个转场一个;峰值在运动峰值的帧上)
  帧      音效            角色
  [FILL]   [FILL whoosh]  引入滑动效果(提前约 4f 开始,尾部落在切割上)
  [FILL]   [FILL impact]  卡片“啪”地弹出,落在切割帧上
  [FILL]   [FILL riser]   在 10-20f 内构建,在揭示时解决
  [FILL]   [FILL pop]     UI 元素出现

旁白(约 150 wpm;场景适应旁白,而不是相反)
  行                                      开始    结束    场景
  [FILL line]                            [FILL]  [FILL]  [FILL]
  (关键行前 / CTA 后静音 8-15f)

降低音量包络(来自 mix_levels.js)- 降低音乐的帧范围
  [FILL: 7-104, 112-233, ...]  淡变 [FILL]f 入/出

交接:remotion-compose 连接 <Audio> + 音量回调;remotion-render 导出。

references/royalty-free-sourcing

商业视频需要你实际获得授权使用的音乐——“我在 YouTube 上找到的”不是授权,客户的 Spotify 也不是。根据使用场景分类的授权/免版税来源:

  • 订阅库(对客户/商业/广告最安全): Epidemic Sound, Artlist, Musicbed, Soundstripe。固定费用,广泛的商业授权,大型音效库,无逐视频归属要求。付费工作的默认选择。
  • 免费但有条件(检查每个音轨): YouTube Audio Library(免费,某些音轨需要归属),Pixabay Music 和 Mixkit(免费,可用于商业用途,无需归属),Free Music Archive 和 ccMixter(知识共享——阅读具体的 CC 许可证,某些禁止商业用途或要求归属)。
  • 专门的音效: Pixabay 和 Mixkit(免费),Epidemic/Artlist(捆绑在订阅中),freesound.org(知识共享——验证每个剪辑的许可证)。

许可证卫生惯例,始终:确认许可证涵盖你的确切用途(个人 vs. 商业 vs. 付费广告,这通常是一个单独的层级);在提示表中记录任何所需的归属文字;保留许可证/下载的证明。CC0 和公共领域是唯一“在任何地方自由使用”的情况——其他一切都有条款。如有疑问,付费订阅库比下架或被索赔更便宜。

参考资料

...

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

Captions From Transcript

Produce an accurate, properly timed caption track (SRT or WebVTT) from a video

Kinetic Typography

Put text in motion the right way - title cards, animated captions, lower-thirds, callouts, and word-by-word reveals - with a reading-time-per-word budget so copy holds long enough to read, plus enter/exit timing, weight and size transitions, and type hierarchy in motion. Use when someone asks to

Motion Design Principles

The craft layer for motion: pick the right easing (ease-in / ease-out / ease-in-out / spring), get timing and spacing right, build the anticipation→action→follow-through arc, and apply Disney

Narration Script

Write the spoken voiceover for a tutorial or demo - the actual words, phrased for the ear and synced one-instruction-per-action to what is on screen, with a pacing budget and a confident, jargon-checked tone. Use when someone says

Product Demo Director

Direct the craft of putting a real software UI on screen - cursor choreography, zoom/pan/callout language, screen-recording vs recreated-UI, and making state changes legible with highlights, focus pulls, and slow-downs. Use when filming or recreating an app for a product demo, feature walkthrough, onboarding clip, or release reel and asking

Remotion Compose

Turns a natural-language video brief into a complete, ready-to-preview Remotion composition - extracts duration, scenes, brand colors, aspect ratio, and real copy; plans the frame budget; and writes data-driven React/TypeScript using useCurrentFrame, interpolate, spring, AbsoluteFill, and Sequence, registered in Root.tsx. Use when someone says

Remotion Render

Renders a Remotion composition to MP4 and runs the edit-and-re-render loop - CLI render commands, 1080p/4K/9:16 presets, concurrency tuning, codec selection, batch variants from a JSON data file, and Lambda for cloud rendering. Use when someone says

Remotion Setup

Scaffolds a new Remotion video project wired for Claude Code Agent Skills - Node check, create-video scaffold, skills install, folder conventions, Google Fonts, and a smoke-test render. Use whenever someone wants to start making videos with Remotion and Claude, even just

Screencast Capture

Capture clean raw screen and camera footage for a tutorial or product demo - choosing the recorder (macOS Screenshot toolbar, QuickTime, OBS, Windows Game Bar), setting resolution / frame-rate / cursor / microphone, prepping a distraction-free stage, and recording in retakeable segments. Use when someone says

SkillMedev/tutorial-video-studio

Plan a product demo, feature announcement, or launch video as a beat sheet and shot list BEFORE animating - hook in the first 3s, problem, reveal, proof, CTA - with target duration and pacing per scene type, output as a JSON scene plan that remotion-compose consumes directly. Use when someone says

Social Video Formatter

Reframe and export a finished video for social platforms - 9:16 ↔ 16:9 cropping, burned-in captions, a platform-native first frame, loop design, and per-platform specs (aspect, length, safe areas) for TikTok, Reels, Shorts, X, and LinkedIn. Use when someone says

相关技能