逐字跑詞是怎麼「估」出來的:Lyric Sync 的卡拉OK效果
Lyric Sync 是一個 Chrome 外掛,在 YouTube 日文歌曲上顯示可拖曳的浮動歌詞面板:原文、假名、中文翻譯,還有像卡拉OK一樣逐字亮起來的跑詞。這個效果看起來很精準,但說實話,它是「估」出來的。
資料來源的限制
歌詞來自開放的歌詞資料庫 lrclib.net。它提供的是 LRC 格式的同步歌詞:每一行有一個開始時間,例如 [01:23.45]。也就是說,我知道「這一句從哪一秒開始」,但不知道「句子裡的每個字在哪一秒被唱出來」。
最簡單的做法,是把「這句開始」到「下一句開始」的時間平均分給每個字。問題是歌不是這樣唱的:主歌通常字很密、速度快,副歌常常拖長音,間奏前還會有一段空白。平均分配會讓快的地方跑太慢,慢的地方跑太快。
用附近的節奏反推
我的做法是先找出「這句到下一句間隔很短、明顯沒有被切斷」的行,用它們反推出當下那一段的實際「每字幾秒」。需要估算的行(例如拖長音的副歌、間奏前的長音),再套用附近段落的節奏,而不是整首歌共用一個平均值。這樣同一首歌的快段與慢段,會各自得到合理的速度。
後來又做了幾項改善:
- 空白時間行:LRC 裡有些時間點後面沒有任何文字,代表「歌聲在這裡停下」。以前我把這些行丟掉,結果間奏前那一句的跑詞會被拉長到整段間奏。現在保留它們,那句歌詞會剛好在歌聲停下時跑完,間奏改顯示 ♪ 與「下一句 N 秒」的倒數。
- 用「拍」計算:日文的時間單位是 mora(拍)。「ゃ、ゅ、ょ」不另外算一拍,標點與空白不佔時間,英文單字則依音節計算。
- 漸進填色:正在唱的字從左到右慢慢填色,而不是整個字一次跳亮,看起來更像真正的卡拉OK。
- 有逐字時間就直接用:少數歌詞檔帶有
<mm:ss.xx>的逐字時間,這時完全照它跑,不用估算。
老實說:它不是逐字精準
這個方法對大部分的歌效果不錯,但終究是估算。遇到節奏很特殊、速度變化很大的歌,字亮起來的時間會和真正的歌聲有落差。我在 README 裡把它列為已知限制,沒有包裝成「精準同步」。
其他實用功能
為了練唱,我另外加了幾個功能:
- 手動微調:歌詞比人聲慢就按+,快就按-,可以即時調整,換歌時自動歸零。
- 詞集模式:像 Spotify 那樣整頁列出歌詞,點任何一句可以直接跳到那一句,比拉進度條精準。
- 練唱速度:可以放慢到 0.5 倍,音高不變,歌詞與跑詞跟著影片的時間走,所以也會自動變慢。
- 升降 key 與消除人聲:用 Web Audio 在瀏覽器本機處理,變調範圍限制在正負 3 個半音,因為再好的演算法也有失真的極限。消除人聲只能去掉「居中」的聲音,效果依歌曲而定。
這些處理全部在你的瀏覽器本機完成,不會上傳任何音訊。
想試試看可以到 Lyric Sync 的介紹頁。下一篇會談假名讀音為什麼不能保證 100% 正確。