资讯专栏INFORMATION COLUMN

lrc滚动歌词解析及显示

android_c / 2661人阅读

摘要:以为扩展名的歌词文件可以在各类数码播放器中同步显示。这是用于总体调整显示快慢的,但多数的可能不会支持这种标签。如何实现歌词的解析解析思路如下根据字符串,通过换行符分成数组的每一项。相应的正则表达式以为例,统一解析成以秒为单位的秒。

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的时间加/减一个偏移量。

    关于作者

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

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/85934.html

    相关文章

    • 卡拉OK歌词原理和实现高仿Android网易云音乐

      摘要:大家好,我们是爱学啊,继上一篇讲解了歌词原理和实现高仿网易云音乐,今天给大家带来一篇关于卡拉歌词原理和在上如何实现歌词逐字滚动的效果,本文来自开发项目实战我的云音乐课程。 大家好,我们是爱学啊,继上一篇讲解了【LRC歌词原理和实现高仿Android网易云音乐】,今天给大家带来一篇关于卡拉OK歌词原理和在Android上如何实现歌词逐字滚动的效果,本文来自【Android开发项目实战我的...

      bluesky 评论0 收藏0
    • 用 TS + Vue 重写 APlayer HTML5 音乐播放器

      摘要:简介是一款简洁漂亮的音乐播放器在我第一次看到这款播放器颜值的时候让我眼前一亮,我非常崇拜那些能设计出好看界面的设计师但是在用过之后发现还是有不足的地方这是我曾经提过的用了一段时间,很喜欢简洁的,提一些其他可改进的建议我认为有必要提供动态管理 简介 @DIYgod/APlayer 是一款简洁漂亮的 HTML5 音乐播放器 (〃ノωノ) 在我第一次看到这款播放器颜值的时候让我眼前一亮,我...

      BingqiChen 评论0 收藏0

    发表评论

    0条评论

    最新活动
    阅读需要支付1元查看
    <