如何用js完美的解析lrc歌词
要想解析lrc,就得先知道lrc是什么,lrc是英文lyric(歌词)的缩写,基于纯文本的歌词专用格式,被用做歌词文件的扩展名。以lrc为扩展名的歌词文件可以在各类数码播放器中同步显示,最早是由郭祥祥先生(Djohan)提出并在其程序中得到应用。目前市场上的支持显示歌词的音乐播放器都有相同的规定,要求歌曲和LRC歌词的文件名相同,即:唐磊 - 丁香花.mp3,唐磊 - 丁香花.lrc。
除了lrc格式外,还有qrc(QQ音乐)、krc(酷狗)等,与lrc不同的是 它们的准确性 要 更强。lrc只能精确到每句歌词,而qrc 和 krc 能 精确到每一个字。(可以扩展lrc的 功能 使他精确到每一个字,以后再说)
lrc歌词文本中含有两类标签: 一是标识标签,其格式为“[标识名:值]”主要包含以下预定义的标签:
[ar:艺人名] [ti:曲名] [al:专辑名] [by:编者(指编辑LRC歌词的人)] [offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的。当用户听歌时,发现歌词快了几秒,可以调整歌词,最后此值被保存在 offset,下次播放时,将自动匹配正确时间。
二是时间标签,形式为“[mm:ss]”或“[mm:ss.ff]”(分钟数:秒数.毫秒数),时间标签需位于某行歌词中的句首部分,一行歌词可以包含多个时间标签(比如歌词中的迭句部分)。当歌曲播放到达某一时间点时,MP3就会寻找对应的时间标签并显示标签后面的歌词文本,这样就完成了“歌词同步”的功能。如以下歌词: [ti:有谁能够一夜之间长大] [ar:戊道子] [al:有谁能够一夜之间长大] [by:珍妮] 匹配时间为: 04 分 44 秒 的歌曲 [00:00]我爱歌词网 [www.5ilrc.com] [00:00.90]有谁能够一夜之间长大 - 戊道子 [00:07.10]词:[盘子] [00:10.99]曲:[陈绍楠] [00:13.11]编曲:[SEVEN] [00:16.76][00:17] [00:35.44][02:09]走去忘记 旧的人旧的自己 [00:42.60][02:16.16]远离回忆 找个人说我爱你 [00:49.79][02:23.22]别带着沉重去飞行 [00:53.31][02:26.68]别怀疑内心深处的勇气 [00:56.88][02:30.34]放纵地拥抱晨曦 [01:00.16][02:33.61]在路上遇见新的自己 [01:06.52][03:11.60]有谁能够一夜之间长大 [01:13.65][03:18.93]爱情碾过还能喘气就不算差 [01:20.73][03:25.99]何必羡慕那不凋败的塑料花 [01:27.66][03:32.96]没有花期不会枯萎 难道美吗 [01:34.76][03:40]尽情亲吻爱情留下的疤 [01:41.66][03:46.96]童话也不只是有水晶鞋和白马 [01:49.01][03:54.40]何必为了一段插曲哭到沙哑 [01:55.91][04:01.08]过程不留遗憾结果也就伟大 [04:13.18]Lrc By:珍妮 QQ:929964514
lrc的写法比较自由,上诉也可写成: 匹配时间为: 04 分 44 秒 的歌曲 [00:00]我爱歌词网 [www.5ilrc.com] [00:00.9]有谁能够一夜之间长大 - 戊道子 [00:07.1]词:[盘子] [00:10.99]曲:[陈绍楠] [00:13.11]编曲:[SEVEN] [00:16.76] [00:17] 这是一句废话,解析lrc的时候要过滤 [00:35.44][2:9]走去忘记 旧的人旧的自己[00:42.60][02:16.16]远离回忆 找个人说我爱你 [00:49.79][2:23.22]别带着沉重去飞行[00:53.31][02:26.68]别怀疑内心深处的勇气 [00:56.88][2:30.34]放纵地拥抱晨曦 [1:00.16][2:33.61]在路上遇见新的自己 [ar:戊道子] [al:有谁能够一夜之间长大][by:珍妮] [1:6.52][3:11.60]有谁能够一夜之间长大[01:13.65][03:18.93]爱情碾过还能喘气就不算差 [1:20.73][3:25.99]何必羡慕那不凋败的塑料花[01:27.66][03:32.96]没有花期不会枯萎 难道美吗 [01:34.76][03:40]尽情亲吻爱情留下的疤[01:41.66][03:46.96]童话也不只是有水晶鞋和白马 [ti:有谁能够一夜之间长大] [01:49.01][03:54.40]何必为了一段插曲哭到沙哑[01:55.91][04:01.08]过程不留遗憾结果也就伟大 [04:13.18]Lrc By:珍妮 QQ:929964514
可以看到,预定义标签被打散放进了歌词标签中间,[00:16.76] [00:17] 标签没有歌词,(你们肯定要说[00:17]标签下面不是有句废话么,但是他们中间隔了一个换行符,换行符表示结束,所以说下面那句是废话,解析lrc的时候要过滤掉)没有歌词的时间标签属于无意义的标签,也要去掉。在歌词开头也有一句废话,也要过滤掉。 [01:06:52]被写成了[1:6.52],[02:09]写成了[2:9],写法多种多样,解析lrc歌词的时候一定要注意。
下面直接贴代码(本程序能真正做到完美的解析lrc,并扩展lrc): 先新建一个html文件,记得引jquery
<div class="lyricPanel"></div>
在新建一个css文件:
最后加入以下js,运行便能看见效果:
var s = "[ti:有谁能够一夜之间长大]" + "[00:00]我爱歌词网 [www.5ilrc.com]"+ "[00:00.90]有谁能够一夜之间长大 - 戊道子"+ "[00:35.44][02:09]走去忘记 旧的人旧的自己"+ "[00:42.60][02:16.16]远离回忆 找个人说我爱你"+ "[00:49.79][02:23.22]别带着沉重去飞行"+ "[00:53.31][02:26.68]别怀疑内心深处的勇气"+ "[00:56.88][02:30.34]放纵地拥抱晨曦"+ "[01:00.16][02:33.61]在路上遇见新的自己"+ "[01:06.52][03:11.60]有谁能够一夜之间长大"+ "[01:13.65][03:18.93]爱情碾过还能喘气就不算差"+ "[01:20.73][03:25.99]何必羡慕那不凋败的塑料花"+ "[01:27.66][03:32.96]没有花期不会枯萎 难道美吗"+ "[01:34.76][03:40]尽情亲吻爱情留下的疤"+ "[01:41.66][03:46.96]童话也不只是有水晶鞋和白马"+ "[01:49.01][03:54.40]何必为了一段插曲哭到沙哑"+ "[01:55.91][04:01.08]过程不留遗憾结果也就伟大"+ "[04:13.18]Lrc By:珍妮 QQ:929964514"; if(typeof binlyric != 'object') {binlyric = {};} for(var j=0;j<this.index-1;j++) for(var i=0;i<this.index-1;i++) if(this.time[i]>this.time[i+1]) this.time[i] = this.time[i+1]; this.lyric[i] = this.lyric[i+1]; for(i=0;i<this.index;i++) $(this.obj).append("<div>"+this.lyric[i]+"</div>"); $(this.obj).find("div").css(this.lyricCSS,this.lyricCSS[i]); findTags:function(index,strArray,number){ number = number || this.txt.length; number = (number>this.txt.length) ? this.txt.length:number; var i,j,complete=0,value; for(i=index;i<number;i++) if(this.txt.substr(i,1)==strArray[complete].s) if(complete<strArray.length) obj.value += '{value:"'+this.txt.substr(value+1,i-value-1)+'"},'; obj.value += '{value:"'+this.txt.substr(value+1,i-value-1)+'"}]'; if(complete==strArray.length) obj.txt = this.txt.substr(index,i-index+1); obj.value = eval('('+obj.value+')'); else if(this.txt.substr(i,1)=="\n") else if(this.txt.substr(i,1)==strArray[0].s && complete>0) findlyric:function(index){ for(i=index;i<str.length;i++) var _obj = this.findTags(i,[{s:"["},{s:":"},{s:"]"}]); obj.lyric = str.substr(index,i-index); else if(str.charAt(i)=="\n") obj.lyric = str.substr(index,i-index); obj.lyric = str.substr(index,i-index); findTime:function(index){ var _obj = thisobj.findTime(obj.index); if(/\[\d{1,2}\:\d{1,2}\.\d{1,2}\]/.test(str.substr(index,10))) obj.time = str.substr(index+1,8) + "|"; else if(/\[\d{1,2}\:\d{1,2}\]/.test(str.substr(index,7))) obj.time = str.substr(index+1,5) + ".00" + "|"; obj = this.findTags(index,[{s:"["},{s:":"},{s:"]"}]); if(obj.value[0].value=="ar") this.ar = obj.value[1].value; else if(obj.value[0].value=="ti") this.ti = obj.value[1].value; else if(obj.value[0].value=="al") this.al = obj.value[1].value; else if(obj.value[0].value=="by") this.by = obj.value[1].value; else if(obj.value[0].value=="offset") this.offset = obj.value[1].value; if(this.txt=="") return false; for(var i=0;i<str.length;i++) var time = this.findTime(i); var lyric = this.findlyric(time.index); if(lyric.lyric!="\n" && lyric.lyric!="") var timeArray = time.time.split("|"); for(var j=0;j<timeArray.length;j++) this.time[this.index] = timeArray[j]; this.lyric[this.index] = lyric.lyric; play:function(position,CSS){ var height = parseInt($(obj.obj).find("div").css("height")); var top = parseInt($(obj.obj).find("div").css("margin-top")); scrollTop:(index*height+index*top-parseInt($(obj.obj).css("height"))/2+height/2) $(obj.obj).find("div").eq(index).css(CSS,CSS[i]); for(var i=0;i<this.index;i++) if(position==this.time[i]) else if(position>this.time[i]) binlyric.obj = ".lyricPanel"; binlyric.lyricCSS = {"font-size":"16px","margin-top":"15px","text-align":"center"}; binlyric.play("01:20.22",{ alert("艺人名:"+binlyric.ar); alert("专辑名:"+binlyric.al); alert("歌词编者:"+binlyric.by); alert("歌曲名:"+binlyric.ti);
发现上面有正则表达的地方 显示出问题了,大家直接下源码吧,源码上有注释。 源码下载地址:http://pan.baidu.com/s/1eRrKwHs 效果图:
原生js实现音乐播放器功能,可以实时显示歌词并且高亮当前句
最近在做项目,总结一下学到的知识, 首先就是一个简单的音乐播放器。可以显示歌词,并且突出显示当前播放的这一句。 但是歌词必须是要转码成utf-8的,不然是乱码,后面提供我淘到的转码工具,非常简单,把下载的lrc格式的歌词文件拖到这个软件上他就提醒你转码完毕,这时候就可以用了。 html,css,js我都放上去,js放到最后,前面两个我就不解释了,各位看官如果想直接看js就拖到最后吧。这是从项目里面提取的代码,用webpack,所以引用什么的就劳烦自己加上去~,具体功能请看html,有的功能还没有做,做了再更新,,,想了想代码还是放在github吧。。。代码有点长na~ 简单粗暴先看一下效果图。 一首分手快乐送给大家 我的资源页,不知道可不可以打开((/ □ ))传送门 本文属原创,转载请注明。
|