javascript 解析 lrc 歌词

date
Aug 9, 2014
note
slug
js-lrc-parse
type
Post
status
Published
tags
技术
Web
summary
最近打算做播放器,研究了下解析lrc歌词的算法,百度基本没有现成的,所以自己各种搜索各种折腾然后写了个~~~特分享给大家
最近打算做播放器,研究了下解析lrc歌词的算法,百度基本没有现成的,所以自己各种搜索各种折腾然后写了个~~~特分享给大家
我们看到的lrc歌词一般都是这样的:
[ti:听妈妈的话] [ar:周杰伦] [al:] [by:] [04:20.31][04:19.10][03:36.65][03:14.96][02:13.35][01:53.08][01:30.43][00:51.06][00:31.01][00:09.00][00:00.00] [00:03.00]听妈妈的话 - 周杰伦 [00:06.00]词:周杰伦 曲:周杰伦 [00:10.33]小朋友 你是否有很多问号 [00:12.70]为什麼 别人在那看漫画 [00:15.25]我却在学画画 对着钢琴说话 [00:17.84]别人在玩游戏 我却靠在墙壁背我的ABC [00:21.00]我说我要一台大大的飞机 [00:23.59]但却得到一台旧旧录音机 [00:26.31]为什麼要听妈妈的话 [00:28.24]长大后你就会开始懂了这段话 [03:16.67][00:31.41]长大后我开始明白 [03:18.65][00:33.73]为什么我跑得比别人快 [03:20.49][00:35.35]飞得比别人高 [03:21.45][00:36.36]将来大家看的都是我画的漫画 [03:24.00][00:38.91]大家唱的都是我写的歌 [03:26.91][00:41.67]妈妈的辛苦不让你看见 [03:29.46][00:44.32]温暖的食谱在她心里面 [03:32.07][00:46.94]有空就多多握握她的手 [03:34.65][00:49.51]把手牵着一起梦游 [03:37.04][02:55.87][02:14.35][00:51.86]听妈妈的话 别让她受伤 [03:47.51][03:05.91][02:24.62][01:02.05]想快快长大 才能保护她 [02:34.99][01:12.39]美丽的白发 幸福中发芽 [04:08.20][02:45.31][01:22.71]天使的魔法 温暖中慈祥 [01:32.43]在你的未来 音乐是你的王牌 [01:34.95]拿王牌谈个恋爱 唉!我不想把你教坏 [01:37.98]还是听妈妈的话吧 晚点再恋爱吧 [01:40.83]我知道你未来的路 当妈比我更清楚 [01:43.76]你会开始学其他同学在书包写东写西 [01:46.28]但我建议你最好写妈妈我会用功读书 [01:48.79]用功读书 怎么会从我嘴巴说出 [01:51.46]不想你输 所以要叫你用功读书 [01:53.48]妈妈织给你的毛衣 你要好好的收着 [01:55.99]因为母亲节到时我要告诉她我还留着 [01:58.57]对了 我会遇到周润发 [02:00.45]所以你可以跟同学炫耀赌神未来是你爸爸 [02:03.63]我找不到童年写的情书 [02:05.55]你写完不要送人 [02:06.91]因为过两天你会在操场上捡到 [02:09.18]你会开始喜欢上流行歌 [02:11.35]因为张学友开始准备唱吻别 [03:58.07]美丽的白发 幸福总发芽
可以看到,歌词是由时间标签和歌词本身构成的,至于那些歌曲信息这些我就忽略了
大概思路是:
  1. 按行把歌词拆成数组
  1. 遍历这个数组,将每一行的歌词和时间标签一道转换为数组
遍历数组的每一次循环要干的事情:
  1. 用正则匹配出这行的时间标签和对应的歌词
  1. 以时间标签为单位,将标签转换为以秒为单位的时间再与该行对应的歌词一同push入数组
  1. 由于多时间标签的存在顺序会打乱,所以我们最后还要将保存歌词和时间的数组按时间从小到大排序
js代码如下:
function parseLyric(text) { //先按行分割 var lyric = text.split('\n'); //新建一个数组存放最后结果 lrc = new Array(); var _l = lyric.length; for(i=0;i<_l;i++) { //正则匹配播放时间返回一个数组 var sj = lyric[i].match(/\[\d{2}:\d{2}((\.|\:)\d{2})\]/g); //获得该行歌词正文 var _lrc = lyric[i].replace(/\[\d{2}:\d{2}((\.|\:)\d{2})\]/g,""); //过滤掉空行等非歌词正文部分 if(sj != null) { //可能有多个时间标签对应一句歌词的情况,用一个循环解决 var _ll = sj.length; for(j=0;j<_ll;j++){ var _s=sj[j]; var min = Number(String(_s.match(/\[\d{2}/i)).slice(1)); var sec = parseFloat(String(_s.match(/\d{2}\.\d{2}/i))); //换算时间,保留两位小数 var _t = Math.round((min * 60 + sec)*100)/100; //把时间和对应的歌词保存到数组 lrc.push([_t,_lrc]); } } } //重新按时间排序 lrc.sort(function(a,b){ return a[0]-b[0]; }); return lrc; }
 

© zgq354 2014 - 2024 | CC BY-NC-SA 4.0 | RSS