사운드 및 음악 싱크은(는) 무엇을 하나요?
사운드는 비디오의 절반이며 사람들이 잊는 절반입니다. 비트에 맞춰 컷한 평범한 애니메이션에 깔끔한 보이스오버가 있으면 전문적으로 읽히지만, 컷이 떠다니고 VO가 음악에 묻힌 아름다운 애니메이션은 아마추어처럼 읽힙니다. 이것이 오디오 취향 레이어입니다. 컷이 어디에 떨어질지, 사운드 효과가 어디를 강조할지, 보이스오버가 어떻게 숨을 쉴지, 믹스가 어떻게 배치될지를 결정한 다음, 구체적인 숫자(비트 프레임, SFX 타임스탬프, 덕 레벨)를 remotion-compose에 넘겨 타임라인에 배선하고 remotion-render에 넘겨 내보냅니다. <Audio> JSX를 작성하거나 렌더러를 실행하지 않습니다. 그들을 공급하는 창의적인 결정을 내립니다.
이것은 motion-video-direction 팩의 나머지와 짝을 이룹니다: video-storyboard 장면 목록과 motion-design-principles 타이밍 결정이 입력입니다 - 이미 존재하는 비트에 맞춰 스코어링합니다. 텍스트가 오디오에 맞춰 애니메이션되면 kinetic-typography와 동기화하고, 컷 리듬이 제품 워크스루를 전달하면 product-demo-director와 조정하며, 세로/소셜 버전을 편집하면 social-video-formatter로 플랫폼별 비트를 다시 도출합니다. 오디오 믹스는 자체 레이어입니다 - 시각적 모양(색 그레이딩, 조명, 대비)은 motion-color-and-light에 맡기고 그것이 그레이딩하는 대로 스코어링합니다.
워크플로우
순서대로 실행하세요. 컷이 비트에 고정되기 전에 SFX를 배치하지 말고, VO 타이밍이 맞기 전에 믹스를 확정하지 마세요 - 각 단계는 이전 단계에 의존합니다.
-
트랙을 선택하고 템포를 고정하세요. 비디오의 에너지와 길이에 맞는 음악을 선택하고, 라이선스를 확인한 다음(참조/로열티-프리-소싱 참조), BPM을 구하세요. 대부분의 로열티 프리 라이브러리는 BPM을 나열합니다. 그렇지 않으면 탭하거나 감지기를 사용하세요. BPM은 모든 다운스트림의 중추입니다 - 하나의 비트는
60 / BPM초 동안 지속되며, 프로젝트 fps에서fps * 60 / BPM프레임입니다. -
비트 그리드를 구축하고 컷을 스냅하세요. 비트를 프레임 번호로 변환하고 모든 하드 컷과 주요 장면 변경을 비트에 배치합니다(아래
beat_grid.js실행). 강조를 위해 다운비트(4/4 박자에서 1, 5, 9박)에서 컷하고, 일상적인 전환을 위해 모든 비트에서 컷합니다. 비트에서 2~3프레임 떨어진 컷은 이유를 설명할 수 없는 시청자에게도 "잘못된" 것으로 읽힙니다. 스냅된 프레임 목록을<Sequence from={...}>경계로 remotion-compose에 전달하세요. -
전환부에 사운드 효과를 배치하고, 그 위에 배치하지 마세요. SFX는 모션을 물리적으로 느끼게 하기 위해 존재합니다. 규칙: 사운드는 모션이 피크에 도달하는 순간에 피크에 도달합니다. 후샤는 스와이프로 리드 인합니다(컷보다 약 3
5프레임 일찍 시작하여 꼬리가 컷에 떨어지도록); 임팩트/둔탁한 소리는 카드가 꽂히는 프레임 에 떨어집니다; 클릭/팝은 UI 요소가 나타나는 프레임에 떨어집니다; 라이저는 공개 전 1020프레임에 걸쳐 쌓이고 그 위에서 해결됩니다. 전환당 하나의 SFX - 쌓으면 구두점이 소음으로 바뀝니다. 참조/sfx-배치를 참조하세요. -
보이스오버에 숨 쉴 공간을 주세요. VO는 비디오의 실제 속도를 설정합니다. 비주얼은 VO를 제공하고, 그 반대는 아닙니다. 대화식으로 분당 약 150단어(≈초당 2.5단어)를 목표로 하세요 - 더 빠르면 서두르는 것으로, 더 느리면 인질 비디오로 읽힙니다. 핵심 문장 전과 CTA 후에 비트의 침묵(8~15프레임)을 남겨두세요. 귀를 위해 쓰세요: 짧은 문장, 각각 하나의 아이디어, 축약형. 장면 컷이 단어 중간에 떨어지지 않게 하세요 - 장면 경계를 문장 사이의 간격에 맞추세요. VO를 먼저 시간을 재고, 그런 다음 장면 지속 시간을 늘리거나 줄여서 맞추세요(이것이 remotion-compose가 사용하는
durationInFrames가 됩니다). -
믹스: VO가 위에 앉도록 음악을 덕킹하세요. 이것은 가장 흔한 오디오 실패입니다. 음악과 전체 볼륨의 VO는 동일한 주파수 범위에서 경쟁하며 단어가 손실됩니다. VO가 말할 때마다 음악을 레벨의 약 25
35%로 덕킹한 다음, 간격에서 다시 올리세요. 구체적인 레벨 및 타이밍 번호는-6 dB(선명하고, 클리핑되지 않음), 덕킹된 음악을 약 -18~-22 dB로 목표로 하세요. 덕 엔벨로프(덕킹할 프레임, 바닥 레벨)를 remotion-compose에 전달하면, per-mix_levels.js를 실행하세요. VO를 약 -3<Audio>volume콜백을 통해 적용됩니다. -
내보내기를 스팟 체크하세요. remotion-render가 MP4를 생성한 후, 좋은 헤드폰뿐만 아니라 노트북 스피커와 휴대폰 스피커로 들어보세요 - 대부분의 시청자는 나쁜 스피커를 사용합니다. 확인: VO의 모든 단어가 음악 위에서 알아들을 수 있고, SFX가 클리핑되거나 놀라게 하지 않으며, 컷이 비트에 고정된 느낌이고, 가장 큰 순간이 왜곡되지 않습니다. 단어가 손실되면 해당 범위에서 더 깊게 덕킹하고, SFX가 놀라게 하면 6dB 낮추세요.
품질 기준
오디오는 다음 모든 사항이 충족될 때만 A+입니다:
- 모든 하드 컷이 그리드의 비트 프레임에 떨어집니다 - 비트 사이에 떠 있지 않습니다.
- 모든 전환 SFX가 모션이 피크에 도달하는 정확한 프레임에서 피크에 도달합니다; 라이저는 공개 시점에 해결되며, 그 전후가 아닙니다.
- VO가 분당 약 140~160단어로 실행되며 핵심 문장 전과 CTA 후에 의도적인 침묵이 있습니다; 단어 중간에 장면 컷이 없습니다.
- VO가 휴대폰 스피커에서 음악 위에서 완전히 알아들을 수 있습니다 - 가정이 아닌 확인됨 - 음악이 음성 아래에서 약 30%로 덕킹되기 때문입니다.
- 전환당 정확히 하나의 SFX; 트랙이 루프되거나 마지막 프레임에서 갑작스러운 차단 없이 깔끔하게 종료됩니다.
- 모든 오디오 에셋의 라이선스가 의도된 사용(상업적/유료 광고/클라이언트 작업)을 허용하고 저작자 표시 요구 사항이 기록됩니다.
하지 말아야 할 것
- 장면의 "자연스러운" 길이를 유지하기 위해 컷이 비트에서 떠다니게 두지 마세요 - 대신 장면을 가장 가까운 비트로 늘리거나 줄이세요.
- 보이스오버 아래에서 음악을 전체 레벨로 재생하지 마세요; 덕킹되지 않은 음악은 VO가 탁해 보이는 이유입니다. 누군가 말할 때마다 덕킹하세요.
- 하나의 전환에 여러 SFX를 쌓거나 모든 컷에 동일한 후샤를 재사용하지 마세요 - 다양하게 하지 않으면 귀가 듣기를 멈춥니다.
- 여기서
<Audio>JSX를 작성하거나startFrom/volume콜백을 설정하거나 렌더러를 호출하지 마세요 - 숫자를 생성하고 remotion-compose / remotion-render에 전달하세요. - YouTube 리핑, 명시된 라이선스가 없는 "무료" 사이트 또는 클라이언트의 Spotify에서 트랙을 가져오지 마세요 - 상업적 사용에는 실제 로열티 프리 또는 라이선스 소스가 필요합니다.
- 전체 믹스를 가능한 한 크게 정규화하지 마세요; 가장 큰 임팩트가 클리핑되지 않도록 헤드룸을 남겨두세요.
- VO가 고정된 런타임에 맞추기 위해 서두르게 하지 마세요 - VO에 맞춰 비주얼을 다시 편집하고, 비주얼에 VO를 맞추지 마세요.
계산기: 비트 그리드
자체 포함 Node 스크립트. beat_grid.js로 저장하고 node beat_grid.js로 실행하세요.
BPM과 fps를 컷이 떨어져야 하는 정확한 프레임 번호로 변환하고 다운비트를 표시합니다. 종속성 없음. 인쇄된 프레임을 <Sequence from={...}> 경계로 remotion-compose에 전달하세요.
// Beat grid. Edit inputs, then: node beat_grid.js
const input = {
bpm: 120, // tempo of the chosen track
fps: 30, // project frame rate
durationSeconds: 12, // length of the video
beatsPerBar: 4, // 4/4 time; downbeat is every 4th beat
}
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('Frames per beat:', framesPerBeat.toFixed(2), '(' + (60 / input.bpm).toFixed(3) + 's each)')
console.log('Cut on these frames (* = downbeat, best for hard cuts):')
for (const b of beats) {
console.log(' beat ' + String(b.beat).padStart(2), '-> frame', String(b.frame).padStart(4), b.downbeat ? '*' : '')
}
console.log('Downbeat frames only:', beats.filter((b) => b.downbeat).map((b) => b.frame).join(', '))
작업 예제 출력
위 입력으로 스크립트는 다음을 출력합니다:
Frames per beat: 15.00 (0.500s each)
Cut on these frames (* = downbeat, best for hard cuts):
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 *
...
Downbeat frames only: 0, 60, 120, 180, 240, 300, 360
해석: 120 BPM 및 30 fps에서 비트는 정확히 15프레임입니다. 일상적인 전환은 나열된 모든 프레임에 배치하고 가장 어려운 컷(인트로-투-콘텐츠 컷, CTA 공개)은 다운비트(0, 60, 120…)에 배치하세요. 장면이 70프레임을 실행하려면 컷이 70에서 떠다니게 하는 대신 75(비트 6)로 스냅하세요. 이러한 스냅된 숫자는 정확히 remotion-compose가 <Sequence from={...}>에 넣는 것입니다.
계산기: 믹스 레벨 및 덕 타이밍
자체 포함 Node 스크립트. mix_levels.js로 저장하고 node mix_levels.js로 실행하세요.
덕킹된 음악 레벨과 각 VO 라인의 프레임 범위를 계산하여 remotion-compose에 분위기 대신 구체적인 엔벨로프를 전달합니다. 종속성 없음.
// Mix and ducking planner. Edit inputs, then: node mix_levels.js
const input = {
fps: 30,
musicVolume: 0.8, // music level when no one is speaking (0-1)
duckToPercent: 0.30, // duck music to this share of its level under VO
voVolume: 1.0, // voiceover level (keep VO the loudest element)
duckFadeFrames: 8, // ramp in/out so the duck is not a hard jump
// VO lines as [startSeconds, endSeconds]; duck music across each, with fade pad
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)
// rough dB for reference: 20*log10(level)
const dB = (v) => (v <= 0 ? '-inf' : (20 * Math.log10(v)).toFixed(1) + ' dB')
console.log('VO level: ', input.voVolume, '(' + dB(input.voVolume) + ') <- loudest element')
console.log('Music (no speech): ', input.musicVolume, '(' + dB(input.musicVolume) + ')')
console.log('Music ducked under VO:', duckedLevel, '(' + dB(duckedLevel) + ')')
console.log('Duck fade: ', input.duckFadeFrames, 'frames in/out')
console.log('Duck music across these frame spans (pad ' + input.duckFadeFrames + 'f each side for the fade):')
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)
}
작업 예제 출력
VO level: 1 (0.0 dB) <- loudest element
Music (no speech): 0.8 (-1.9 dB)
Music ducked under VO: 0.24 (-12.4 dB)
Duck fade: 8 frames in/out
Duck music across these frame spans (pad 8f each side for the fade):
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
해석: VO는 전체 레벨(믹스에서 가장 큰 요소)을 유지하고, 음악은 간격에서 0.8로 재생되며 누군가 말할 때마다 약 1/3인 0.24로 덕킹되고, 8프레임에 걸쳐 페이드되어 딥이 갑작스러운 점프가 되지 않습니다. 프레임 범위는 정확히 remotion-compose가 음악 <Audio> volume 콜백에 공급하는 범위입니다: 범위 밖에서는 전체 레벨, 내부에서는 duckedLevel, 페이드 패드에서 선형 램프됩니다. 이것이 단어가 음악이 사라지지 않고 선명하게 유지되는 이유입니다.
템플릿: 오디오 큐 시트
이것을 복사하고, 비트 그리드 및 믹스 레벨 출력으로 FILL 필드를 채운 다음, 완성된 시트를 remotion-compose에 전달하세요. 비디오의 모든 오디오 결정에 대한 단일 진실 공급원입니다.
AUDIO CUE SHEET. [FILL: video name]. fps [FILL] / [FILL] BPM / [FILL]s total
MUSIC
Track: [FILL: title + source]
License: [FILL: e.g. Epidemic Sound commercial / CC0] - attribution: [FILL: yes/no, text]
Level (no speech): [FILL: 0-1] Ducked under VO: [FILL: 0-1] (~30%)
BEAT GRID (from beat_grid.js) - cuts land here
Downbeat frames: [FILL: 0, 60, 120, ...]
Hard cuts on: [FILL: which downbeats carry the big cuts]
SFX (one per transition; peak ON the motion peak)
FRAME SFX ROLE
[FILL] [FILL whoosh] leads into swipe (start ~4f early, tail on cut)
[FILL] [FILL impact] card slam-in, lands ON cut frame
[FILL] [FILL riser] builds across 10-20f, resolves on reveal
[FILL] [FILL pop] UI element appears
VOICEOVER (~150 wpm; scenes fit the VO, not the reverse)
LINE START END SCENE
[FILL line] [FILL] [FILL] [FILL]
(silence 8-15f before key line / after CTA)
DUCK ENVELOPE (from mix_levels.js) - frame spans to lower music
[FILL: 7-104, 112-233, ...] fade [FILL]f in/out
HANDOFF: remotion-compose wires <Audio> + volume callbacks; remotion-render exports.
참조/로열티-프리-소싱
상업용 비디오에는 실제로 사용할 수 있는 라이선스가 있는 음악이 필요합니다. "YouTube에서 찾았어요"는 라이선스가 아니며 클라이언트의 Spotify도 아닙니다. 사용 사례별 라이선스/로열티 프리 소스:
- 구독 라이브러리(클라이언트/상업/광고에 가장 안전함): Epidemic Sound, Artlist, Musicbed, Soundstripe. 고정 요금, 광범위한 상업 라이선스, 대규모 SFX 라이브러리, 비디오별 저작자 표시 불필요. 유료 작업의 기본값.
- 조건이 있는 무료(각 트랙 확인 필요): YouTube Audio Library, Free Music Archive, Incompetech, Freesound. 종종 라이선스 유형(CC0, CC BY 등)을 지정합니다. CC BY는 저작자 표시가 필요하며 일부 상업 라이선스는 허용하지 않습니다. 확인하세요.
- 피해야 할 것: YouTube 리핑, 라이선스가 명시되지 않은 "무료" 사이트, 클라이언트의 Spotify 계정. 저작권 위반 책임은 귀하에게 있습니다.
- 라이선스 기록: 각 트랙에 대해 제목, 소스, 라이선스 유형, 저작자 표시 필요 여부를 기록하세요. 프로젝트 자산 폴더에 LICENSE.txt 파일이 좋은 방법입니다.
참조/SFX-배치
SFX는 모션의 물리적 느낌을 강화하며 모든 전환을 개별적으로 만듭니다. 여기에 몇 가지 일반적인 예가 있습니다.
| SFX 유형 | 모션 순간 | 프레임 배치 | 효과 |
|---|---|---|---|
| 후샤 | 스와이프/패닝 | 컷보다 3~5프레임 일찍 시작, 꼬리가 컷에 떨어짐 | 부드러운 전환 강조 |
| 임팩트/둔탁 | 카드 슬램인/요소 등장 | 정확히 컷 프레임 | 갑작스러운 느낌을 물리적으로 만듦 |
| 클릭/팝 | UI 요소 나타남 | 정확히 컷 프레임 | 깔끔한 마이크로 상호 작용 |
| 라이저 | 공개 전 빌드업 | 공개 전 10~20프레임, 공개 시 해결 | 기대감 구축 |
| 스월 | 화면 밖에서 요소가 회전하며 들어옴 | 회전 피크 전 5~10프레임 시작 | 회전 동작 강조 |
규칙: 각 효과의 피크를 해당 모션의 피크와 일치시키세요. 전환당 하나의 SFX. 규칙은 기억하기 쉽습니다: 같은 효과를 반복해서 사용하지 마세요. 패턴이 지루해집니다.