節拍同步
scripts/ 中的腳本:
beats.py MUSIC --out beats.json [--start S --end E]— 速度、節拍、強拍預測、強打擊點(重擊)、每秒 RMS 能量。timemap.py— 建立可變速度時間映射(速度曲線),並使用 ffmpeg 逐幀渲染。
1. 分析音樂
python beats.py song.mp3 --out edit/beats.json
輸出 tempo、beats(秒)、downbeats(從最強相位開始每 4 拍一個)、hits(強打擊點:小鼓/大鼓/墜落)、energy(每 0.5 秒)。
讀取結果:
- 節拍週期
P = 60 / BPM。在 30 FPS 時,120 BPM 的一拍 = 15 幀。 - 打擊點不一定是節拍。 人聲重音、上升結束、墜落。對於「編輯音頻」趨勢,剪輯點是打擊點,而非節拍器。
- librosa 可能鎖定到半速或倍速。快速確認:典型流行樂 90-130 BPM,Trap 130-160(常感覺像半速),EDM 120-128,Phonk 130-150。如果偵測到的網格在逐幀測試中感覺不對,請將速度減半或加倍。
- 能量曲線可找到墜落/副歌:安靜段落後最大的 RMS 跳躍。
2. 選取歌曲段落
- 短格式:7-20 秒。段落從強拍開始,並在強拍或樂句結尾(4 或 8 小節)結束。
- 將最強烈的視覺效果放在墜落處。如果墜落在歌曲中的第 12 秒,而你希望它在 Reel 的第 3 秒出現,則段落從第 9 秒開始。
- Instagram/TikTok 上的流行音效:應用程式內音效從固定點開始。如果最終貼文將使用應用程式內音效,請將你的剪輯對齊該起始點,並匯出一個包含參考音訊作為引導的版本。
- 淡入音樂 10-50 毫秒(避免爆音),除非段落從瞬態開始;淡出 0.3-1.5 秒,或在強打擊點結束。
3. 建立網格與放置事件
fps = 30
fr = lambda t: round(t * fps) # 將每個事件對齊到最近的幀
U = beat_period / 2 # 子拍單位(8 分音符),適用於節奏較快的歌曲
- 剪輯:為了流暢感選擇節拍,為了衝擊感選擇打擊點。每拍都剪輯會讓人疲勞;每 2 或 4 拍剪輯一次,僅在墜落前短時間(2-4 秒)使用每拍剪輯。
- 預先剪輯:將剪輯點放在節拍之前 1-2 幀,在手機上感覺更緊湊(音頻延遲 + 感知)。測試兩者並始終如一地選擇。
- 閃爍 / 抖動 / 縮放衝擊:在打擊點上,持續 2-6 幀,並衰減。
- 文字:單詞出現在人聲音節或節拍上;每個單詞至少停留 0.4 秒(單字),或按節奏朗讀的行約 0.25 秒/字。
- 速度 / 效果變化:在強拍或墜落處。
- 建立一個表格(
timing.json),記錄每個事件及其音樂理由;建置腳本會讀取它。
4. 速度曲線(速率)
速度曲線是時間映射 src_t = f(out_t)。透過具有平滑速度的段落來建構:
# 速度曲線:1x ... 在打擊點之間加速到 4x ... 在打擊點上回到 0.3x
segments = [(out_start, out_end, speed_start, speed_end, ease)]
- 使用平滑步進/三次函數來緩入緩出速度;瞬間從 1x 跳到 4x 看起來像故障。
- 在打擊點上慢速(0.2-0.5x),在打擊點之間快速(2-5x)。打擊點本身顯示關鍵動作(撞擊、轉身、看向鏡頭)。
- 慢速段落需要高 FPS 素材或幀插值(
minterpolate、Resolve Speed Warp、RIFE)。 - 在快速部分添加動態模糊(
tmix=frames=3或在時間映射渲染器中進行幀混合),以避免閃爍。 - 真實案例:俯拍桌面鏡頭,移動部分保持在 1x,靜止部分為 5.6x,每次速度變化都在強打擊點上;光流法(OpenCV LK + RANSAC 相似度)自動定位相機移動(參見
motion-tracking)。
timemap.py 透過為每個輸出幀拉取正確的原始幀(可選幀混合)來渲染時間映射——比串聯 setpts 濾鏡更準確、更簡單。
5. 比對參考影片的時機
- 下載/取得參考影片;提取其音頻。
- 偵測其剪輯點:
ffmpeg -i ref.mp4 -vf "select='gt(scene,0.3)',showinfo" -f null - 2>&1 | grep pts_time。 - 偵測其音頻的節拍;將每個剪輯點表示為節拍索引或偏移量 → 這就是節奏模板。
- 透過逐幀步進(1/30 秒精度)測量文字出現/消失時間。
- 使用你的素材在同一個網格上重建(參見
reference-matching)。
6. 驗證
- 對渲染結果進行場景偵測;每個剪輯點時間 × fps 應等於規劃的幀數(±0)。
- 在偵錯渲染中疊加節拍上的點擊音軌(使用
aevalsrc產生正弦波脈衝),並在打擊點處抓取幀。 - 你無法透過聽覺驗證:報告數字(規劃 vs 實際測量的剪輯幀數),並請使用者以聽覺檢查。