Skip to content

LRC 文件相关

LRC 文件为包含了时间信息的歌词文件,常用于卡拉 OK、播放器滚动歌词等场景。

简单格式

一般情况下,LRC 文件中,每句歌词都以时间标签开头。时间标签格式为 [mm:ss.xx],其中 mm 为分钟数,ss为秒数,xx为百分之一秒。示例:

[00:12.00]Line 1 lyrics
[00:17.20]Line 2 lyrics
[00:21.10]Line 3 lyrics

个别软件会支持到更精确的千分之一秒,即 [mm:ss.xxx] 格式。

增强格式

作为基础 LRC 的扩展,有些软件增加了 <mm:ss.xx> 格式的支持,以便精确定位到词语。如:

[00:00.00] <00:00.04> When <00:00.16> the <00:00.82> truth <00:01.29> is <00:01.63> found <00:03.09> to <00:03.37> be <00:05.92> lies

但是大多只是软件自行定义,并没有统一的格式规范。

ID3 支持

有些软件可以支持解析 LRC 文件中的标准 ID3 信息,如

[al:Sarah Hi]
[ar:Jade Michael]
[au:Jade Michael]
[by:]
[ti:Somebody to Love]
[offset:0]
tag作用
al所属专辑名
ar艺人名(演出者/歌手)
au词作者/曲作者
byLRC 歌词制作人
ti歌曲标题
offset时间轴偏移量(毫秒为单位,支持负数)

另外,ID3 仅存储文本信息,并不校验文本内容正确性及格式,以下情况都是合法的:

  • [au: Jade Michael][au: Written by Jade Michael]
  • [au: Slash/Duff/Rose][au: Slash - Duff - Rose]

ID3(ID Tags)因为被广泛支持而成为事实标准,但是并没有实质的规范,更像是 “约定”,实现版本也很松散。

开源介绍

在线版开源的目前比较成型的有两个:

业界实现

腾讯音乐使用了 LRC 歌词,通过歌曲详情页的 HTTP 接口可以看到。内部存储的是 base64,需要 decode,比如 周杰伦的 说好不哭,接口返回的是

W3RpOuivtOWlveS4jeWTre+8iFdpdGgg5LqU5pyI5aSp6Zi/5L+h77yJXQpbYXI65ZGo5p2w5LymXQpbYWw66K+05aW95LiN5ZOt77yIV2l0aCDkupTmnIjlpKnpmL/kv6HvvIldCltieTpdCltvZmZzZXQ6MF0KWzAwOjAwLjAwXeivtOWlveS4jeWTre+8iHdpdGgg5LqU5pyI5aSp6Zi/5L+h77yJIC0g5ZGo5p2w5LymIChKYXkgQ2hvdSkKWzAwOjA1LjgxXeivje+8muaWueaWh+WxsQpbMDA6MTEuNjJd5puy77ya5ZGo5p2w5LymClswMDoxNy40M13nvJbmm7LvvJrpu4Tpm6jli4sKWzAwOjIzLjI0XeWRqOadsOS8pu+8mgpbMDA6MjYuNTFd5rKh5pyJ5LqG6IGU57ucIOWQjuadpeeahOeUn+a0uwpbMDA6MjkuNzZd5oiR6YO95piv5ZCs5Yir5Lq66K+0ClswMDozMi44NV3or7TkvaDmgI7kuYjkuoYg6K+05L2g5oCO5LmI6L+HClswMDozNi4wMl3mlL7kuI3kuIvnmoTkurrmmK/miJEKWzAwOjM5LjIwXeS6uuWkmueahOaXtuWAmSDlsLHlvoXlnKjop5LokL0KWzAwOjQyLjM0XeWwseaAleWIq+S6uumXrui1t+aIkQpbMDA6NDUuMzdd5L2g5Lus5oCO5LmI5LqGIOS9oOS9juedgOWktApbMDA6NDguMzBd5oqk552A5oiR6L+e5oqx5oCo6YO95rKh5pyJClswMDo1MS44Ml3nlLXor53lvIDlp4vourIg5LuO5LiN5a+55oiR6K+0ClswMDo1NC45OF3kuI3kuaDmg6/kuIDkuKrkurrnlJ/mtLsKWzAwOjU4LjExXeemu+W8gOaIkeS7peWQjiDopoHmiJHlpb3lpb3ov4cKWzAxOjAxLjMyXeaAleaJk+aJsOaDs+iHqueUseeahOaIkQpbMDE6MDQuMzld6YO96L+Z5Liq5pe25YCZIOS9oOi/mOWcqOaEj+edgApbMDE6MDcuNTZd5Yir5Lq65piv5oCO5LmI5oCO5LmI55yL5oiR55qEClswMToxMC43N13mi7zlkb3op6Pph4rnnYAg5LiN5piv5oiR55qE6ZSZIOaYr+S9oOimgei1sApbMDE6MTUuNTVd55y855yL552A5L2g6Zq+6L+HIOaMveeVmeeahOivneWNtOayoeacieivtApbMDE6MjguMTRd5L2g5Lya5b6u56yR5pS+5omLIOivtOWlveS4jeWTreiuqeaIkei1sApbMDE6NTIuMTNd6Zi/5L+h77yaClswMTo1NC45NV3nlLXor53lvIDlp4vourIg5LuO5LiN5a+55oiR6K+0ClswMTo1OC4xN13kuI3kuaDmg6/kuIDkuKrkurrnlJ/mtLsKWzAyOjAxLjI2Xeemu+W8gOaIkeS7peWQjiDopoHmiJHlpb3lpb3ov4cKWzAyOjA0LjQxXeaAleaJk+aJsOaDs+iHqueUseeahOaIkQpbMDI6MDcuNjJd6YO96L+Z5Liq5pe25YCZIOS9oOi/mOWcqOaEj+edgApbMDI6MTAuNjJd5Yir5Lq65piv5oCO5LmI5oCO5LmI55yL5oiR55qEClswMjoxMy45MF3mi7zlkb3op6Pph4rnnYAg5LiN5piv5oiR55qE6ZSZIOaYr+S9oOimgei1sApbMDI6MTguNTFd5ZCI77yaClswMjoxOC43MV3nnLznnIvnnYDkvaDpmr7ov4cg5oy955WZ55qE6K+d5Y205rKh5pyJ6K+0ClswMjozMS4yOF3kvaDkvJrlvq7nrJHmlL7miYsg6K+05aW95LiN5ZOt6K6p5oiR6LWwClswMjo1MC41NF3lkajmnbDkvKbvvJoKWzAyOjUzLjM4XeS9oOS7gOS5iOmDveayoeaciSDljbTov5jkuLrmiJHnmoTmoqbliqDmsrkKWzAzOjA0Ljk5XemYv+S/oe+8mgpbMDM6MDUuOTJd5b+D55a86L+H5LqG5aSa5LmFClswMzowOS44M13lkajmnbDkvKbvvJoKWzAzOjEwLjAyXei/h+S6huWkmuS5hQpbMDM6MTIuNThd5ZCI77yaClswMzoxMi43N13ov5jlnKjmib7nkIbnlLHnrYnmiJE=

