diff --git a/README.md b/README.md index 57d605e..414bc4a 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ ap.init(); ``` [mm:ss.xx]lyric [mm:ss.xx]lyric -[mm:ss.xx]lyric +[mm:ss.xx][mm:ss.xx][mm:ss.xx]lyric ... ``` @@ -107,6 +107,16 @@ ap.init(); [00:17.37]你要走吗 [00:23.20]易碎的 骄傲着 [00:28.75]那也曾是我的模样 + [00:34.55]沸腾着的 不安着的 + [00:40.26]你要去哪 + [00:46.00]谜一样的 沉默着的 + [00:51.75]故事你真的在听吗 + [00:56.25][03:25.78][04:10.64]我曾经跨过山和大海 + [00:59.55][03:28.14][04:13.54]也穿过人山人海 + [01:02.70][03:30.44]我曾经拥有着一切 + [01:05.00][03:33.69]转眼都飘散如烟 + [01:07.75][03:36.24]我曾经失落失望失掉所有方向 + [01:13.46][03:42.04]直到看见平凡才是唯一的答案 diff --git a/demo/index.html b/demo/index.html index e8280ab..ec68c93 100644 --- a/demo/index.html +++ b/demo/index.html @@ -70,24 +70,24 @@ [00:40.26]你要去哪 [00:46.00]谜一样的 沉默着的 [00:51.75]故事你真的在听吗 - [00:56.25]我曾经跨过山和大海 - [00:59.55]也穿过人山人海 - [01:02.70]我曾经拥有着一切 - [01:05.00]转眼都飘散如烟 - [01:07.75]我曾经失落失望失掉所有方向 - [01:13.46]直到看见平凡才是唯一的答案 + [00:56.25][03:25.78][04:10.64]我曾经跨过山和大海 + [00:59.55][03:28.14][04:13.54]也穿过人山人海 + [01:02.70][03:30.44]我曾经拥有着一切 + [01:05.00][03:33.69]转眼都飘散如烟 + [01:07.75][03:36.24]我曾经失落失望失掉所有方向 + [01:13.46][03:42.04]直到看见平凡才是唯一的答案 [01:31.70]当你仍然 [01:33.10]还在幻想 [01:37.40]你的明天 [01:43.00]她会好吗 还是更烂 [01:49.78]对我而言是另一天 - [01:53.33]我曾经毁了我的一切 - [01:56.54]只想永远地离开 - [01:59.82]我曾经堕入无边黑暗 - [02:02.14]想挣扎无法自拔 - [02:04.79]我曾经像你像他像那野草野花 - [02:10.54]绝望着 渴望着 - [02:13.54]也哭也笑平凡着 + [01:53.33][03:47.69]我曾经毁了我的一切 + [01:56.54][03:50.84]只想永远地离开 + [01:59.82][03:53.39]我曾经堕入无边黑暗 + [02:02.14][03:56.29]想挣扎无法自拔 + [02:04.79][03:59.04]我曾经像你像他像那野草野花 + [02:10.54][04:04.79]绝望着 渴望着 + [02:13.54][04:07.79]也哭也笑平凡着 [03:03.38]向前走 就这么走 [03:06.23]就算你被给过什么 [03:09.08]向前走 就这么走 @@ -96,20 +96,6 @@ [03:17.58]就算你会错过什么 [03:20.33]向前走 就这么走 [03:23.13]就算你会 - [03:25.78]我曾经跨过山和大海 - [03:28.14]也穿过人山人海 - [03:30.44]我曾经拥有着一切 - [03:33.69]转眼都飘散如烟 - [03:36.24]我曾经失落失望失掉所有方向 - [03:42.04]直到看见平凡才是唯一的答案 - [03:47.69]我曾经毁了我的一切 - [03:50.84]只想永远地离开 - [03:53.39]我曾经堕入无边黑暗 - [03:56.29]想挣扎无法自拔 - [03:59.04]我曾经像你像他像那野草野花 - [04:04.79]绝望着 渴望着 也哭也笑平凡着 - [04:10.64]我曾经跨过山和大海 - [04:13.54]也穿过人山人海 [04:16.14]我曾经问遍整个世界 [04:19.49]从来没得到答案 [04:22.88]我不过像你像他像那野草野花 diff --git a/dist/APlayer.min.js b/dist/APlayer.min.js index 7922ebd..28a7043 100644 --- a/dist/APlayer.min.js +++ b/dist/APlayer.min.js @@ -1 +1 @@ -function APlayer(e){if(!("music"in e&&"title"in e.music&&"author"in e.music&&"url"in e.music&&"pic"in e.music))throw"APlayer Error: Music, music.title, music.author, music.url, music.pic are required in options";if(null===e.element)throw"APlayer Error: element option null";this.isMobile=navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i),this.isMobile&&(e.autoplay=!1);var a={element:document.getElementsByClassName("aplayer")[0],narrow:!1,autoplay:!1,showlrc:!1};for(var t in a)a.hasOwnProperty(t)&&!e.hasOwnProperty(t)&&(e[t]=a[t]);this.option=e}APlayer.prototype.init=function(){function e(e){var a=e||window.event,i=(a.clientX-t(p.bar))/y;i=i>0?i:0,i=1>i?i:1,p.updateBar.call(p,"played",i,"width"),p.option.showlrc&&p.updateLrc.call(p,parseFloat(p.playedBar.style.width)/100*p.audio.duration),p.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=p.secondToTime(i*p.audio.duration)}function a(){document.removeEventListener("mouseup",a),document.removeEventListener("mousemove",e),p.audio.currentTime=parseFloat(p.playedBar.style.width)/100*p.audio.duration,p.play()}function t(e){for(var a,t=e.offsetLeft,i=e.offsetParent;null!==i;)t+=i.offsetLeft,i=i.offsetParent;return a=document.body.scrollLeft+document.documentElement.scrollLeft,t-a}function i(e){for(var a,t=e.offsetTop,i=e.offsetParent;null!==i;)t+=i.offsetTop,i=i.offsetParent;return a=document.body.scrollTop+document.documentElement.scrollTop,t-a}if(this.element=this.option.element,this.music=this.option.music,this.option.showlrc){this.lrcTime=[],this.lrcLine=[];for(var l=this.element.getElementsByClassName("aplayer-lrc-content")[0].innerHTML,s=l.split(/\n/),r=/\[(\d{2}):(\d{2})\.(\d{2})]/,n=/](.*)$/,o=/\[[A-Za-z]+:/,d=0;d
'+this.music.title+' - (>﹏<)加载中,好累的说...
- 00:00 / (o゚▽゚)
',this.option.showlrc){this.element.classList.add("aplayer-withlrc");var m="";for(this.lrcContents=this.element.getElementsByClassName("aplayer-lrc-contents")[0],d=0;d"+this.lrcLine[d]+"

";this.lrcContents.innerHTML=m,this.lrcIndex=0,this.lrcContents.getElementsByTagName("p")[0].classList.add("aplayer-lrc-current")}this.option.narrow&&this.element.classList.add("aplayer-narrow"),this.audio=document.createElement("audio"),this.audio.src=this.music.url,this.audio.loop=!0,this.audio.preload="metadata";var p=this;this.audio.addEventListener("durationchange",function(){1!==p.audio.duration&&(p.element.getElementsByClassName("aplayer-dtime")[0].innerHTML=p.secondToTime(p.audio.duration))}),this.audio.addEventListener("loadedmetadata",function(){p.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - "+p.music.author,p.loadedTime=setInterval(function(){var e=p.audio.buffered.end(p.audio.buffered.length-1)/p.audio.duration;p.updateBar.call(p,"loaded",e,"width"),1===e&&clearInterval(p.loadedTime)},500)}),this.audio.addEventListener("error",function(){p.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - 加载失败 ╥﹏╥"}),this.playButton=this.element.getElementsByClassName("aplayer-play")[0],this.pauseButton=this.element.getElementsByClassName("aplayer-pause")[0],this.playButton.addEventListener("click",function(){p.play.call(p)}),this.pauseButton.addEventListener("click",function(){p.pause.call(p)}),this.playedBar=this.element.getElementsByClassName("aplayer-played")[0],this.loadedBar=this.element.getElementsByClassName("aplayer-loaded")[0],this.thumb=this.element.getElementsByClassName("aplayer-thumb")[0],this.bar=this.element.getElementsByClassName("aplayer-bar")[0];var y;this.bar.addEventListener("click",function(e){var a=e||window.event;y=p.bar.clientWidth;var i=(a.clientX-t(p.bar))/y;p.updateBar.call(p,"played",i,"width"),p.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=p.secondToTime(i*p.audio.duration),p.audio.currentTime=parseFloat(p.playedBar.style.width)/100*p.audio.duration}),this.thumb.addEventListener("mousedown",function(){y=p.bar.clientWidth,clearInterval(p.playedTime),document.addEventListener("mousemove",e),document.addEventListener("mouseup",a)}),this.audio.volume=.8,this.volumeBar=this.element.getElementsByClassName("aplayer-volume")[0];var h=this.element.getElementsByClassName("aplayer-volume-bar")[0],v=p.element.getElementsByClassName("aplayer-time")[0].getElementsByTagName("i")[0],f=35;this.element.getElementsByClassName("aplayer-volume-bar-wrap")[0].addEventListener("click",function(e){var a=e||window.event,t=(f-a.clientY+i(h))/f;t=t>0?t:0,t=1>t?t:1,p.updateBar.call(p,"volume",t,"height"),p.audio.volume=t,p.audio.muted&&(p.audio.muted=!1),1===t?v.className="demo-icon aplayer-icon-volume-up":v.className="demo-icon aplayer-icon-volume-down"}),v.addEventListener("click",function(){p.audio.muted?(p.audio.muted=!1,v.className=1===p.audio.volume?"demo-icon aplayer-icon-volume-up":"demo-icon aplayer-icon-volume-down",p.updateBar.call(p,"volume",p.audio.volume,"height")):(p.audio.muted=!0,v.className="demo-icon aplayer-icon-volume-off",p.updateBar.call(p,"volume",0,"height"))}),this.option.autoplay&&this.play()},APlayer.prototype.play=function(){this.playButton.classList.add("aplayer-hide"),this.pauseButton.classList.remove("aplayer-hide"),this.audio.play();var e=this;this.playedTime=setInterval(function(){e.updateBar.call(e,"played",e.audio.currentTime/e.audio.duration,"width"),e.option.showlrc&&e.updateLrc.call(e),e.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=e.secondToTime(e.audio.currentTime)},100)},APlayer.prototype.pause=function(){this.pauseButton.classList.add("aplayer-hide"),this.playButton.classList.remove("aplayer-hide"),this.audio.pause(),clearInterval(this.playedTime)},APlayer.prototype.updateBar=function(e,a,t){a=a>0?a:0,a=1>a?a:1,this[e+"Bar"].style[t]=100*a+"%"},APlayer.prototype.updateLrc=function(e){if(e||(e=this.audio.currentTime),e=this.lrcTime[this.lrcIndex+1])for(var a=0;a=this.lrcTime[a]&&(!this.lrcTime[a+1]||ee?"0"+e:""+e},t=parseInt(e/60),i=parseInt(e-60*t);return a(t)+":"+a(i)}; \ No newline at end of file +function APlayer(e){if(!("music"in e&&"title"in e.music&&"author"in e.music&&"url"in e.music&&"pic"in e.music))throw"APlayer Error: Music, music.title, music.author, music.url, music.pic are required in options";if(null===e.element)throw"APlayer Error: element option null";this.isMobile=navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i),this.isMobile&&(e.autoplay=!1);var a={element:document.getElementsByClassName("aplayer")[0],narrow:!1,autoplay:!1,showlrc:!1};for(var t in a)a.hasOwnProperty(t)&&!e.hasOwnProperty(t)&&(e[t]=a[t]);this.option=e}APlayer.prototype.init=function(){function e(e){var a=e||window.event,l=(a.clientX-t(n.bar))/o;l=l>0?l:0,l=1>l?l:1,n.updateBar.call(n,"played",l,"width"),n.option.showlrc&&n.updateLrc.call(n,parseFloat(n.playedBar.style.width)/100*n.audio.duration),n.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=n.secondToTime(l*n.audio.duration)}function a(){document.removeEventListener("mouseup",a),document.removeEventListener("mousemove",e),n.audio.currentTime=parseFloat(n.playedBar.style.width)/100*n.audio.duration,n.play()}function t(e){for(var a,t=e.offsetLeft,l=e.offsetParent;null!==l;)t+=l.offsetLeft,l=l.offsetParent;return a=document.body.scrollLeft+document.documentElement.scrollLeft,t-a}function l(e){for(var a,t=e.offsetTop,l=e.offsetParent;null!==l;)t+=l.offsetTop,l=l.offsetParent;return a=document.body.scrollTop+document.documentElement.scrollTop,t-a}if(this.element=this.option.element,this.music=this.option.music,this.option.showlrc){var i=this.element.getElementsByClassName("aplayer-lrc-content")[0].innerHTML;this.lrc=this.parseLrc(i)}if(this.element.innerHTML='
'+this.music.title+' - (>﹏<)加载中,好累的说...
- 00:00 / (o゚▽゚)
',this.option.showlrc){this.element.classList.add("aplayer-withlrc");var s="";this.lrcContents=this.element.getElementsByClassName("aplayer-lrc-contents")[0];for(var r=0;r"+this.lrc[r][1]+"

";this.lrcContents.innerHTML=s,this.lrcIndex=0,this.lrcContents.getElementsByTagName("p")[0].classList.add("aplayer-lrc-current")}this.option.narrow&&this.element.classList.add("aplayer-narrow"),this.audio=document.createElement("audio"),this.audio.src=this.music.url,this.audio.loop=!0,this.audio.preload="metadata";var n=this;this.audio.addEventListener("durationchange",function(){1!==n.audio.duration&&(n.element.getElementsByClassName("aplayer-dtime")[0].innerHTML=n.secondToTime(n.audio.duration))}),this.audio.addEventListener("loadedmetadata",function(){n.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - "+n.music.author,n.loadedTime=setInterval(function(){var e=n.audio.buffered.end(n.audio.buffered.length-1)/n.audio.duration;n.updateBar.call(n,"loaded",e,"width"),1===e&&clearInterval(n.loadedTime)},500)}),this.audio.addEventListener("error",function(){n.element.getElementsByClassName("aplayer-author")[0].innerHTML=" - 加载失败 ╥﹏╥"}),this.playButton=this.element.getElementsByClassName("aplayer-play")[0],this.pauseButton=this.element.getElementsByClassName("aplayer-pause")[0],this.playButton.addEventListener("click",function(){n.play.call(n)}),this.pauseButton.addEventListener("click",function(){n.pause.call(n)}),this.playedBar=this.element.getElementsByClassName("aplayer-played")[0],this.loadedBar=this.element.getElementsByClassName("aplayer-loaded")[0],this.thumb=this.element.getElementsByClassName("aplayer-thumb")[0],this.bar=this.element.getElementsByClassName("aplayer-bar")[0];var o;this.bar.addEventListener("click",function(e){var a=e||window.event;o=n.bar.clientWidth;var l=(a.clientX-t(n.bar))/o;n.updateBar.call(n,"played",l,"width"),n.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=n.secondToTime(l*n.audio.duration),n.audio.currentTime=parseFloat(n.playedBar.style.width)/100*n.audio.duration}),this.thumb.addEventListener("mousedown",function(){o=n.bar.clientWidth,clearInterval(n.playedTime),document.addEventListener("mousemove",e),document.addEventListener("mouseup",a)}),this.audio.volume=.8,this.volumeBar=this.element.getElementsByClassName("aplayer-volume")[0];var d=this.element.getElementsByClassName("aplayer-volume-bar")[0],c=n.element.getElementsByClassName("aplayer-time")[0].getElementsByTagName("i")[0],u=35;this.element.getElementsByClassName("aplayer-volume-bar-wrap")[0].addEventListener("click",function(e){var a=e||window.event,t=(u-a.clientY+l(d))/u;t=t>0?t:0,t=1>t?t:1,n.updateBar.call(n,"volume",t,"height"),n.audio.volume=t,n.audio.muted&&(n.audio.muted=!1),1===t?c.className="demo-icon aplayer-icon-volume-up":c.className="demo-icon aplayer-icon-volume-down"}),c.addEventListener("click",function(){n.audio.muted?(n.audio.muted=!1,c.className=1===n.audio.volume?"demo-icon aplayer-icon-volume-up":"demo-icon aplayer-icon-volume-down",n.updateBar.call(n,"volume",n.audio.volume,"height")):(n.audio.muted=!0,c.className="demo-icon aplayer-icon-volume-off",n.updateBar.call(n,"volume",0,"height"))}),this.option.autoplay&&this.play()},APlayer.prototype.play=function(){this.playButton.classList.add("aplayer-hide"),this.pauseButton.classList.remove("aplayer-hide"),this.audio.play();var e=this;this.playedTime=setInterval(function(){e.updateBar.call(e,"played",e.audio.currentTime/e.audio.duration,"width"),e.option.showlrc&&e.updateLrc.call(e),e.element.getElementsByClassName("aplayer-ptime")[0].innerHTML=e.secondToTime(e.audio.currentTime)},100)},APlayer.prototype.pause=function(){this.pauseButton.classList.add("aplayer-hide"),this.playButton.classList.remove("aplayer-hide"),this.audio.pause(),clearInterval(this.playedTime)},APlayer.prototype.updateBar=function(e,a,t){a=a>0?a:0,a=1>a?a:1,this[e+"Bar"].style[t]=100*a+"%"},APlayer.prototype.updateLrc=function(e){if(e||(e=this.audio.currentTime),e=this.lrc[this.lrcIndex+1][0])for(var a=0;a=this.lrc[a][0]&&(!this.lrc[a+1]||ee?"0"+e:""+e},t=parseInt(e/60),l=parseInt(e-60*t);return a(t)+":"+a(l)},APlayer.prototype.parseLrc=function(e){for(var a=e.split("\n"),t=[],l=a.length,i=0;l>i;i++){var s=a[i].match(/\[(\d{2}):(\d{2})\.(\d{2})]/g),r=a[i].replace(/\[(\d{2}):(\d{2})\.(\d{2})]/g,"").replace(/^\s+|\s+$/g,"");if(null!=s)for(var n=s.length,o=0;n>o;o++){var d=/\[(\d{2}):(\d{2})\.(\d{2})]/.exec(s[o]),c=60*d[1]+parseInt(d[2])+parseInt(d[3])/100;t.push([c,r])}}return t.sort(function(e,a){return e[0]-a[0]}),t}; \ No newline at end of file diff --git a/src/APlayer.js b/src/APlayer.js index 4ba61a8..e84edbc 100644 --- a/src/APlayer.js +++ b/src/APlayer.js @@ -1,3 +1,10 @@ +/** + * APlayer constructor function + * + * @param {Object} option - See README + * @constructor + */ + function APlayer(option) { // handle options error if (!('music' in option && 'title' in option.music && 'author' in option.music && 'url' in option.music && 'pic' in option.music)) { @@ -29,31 +36,17 @@ function APlayer(option) { this.option = option; } +/** + * AutoLink initialization function + */ APlayer.prototype.init = function () { this.element = this.option.element; this.music = this.option.music; // parser lrc if (this.option.showlrc) { - this.lrcTime = []; - this.lrcLine = []; var lrcs = this.element.getElementsByClassName('aplayer-lrc-content')[0].innerHTML; - var lines = lrcs.split(/\n/); - var timeExp = /\[(\d{2}):(\d{2})\.(\d{2})]/; - var lrcExp = /](.*)$/; - var notLrcLineExp = /\[[A-Za-z]+:/; - for (var i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(/^\s+|\s+$/g, ''); - var oneTime = timeExp.exec(lines[i]); - var oneLrc = lrcExp.exec(lines[i]); - if (oneTime && oneLrc && !lrcExp.exec(oneLrc[1])) { - this.lrcTime.push(parseInt(oneTime[1]) * 60 + parseInt(oneTime[2]) + parseInt(oneTime[3]) / 100); - this.lrcLine.push(oneLrc[1]); - } - else if (lines[i] && !notLrcLineExp.exec(lines[i])) { - throw 'APlayer Error: lrc format error : should be like `[mm:ss.xx]lyric` : ' + lines[i]; - } - } + this.lrc = this.parseLrc(lrcs); } // fill in HTML @@ -103,8 +96,8 @@ APlayer.prototype.init = function () { this.element.classList.add('aplayer-withlrc'); var lrcHTML = ''; this.lrcContents = this.element.getElementsByClassName('aplayer-lrc-contents')[0]; - for (i = 0; i < this.lrcLine.length; i++) { - lrcHTML += '

' + this.lrcLine[i] + '

'; + for (var i = 0; i < this.lrc.length; i++) { + lrcHTML += '

' + this.lrc[i][1] + '

'; } this.lrcContents.innerHTML = lrcHTML; this.lrcIndex = 0; @@ -265,7 +258,9 @@ APlayer.prototype.init = function () { } }; -// play +/** + * Play music + */ APlayer.prototype.play = function () { this.playButton.classList.add('aplayer-hide'); this.pauseButton.classList.remove('aplayer-hide'); @@ -280,7 +275,9 @@ APlayer.prototype.play = function () { }, 100); }; -// pause +/** + * Pause music + */ APlayer.prototype.pause = function () { this.pauseButton.classList.add('aplayer-hide'); this.playButton.classList.remove('aplayer-hide'); @@ -288,21 +285,31 @@ APlayer.prototype.pause = function () { clearInterval(this.playedTime); }; -// update progress bar (loading progress bar, play progress bar) +/** + * Update progress bar, including loading progress bar and play progress bar + * + * @param {String} type - Point out which bar it is, should be played loaded or volume + * @param {Number} percentage + * @param {String} direction - Point out the direction of this bar, Should be height or width + */ APlayer.prototype.updateBar = function (type, percentage, direction) { percentage = percentage > 0 ? percentage : 0; percentage = percentage < 1 ? percentage : 1; this[type + 'Bar'].style[direction] = percentage * 100 + '%'; }; -// update lrc +/** + * Update lrc + * + * @param {Number} currentTime + */ APlayer.prototype.updateLrc = function (currentTime) { if (!currentTime) { currentTime = this.audio.currentTime; } - if (currentTime < this.lrcTime[this.lrcIndex] || currentTime >= this.lrcTime[this.lrcIndex + 1]) { - for (var i = 0; i < this.lrcTime.length; i++) { - if (currentTime >= this.lrcTime[i] && (!this.lrcTime[i + 1] || currentTime < this.lrcTime[i + 1])) { + if (currentTime < this.lrc[this.lrcIndex][0] || (!this.lrc[this.lrcIndex + 1] || currentTime >= this.lrc[this.lrcIndex + 1][0])) { + for (var i = 0; i < this.lrc.length; i++) { + if (currentTime >= this.lrc[i][0] && (!this.lrc[i + 1] || currentTime < this.lrc[i + 1][0])) { this.lrcIndex = i; this.lrcContents.style.transform = 'translateY(' + -this.lrcIndex * 20 + 'px)'; this.lrcContents.getElementsByClassName('aplayer-lrc-current')[0].classList.remove('aplayer-lrc-current'); @@ -312,7 +319,12 @@ APlayer.prototype.updateLrc = function (currentTime) { } }; -// format second to 00:00 +/** + * Parse second to 00:00 format + * + * @param {Number} second + * @return {String} 00:00 format + */ APlayer.prototype.secondToTime = function (second) { var add0 = function (num) { return num < 10 ? '0' + num : '' + num; @@ -320,4 +332,38 @@ APlayer.prototype.secondToTime = function (second) { var min = parseInt(second / 60); var sec = parseInt(second - min * 60); return add0(min) + ':' + add0(sec); +}; + +/** + * Parse lrc, suppose multiple time tag + * + * @param {String} text - Format: [mm:ss.xx][mm:ss.xx]lyric + * @return {Array} [[time, text], [time, text], [time, text], ...] + */ +APlayer.prototype.parseLrc = function (text) { + var lyric = text.split('\n'); + var lrc = []; + var lyricLen = lyric.length; + for (var i = 0; i < lyricLen; i++) { + // match lrc time + var lrcTimes = lyric[i].match(/\[(\d{2}):(\d{2})\.(\d{2})]/g); + // match lrc text + var lrcText = lyric[i].replace(/\[(\d{2}):(\d{2})\.(\d{2})]/g, '').replace(/^\s+|\s+$/g, ''); + + if (lrcTimes != null) { + // handle multiple time tag + var timeLen = lrcTimes.length; + for (var j = 0; j < timeLen; j++) { + var oneTime = /\[(\d{2}):(\d{2})\.(\d{2})]/.exec(lrcTimes[j]); + var lrcTime = (oneTime[1]) * 60 + parseInt(oneTime[2]) + parseInt(oneTime[3]) / 100; + lrc.push([lrcTime, lrcText]); + } + } + } + // sort by time + lrc.sort(function (a, b) { + return a[0] - b[0]; + }); + + return lrc; }; \ No newline at end of file