.lrc java解析_lrc滚动歌词解析及显示

范浩宕
2023-12-01

lrc歌词格式是什么样的?

lrc是英文lyric(歌词)的缩写,被用做歌词文件的扩展名。以lrc为扩展名的歌词文件可以在各类数码播放器中同步显示。LRC 歌词是一种包含着“:”形式的“标签(tag)”的、基于纯文本的歌词专用格式。这种歌词文件既可以用来实现卡拉OK功能(需要专门程序),又能以普通的文字处理软件查看、编辑。当然,实际操作时通常是用专门的LRC歌词编辑软件进行高效编辑的。

lrc歌词文本中含有两类标签:

一是标识标签,其格式为“[标识名:值]”主要包含以下预定义的标签:

[ar:艺人名]

[ti:曲名]

[al:专辑名]

[by:编者(指编辑LRC歌词的人)]

[offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的,(但多数的MP3可能不会支持这种标签)。

二是时间标签,形式为“[mm:ss]”或“[mm:ss.ff]”(分钟数:秒数.毫秒数),时间标签需位于某行歌词中的句首部分,一行歌词可以包含多个时间标签(比如歌词中的迭句部分)。当歌曲播放到达某一时间点时,MP3就会寻找对应的时间标签并显示标签后面的歌词文本,这样就完成了“歌词同步”的功能。

形式为"[mm:ss]"(分钟数:秒数)或"[mm:ss.ff]"。数字须为非负整数, 比如"[12:34.50]"是有效的,而"[0x0C:-34.50]"无效。标签无须排序。

js如何实现lrc歌词的解析?

解析思路如下

根据lrc字符串,通过换行符分成数组的每一项。

对每行进行正则表达式匹配,如果匹配上的是时间正则表达式,则对这行进行时间逻辑处理。相应的,如果是曲作者或者演唱者或者是偏移量,则进行相对应的逻辑处理。相应的正则表达式

_regAr = /\[ar:(.+)\]/,

_regTi = /\[ti:(.+)\]/,

_regAl = /\[al:(.+)\]/,

_regBy = /\[by:(.+)\]/,

_regOffset = /\[offset:.+\]/,

_regTime = /\[\d+:\d+(\.\d+)?\]/g,

以[01:10.50]为例,统一解析成以秒为单位的70.5秒。转换成这样是为了让时间的表示更简洁,但是在进行显示和存储歌词之前还需提供一个format函数将时间计算回去。

输出结果为:按照时间排序之后的数组,数组每一项为以time,和txt为key的对象。Lrclist如下的格式

0: Object

time: 9.841

txt: "It's been a long day without you my friend"

1: Object

time: 16.8

txt: "And I'll tell you all about it when

如果需要歌词的Lrctxt文本,就可以借助format函数将时间将Lrclist中的每一项进行拼接成如下的格式:

0: "[00:09.841]It's been a long day without you my friend"

1: "[00:16.800]And I'll tell you all about it when I see you again"

2: "[00:22.600]We've come a long way from where we began"

如何实现滚动歌词的播放界面?

滚动歌词的界面是将内容插入到播放父节点this.__ncontent下面:

_u._$forEach(Lrclist,function(_item){

_lines.push('

'+_item.txt+'');

}

this.__ncontent.innerHTML = _lines.join('');

当歌曲在播放的过程中,根据播放的时间_time,从后向前依次对比时间,找到对应的index记录为currnetplay,通过更改样式,表示是当前播放的歌词。

而滚动的效果可以通过整体改变margin-top来实现滚动的效果。在项目中简化处理是直接设置li个父节点top为播放父节点的height/2-li的行高。

这里存在一个问题,如果一行歌词特别长,显示的时候进行了换行,那么这个距离计算的就会有问题。当然,一种是通过js计算出几行;另外是加个横向的滚动条,丑是丑了点,确实是比较简单的处理了。

同时显示翻译歌词如何实现?

当带翻译的歌词滚动播放的时候,我们希望连带翻译歌词一块滚动。在这里,我是通过对解析出来的lrclist中的时间找到对应的翻译歌词translist中的索引,来为列表中的每一项增加key为transtxt的内容:

_u._$forEach(_list, function(_item){

var _index = _u._$indexOf(_translist, function(_item0){

return _item0.time==_item.time;

});

if(_index!=-1){

var _trans = _translist[_index];

}

if(_trans){

_item.transtxt = _trans.txt||'';

}

});

这样解析出来的歌词对象就变成:

0: Object

time: 9.841

transtxt: "没有老友你的陪伴 日子真是漫长"

txt: "It's been a long day without you my

滚动时候的显示规则同上,只不过在滚动时,top值要减去 2*li 的行高了。

歌词时间轴调整如何实现?

在滚动播放的过程中,常常希望根据播放的效果对歌词进行整体的,或者当前句的微调。

这些需求就是直接操作歌词的时间轴了。

整体偏移一个offset就是将解析出来的lrclist中的每一item中的时间加/减一个offset,通常微调的话,毫秒级别了。

当前句偏移,关键是找到currentplay,这个在前面已经介绍了。

之后偏移,也是找到currentplay,将该索引之后的item的时间加/减一个偏移量。

关于作者

菜鸟一枚,希望自己能将写博客的习惯养成,并发扬光大。嗯嗯。。自勉。。。

 类似资料: