859 字
4 分钟
给博客播放器加歌词:LRC 解析、三处消费与 Meting 透传

目标形态#

接入完成后,歌词在三个地方消费同一份数据:

  1. 侧栏播放器的歌词面板——逐行滚动、点击行跳转进度;
  2. 悬浮歌词条——屏幕下缘一条始终可见的当前歌词;
  3. 悬浮控件的胶囊歌词——收起形态下唱片旁边的单行歌词。

三处共用一个解析结果和一个「当前行」计算,播放逻辑零侵入。

LRC 解析器#

LRC 本质是「时间标签 + 文本」的行式格式。解析器只做一件事:把 [mm:ss.xx] 抽出来换算成秒并排序。

export interface LrcLine {
time: number; // 秒
text: string;
}
export function parseLrc(raw: string): LrcLine[] {
const lines: LrcLine[] = [];
for (const line of raw.split(/\r?\n/)) {
// 一行可能有多个时间标签(合并重复句),全部展开
const times = [...line.matchAll(/\[(\d+):(\d+)(?:\.(\d+))?\]/g)];
if (times.length === 0) continue;
const text = line.replace(/\[(\d+):(\d+)(?:\.(\d+))?\]/g, "").trim();
for (const m of times) {
const time = Number(m[1]) * 60 + Number(m[2]) + Number(`0.${m[3] ?? "0"}`);
lines.push({ time, text });
}
}
return lines.sort((a, b) => a.time - b.time);
}

「当前行」用一次线性扫描就够了——歌词通常不超过百行,没必要二分:

export function currentLrcIndexAt(lines: LrcLine[], t: number): number {
let index = -1;
for (let i = 0; i < lines.length; i++) {
if (lines[i].time <= t) index = i;
else break;
}
return index;
}

歌词资源放在内容仓#

歌词文件放在内容仓 public/assets/music/lrc/ 下,与曲目在 data/music.ts 里对接:

export const musicTracks = [
{
id: "koufue",
title: "口笛で愛は歌えない",
artist: "Dazbee",
cover: "/assets/music/cover/dazbee.webp",
src: "/assets/music/audio/koufue.mp3",
// 歌词:远端 .lrc 地址或内嵌 LRC 文本均可
lrc: "/assets/music/lrc/koufue.lrc",
},
// ...
];

歌词内容的获取是懒加载的:面板或歌词条第一次需要显示时才 fetch,解析结果按曲目缓存——不听歌的访客不会为歌词付出任何请求。

Meting 平台的歌词透传#

本地曲目之外,Meting(在线音乐平台聚合)模式同样支持歌词:接口返回的 lrc 字段原样透传给同一个解析器。这样无论曲目来自本地还是在线平台,下游三处消费逻辑完全一致。

// Meting 曲目解析时保留 lrc 字段
if (metingLrc) {
track.lrc = metingLrc; // 透传,下游统一懒加载解析
}

三处消费的取舍#

消费位置交互备注
歌词面板自动滚动跟随 + 点击跳转 + 手动滚动暂停 3s功能最全
悬浮歌词条只显示当前行常驻屏幕下缘,无滚动
胶囊歌词只显示当前行,超长省略嵌在悬浮控件里

自动滚动跟随的实现要点:歌词行变化时 scrollTo 目标行到容器垂直居中;用户手动滚动(wheel / touchstart)后暂停跟随 3 秒再恢复,避免「人在看上一句、视图被拽走」的对抗。

空歌词的降级链

无 lrc 配置 → 显示「暂无歌词」占位 → 相关按钮隐藏。歌词加载失败同理,占位文案区分「加载中」和「没有歌词」,不留空白区域。

收尾#

整个歌词功能约 200 行:一个解析器、一个当前行计算、三处消费、一次懒加载。配置上 showLyrics: false 一行可以让全部歌词 UI 零 DOM;每首歌想不加歌词,不写 lrc 字段就行。

给博客播放器加歌词:LRC 解析、三处消费与 Meting 透传
https://blog.fqzlr.top/posts/tech/blog-music-lyrics-lrc/
作者
fqzlr
发布于
2026-09-05
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取