Audio Pitch:用 playbackRate 改音高——窮人版的 pitch shift
用 Remotion 的 playbackRate 一行字把音效變低音/高音。原理是「速度跟音高綁在一起」,做出來的 BASS / CHIPMUNK 效果免費又好用。順便講為什麼這不是真正的 pitch shift。
成品預覽
一個 source chime 透過三條不同的 playbackRate 線分別播放——1.0(原版)、0.6(低八度)、1.5(高八度)。同一個音檔,三種感覺,沒有外掛、沒有 ffmpeg、就是 Remotion 內建的一個 prop。
這篇會做出什麼
把同一個音效檔變成三種不同個性的聲音:
- ORIGINAL (
playbackRate=1.0):原版 - BASS (
playbackRate=0.6):降速 40%,音高同時降低八度,變成「重低音」 - CHIPMUNK (
playbackRate=1.5):加速 50%,音高升高,變成「卡通松鼠」
整篇只教一個技術:<Audio playbackRate> 這個 prop。
前置知識
- T16 Audio Ducking — 熟悉 dynamic
<Audio> - T13 影片剪輯 — 用過
playbackRate在影片上
Step 1:基礎用法
Claude Code:
新增 Composition "PitchDemo":
- 1920x1080 fps 30 durationInFrames 300(10 秒)
- 新建 src/compositions/PitchDemo.tsx 並在 Root.tsx 註冊
掛三個 <Audio>,全部用同一個 source 檔,但 playbackRate 不同:
<Sequence from={30} durationInFrames={50}>
<Audio src={staticFile("audio/chime.mp3")} playbackRate={1.0} />
</Sequence>
<Sequence from={90} durationInFrames={50}>
<Audio src={staticFile("audio/chime.mp3")} playbackRate={0.6} />
</Sequence>
<Sequence from={150} durationInFrames={50}>
<Audio src={staticFile("audio/chime.mp3")} playbackRate={1.5} />
</Sequence>
播一次:你會聽到同一個 chime 變成三個完全不同的聲音。第一行字就讓你做出 pitch shift。
💡
playbackRate對音訊與影片都有效,完整行為在 /docs/audio-pitch。
Step 2:原理——為什麼速度會改音高?
數位音訊就是一串波形 sample(例如每秒 44,100 個點)。playbackRate=0.6 等於:
「把每個 sample 之間的時間拉長 1.67 倍」
時間拉長 → 波形變慢 → 頻率變低 → 聽起來音高下降。
數學上:新音高 = 原音高 × playbackRate。
playbackRate | 聽感 | 半音差 |
|---|---|---|
0.5 | 降一個八度 | −12 |
0.6 | 降六度 | −9 |
0.8 | 降三度 | −4 |
1.0 | 原音 | 0 |
1.2 | 升三度 | +3 |
1.5 | 升五度 | +7 |
2.0 | 升一個八度 | +12 |
知道這張表你就能用 playbackRate 「彈奏」任何音效——例如 4 個不同 rate 的 kick drum 就是一條 bassline。
Step 3:實戰應用
A. 重低音版本的 SFX
UI 音效(pop / whoosh / ding)通常是中高頻。想做「重磅落地」感:
// 普通 whoosh
<Audio src={staticFile("audio/whoosh.mp3")} playbackRate={1.0} />
// 重低音版本(搭配畫面震動更有感)
<Audio src={staticFile("audio/whoosh.mp3")} playbackRate={0.55} volume={1.0} />一個 whoosh 檔案可以有「飛行版」(1.0)、「砸地版」(0.6)、「微氣流版」(1.4)三個不同用途。
B. 卡通對話
把人聲錄音的 playbackRate 開到 1.4~1.6,瞬間變成卡通松鼠的對話。<Audio> 跟 <OffthreadVideo> 都吃這個 prop,可以視訊一起變速。
C. 自製 bassline
把同一個 piano hit 用不同 playbackRate 排成一條 sequence:
const NOTES = [
{ from: 0, rate: 0.50 }, // C2
{ from: 30, rate: 0.56 }, // D2
{ from: 60, rate: 0.63 }, // E2
{ from: 90, rate: 0.67 }, // F2
];
{NOTES.map((n, i) => (
<Sequence key={i} from={n.from} durationInFrames={30}>
<Audio src={staticFile("audio/piano-c4.mp3")} playbackRate={n.rate} />
</Sequence>
))}一個 piano sample,零成本做出旋律。
Step 4:limitation——為什麼這不是「真的」pitch shift
專業 DAW(Pro Tools、Ableton)的 pitch shift 可以做到:
改音高、不改速度 ✅
Remotion 的 playbackRate 做不到——它是「速度跟音高綁在一起」的單一 knob。
| 需求 | Remotion playbackRate | 真正的 pitch shift |
|---|---|---|
| 改音高 | ✅ | ✅ |
| 改速度 | ✅(強制) | ❌(可以保持) |
| 即時、無 artifact | ✅ | ❌(需要相位重建演算法) |
| 一行 prop 搞定 | ✅ | ❌(要外掛 / ffmpeg) |
什麼時候 Remotion 夠用:SFX(whoosh、kick、impact、pop)。這些東西本來就短促、不在乎速度被改、不在乎變調 artifact。
什麼時候要用 ffmpeg:人聲對話、主旋律樂器、長音樂段——這些東西必須保持速度但改變音高。預先用 ffmpeg 的 rubberband filter 處理:
ffmpeg -i in.mp3 -af "rubberband=pitch=0.5" out-bass.mp3然後在 Remotion 用 <Audio src={staticFile("out-bass.mp3")} /> 載入處理過的版本。
💡
audio-pitch的進階用法、限制與替代方案在 /docs/audio-pitch。
Step 5:讓 playbackRate 動態變化
playbackRate 一經 <Audio> 設定就是固定的,不能寫成 frame 函式——因為 Remotion 要靠這個值規劃整段音訊在 timeline 上的長度。
想要「音高漸變」效果(例如 pitch sweep),用兩種方法:
方法 1:多段拼接
{[0.6, 0.7, 0.8, 0.9, 1.0].map((rate, i) => (
<Sequence key={i} from={i * 6} durationInFrames={6}>
<Audio src={staticFile("audio/tone.mp3")} playbackRate={rate} />
</Sequence>
))}每 6 幀換一段更高的 rate,聽起來像 pitch up sweep。
方法 2:預先處理
用 ffmpeg 的 asetrate filter 預先做出 sweep 版本:
ffmpeg -i tone.mp3 -af "asetrate=44100*1.5" tone-sweep.mp3然後 Remotion 直接 <Audio src=…> 載入。
Step 6:渲染
渲染 PitchDemo:
- 1920x1080 H.264
- 音訊 codec aac
- 音訊 bitrate 192k
- 輸出 out/audio-pitch.mp4
戴耳機聽——三段 chime 的音高高低差很明顯,但也聽得出來時間長度也跟著變了(BASS 比 ORIGINAL 久、CHIPMUNK 比 ORIGINAL 短)。這就是 playbackRate 的本質。
完成!回顧學到的概念
| 概念 | 重點 |
|---|---|
<Audio playbackRate> | 一個數字改速度 + 音高 |
| 速度 ↔ 音高公式 | 新音高 = 原音高 × playbackRate |
| 八度數學 | 0.5x = −12 半音、2.0x = +12 半音 |
| 只能設靜態值 | 想動態變化要拼多段 Sequence |
| 不是真 pitch shift | 速度也會跟著變;只適合 SFX |
本篇涵蓋的官方文件
- /docs/audio-pitch —
playbackRate改音高 - /docs/audio-playback-rate — playbackRate 詳解
- /docs/video-playback-rate — 影片版的 playbackRate
- /docs/audio-details — 音訊處理細節
常見問題
Q:playbackRate={2} 把 1 秒的音檔變成 0.5 秒,那 <Sequence durationInFrames={30}> 裝得下什麼?
A:Remotion 會在 sequence 結束時自動截掉沒播完的部分。如果你的 sequence 比加速後的音訊還長,多出來那段就是靜音。
Q:playbackRate={0.5} 會讓音檔變兩倍長嗎?
A:是。<Sequence durationInFrames> 要相對應地給足時間,不然會被切掉。
Q:可以把 playbackRate 跟 volume 函式同時用嗎?
A:可以。volume 接函式、playbackRate 接靜態值,互不干擾。
Q:低 playbackRate 為什麼會出現 artifact(像 robot 聲)?
A:digital sample 之間靠 interpolation 補出來——速度越慢,補的點越多,artifact 越明顯。0.6 還可以接受,0.3 以下就會很明顯。
Q:播放 mp3 跟 wav 結果有差嗎? A:理論上沒有。實務上 mp3 在低 bitrate(<128k)做大幅度 pitch shift 時 artifact 會比 wav 明顯。
下一步
- T16:Audio Ducking — 配音/配樂混音的另一半
- T14:3D 特效與 Shader — 視覺升級
有問題歡迎到 FB 社群 討論!