HTML5音乐播放器(五):同步显示歌词

好久没更新博客了,真是罪过,老偷懒,鄙视下自己,这两天把歌词同步显示的功能弄完了,先来说说原理:
1.ajax获取歌词文件(lrc文件)。
2.用正则分别去过滤出歌词和歌词前面对应的时间,存入数组。

[ti:很难]
[ar:张震岳]
[al:OK]
[by:]
[00:15.79]又一天的一个晴天
[00:19.07]阳光印在这张旧沙发
[00:22.96]躺下来 闭上眼
[00:25.11]恍然不知寂寞 枕着蔓延
.....
//获取歌词内容
lrcVal = xmlhttp.responseText.replace(/[dd:dd.dd]/g,"");
lrcArray = lrcVal.split("n");
//歌曲名
lrcArray[0].replace(/[ww:(.*?)]/g,function(){
    musicName = arguments[1] || "暂无";
});
//歌手
lrcArray[1].replace(/[ww:(.*?)]/g,function(){
    singer = arguments[1] || "暂无";
});
//获取歌词时间轴
xmlhttp.responseText.replace(/[(d*):(d*)([.|:]d*)]/g,function(){
    var min = arguments[1] | 0, //分
    sec = arguments[2] | 0, //秒
    realMin = min * 60 + sec; //计算总秒数
    lrcTimeArray.push(realMin);
});


3.将歌词的时间和内容遍历存入 HTML。

<p class="lrc-line" data-timeline="15">又一天的一个晴天</p>
<p class="lrc-line" data-timeline="19">阳光印在这张旧沙发</p>
<p class="lrc-line" data-timeline="22">躺下来 闭上眼</p>
<p class="lrc-line" data-timeline="25">恍然不知寂寞 枕着蔓延</p>
.....

4.每秒都去判断一下现在歌曲播放的时间,如果和临时数据 data-timeline 里的值一样,就滚动。

//---------------------------------------------------【计算歌词滚动】
function lrcMove(timeall,currenttime){
    //歌曲总时间 timeall
    //当前时间 currenttime
    var lrcBox = document.getElementById("lrcBox"),
        domList = lrcBox.getElementsByTagName("p"),
        timer,
        index,
        s,
        m = parseInt(lrcBox.style.marginTop.split("-")[1]) || 0;
    for(var i=0;i<domList.length;i++){
        //如果当前时间等于遍历的歌词的时间
        var dataTimeLine = parseInt(domList[i].attributes["data-timeLine"].nodeValue);
        //等到唱第一句歌词的时候再滚动
        if(dataTimeLine > 0 && dataTimeLine === parseInt(currenttime)){
            //当前歌词的下标
            index = i;
            //当前下标值和上次记录的下标值不同才滚动,一个下标值只滚动一次
            if(s != i){
                //记录下标值
                s = i;
                //歌词颜色变化
                for(var j=0;j<domList.length;j++){
                    removeClass(domList[j],"color");
                }
                if(index > 0){
                    addClass(domList[index],"color");
                }
                //歌词滚动
                clearInterval(timer);
                timer = setInterval(function(){
                    m += 1;
                    if(m >= index * 30){
                        clearInterval(timer);
                    }else{
                        lrcBox.style.marginTop = "-" + m + "px";
                    }
                },10);
            }
        }
    }
}

好了,原理呢,就是这4步,并不复杂,还有一个地方要注意,就是用户在调整歌曲的播放进度的时候,要快速跳转到对应时间的歌词,这个值要怎么找呢?我的办法是,跳转到时间数组里最后一个小于或等于它的数。

//---------------------------------------------------【调整歌曲播放进度后,歌词自动到位】
function lrcAtuoMove(time){
    var lrcBox = document.getElementById("lrcBox"),
        domList = lrcBox.getElementsByTagName("p"),
        songTime = parseInt(time),
        dataArr = [],
        MoveTime,
        e;
    //获取歌词时间数组
    for(var i=0;i<domList.length;i++){
        dataArr.push(domList[i].attributes["data-timeLine"].nodeValue);
    }
    //找到应该跳转的时间
    for(var j=0;j<dataArr.length;j++){
        //时间为数组里最后一个小于或等于它的数
        if(dataArr[j] > songTime){
            MoveTime = dataArr[j - 1];
            break;
        }
    }
    //找到下标index,跳转
    e = MoveTime ? dataArr.indexOf(MoveTime) : domList.length - 1;
    lrcBox.style.marginTop = "-" + parseInt(e) * 30 + "px";
    //歌曲颜色
    for(var k=0;k<domList.length;k++){
        removeClass(domList[k],"color");
    }
    if(e > 0){
        addClass(domList[e],"color");
    }
}

猛击demo ☻

发表评论

电子邮件地址不会被公开。 必填项已用*标注

8 thoughts on “HTML5音乐播放器(五):同步显示歌词

  1. 博主,有个问题想问一下,JS的正则里, 两位数字直接用dd就可以匹配到么?我记得d{2}这样才可以匹配到的啊