解析出来即为

[ti:说好不哭(With 五月天阿信)]
[ar:周杰伦]
[al:说好不哭(With 五月天阿信)]
[by:]
[offset:0]
[00:00.00]说好不哭(with 五月天阿信) - 周杰伦 (Jay Chou)
[00:05.81]词:方文山
[00:11.62]曲:周杰伦
[00:17.43]编曲:黄雨勋
[00:23.24]周杰伦:
[00:26.51]没有了联络 后来的生活
[00:29.76]我都是听别人说
[00:32.85]说你怎么了 说你怎么过
[00:36.02]放不下的人是我
[00:39.20]人多的时候 就待在角落
[00:42.34]就怕别人问起我
[00:45.37]你们怎么了 你低着头
[00:48.30]护着我连抱怨都没有
[00:51.82]电话开始躲 从不对我说
[00:54.98]不习惯一个人生活
[00:58.11]离开我以后 要我好好过
[01:01.32]怕打扰想自由的我
[01:04.39]都这个时候 你还在意着
[01:07.56]别人是怎么怎么看我的
[01:10.77]拼命解释着 不是我的错 是你要走
[01:15.55]眼看着你难过 挽留的话却没有说
[01:28.14]你会微笑放手 说好不哭让我走
[01:52.13]阿信:
[01:54.95]电话开始躲 从不对我说
[01:58.17]不习惯一个人生活
[02:01.26]离开我以后 要我好好过
[02:04.41]怕打扰想自由的我
[02:07.62]都这个时候 你还在意着
[02:10.62]别人是怎么怎么看我的
[02:13.90]拼命解释着 不是我的错 是你要走
[02:18.51]合:
[02:18.71]眼看着你难过 挽留的话却没有说
[02:31.28]你会微笑放手 说好不哭让我走
[02:50.54]周杰伦:
[02:53.38]你什么都没有 却还为我的梦加油
[03:04.99]阿信:
[03:05.92]心疼过了多久
[03:09.83]周杰伦:
[03:10.02]过了多久
[03:12.58]合:
[03:12.77]还在找理由等我

严格意义上这并不是一份干净的 LRC,里面人声部分的人名、词曲都夹杂进了时间轴。 如果一首歌一开始就有实际的人声,这些多余信息就会干扰正常时间轴。

开发记录

一些关键点:

本地音频文件读取

File 搭配 URL.createObjectURL,生成 blob:http:// 格式的音频文件地址,规避 audio 播放音频的跨域问题

歌词逐行读取及维护时间标签

一般情况下,歌词输入框使用原生的 textarea,换行符号会是 \n, JS 根据 \n 分割即可。

但是在交互层,textarea 内的文本无法在 UI 层面 选定单行,所以目前的开源方案都是选择了 一个歌词文本输入框,搭配一个实时同步的歌词纯展示界面,两者并行的方法。

  • 歌词文本输入框负责纯文本模式修改
  • 展示界面负责在听歌的时候实时维护每一行的事件标签

判断句子是否已经存在时间标签

正则匹配即可

参考