BaiDu Mp3歌词同步功能实现

特点:采用2.0 java+xml技术加载 歌词,并且 歌词根据词曲滚动,并自动把正在演唱的 歌词加重显示

前几天偶然发现百度 MP3的试听歌曲可以 实现 歌词动态滚动,看了下源文件,呵呵,而且Only For IE。

主要是一个JS函数来 实现这个效果,代码如下:

[code]
function lrcInterface(pID,lrcID)
{
    var tmpOutput=document.getElementById('LrcShower');
    var count=0;
    tmpOutput.innerHTML="<br><br><br><br><br><br><span style='font-size:12px;margin-left:12px'> 正在加载 歌词信息,请您稍等片刻....";
    var tmp=setInterval(getObject,200);
function getObject()
{
    bdLRC=new bdSyncLRC();
    if(bdLRC!=null)
    {
        clearInterval(tmp);
        bdLRC.setPlayer(pID);
        bdLRC.setURL(lrcID);
        bdLRC.setOutput("LrcShower");
        bdLRC.Exchange();
        bdLRC.begin();
    };
    else
    {
        if(count==25)
        {
            clearInterval(tmp);
            tmpOutput.innerHTML="<br><br><br><br><br><br><span style='font-size:12px;margin-left:12px'> 可能是因为网络的原因,系统没有找到合适的 歌词。请稍后重试";
        };
        else count++;
    };
};
};
function bdSyncLRC()
{
    var playerObj=null;
    var playerTypeStr=null;
    var lrcURL="";
    var lrcShower="";
    var lrcContent="";
    var lrcObjArray=new Array();
    this.preLRC=new Array();
    this.offsetTime=0;
    this.scrollMoveLen=20;
    if(arguments.length>=1)this.setPlayer(arguments[0]);
    if(arguments.length>=2)this.setURL(arguments[1]);
    if(arguments.length>=3)this.setOutput(arguments[2]);
};
bdSyncLRC.prototype.setPlayer=function()
{
    if(arguments.length>=1)
    {
        arg=arguments[0];
        playerTypeStr=String(arg);
        if(typeof(arg)=="string")this.playerObj=document.getElementById(arg);
        else if(typeof(arg)=="object")this.playerObj=arg;
    };
};
bdSyncLRC.prototype.getPlayer=function()
{
    if(typeof(document.getElementById("this.playerObj"))=='object')return this.playerObj;
    else return null;
};
bdSyncLRC.prototype.setURL=function()
{
    if(arguments.length>=1)
    {
        var lrcDir,lrcFileName;
        lrcDir=String(Math.floor((parseInt(arguments[0])/100)));
        lrcFileName=arguments[0]+".lrc";
        this.lrcURL="/bdlrc/"+lrcDir+"/"+lrcFileName;
    };
};
bdSyncLRC.prototype.getURL=function()
{
    return this.lrcURL;
};
bdSyncLRC.prototype.setContent=function()
{
    if(arguments.length>=1)this.lrcContent=arguments[0];
};
bdSyncLRC.prototype.getContent=function()
{
    return this.lrcContent;
};
bdSyncLRC.prototype.setLRC=function()
{
    if(arguments.length>=1)this.lrcObjArray=arguments[0];
};
bdSyncLRC.prototype.getLRC=function()
{
    return this.lrcObjArray;
};
bdSyncLRC.prototype.setOutput=function(showerId)
{
    this.lrcShower=showerId;
};
bdSyncLRC.prototype.getOutput=function()
{
    if(this.lrcShower!="")
    {
        arg=this.lrcShower;
        if(typeof(arg)=="string")return document.getElementById(arg);
        else if(typeof(arg)=="object")return arg;
    };
    return null;
};
bdSyncLRC.prototype.multiLRC=function(lrcLine)
{
    thisObj=this;
    tmpVar=lrcLine.split("]");
    if(tmpVar.length>=2)
    {
        lrcText=tmpVar[tmpVar.length-1];
        for(j=0;j<tmpVar.length-1;j++)
        {
            lrcTime=tmpVar[j]+"]";
            thisObj.preLRC.push(lrcTime+""+lrcText);
        };
    };
};
bdSyncLRC.prototype.preSyncLRC=function()
{
    if(this.getContent()==null||this.getContent()=="")return;
    lrcLines=this.getContent().split("/n");
    tmpArr=new Array();
    for(i=0;i<lrcLines.length;i++)this.multiLRC(replaceStr(lrcLines));
    this.preLRC.sort();
    var tmpVar="aaa";
    for(i=this.preLRC.length-1;i>=0;i--)if(this.preLRC==tmpVar)
    {
        tmpVar=this.preLRC;
        this.preLRC.splice(i,1);
    };
    else tmpVar=this.preLRC;
    preTime=0;
    indexLRC=1;
    tmpArr[0]=new LRCItem(0,"");
    for(i=0;i<this.preLRC.length;i++)
    {
        if(this.preLRC.length>9)
        {
            tmpTime=getLyrcTime(this.preLRC);
            tmpLrc=getLyrc(this.preLRC);
            if(tmpTime<preTime)continue;
            preTime=tmpTime;
            var tmpItem=new LRCItem(tmpTime,tmpLrc);
            tmpArr[indexLRC++]=tmpItem;
        };
    };
    var tmpItem=new LRCItem(3600,"Over...");
    tmpArr[indexLRC]=tmpItem;
    this.setLRC(tmpArr);
};
function replaceStr(tmpStr)
{
    return tmpStr.replace(/^/s*|/s*$/g,"");
};
function getLyrc(tmpStr)
{
    try
    {
        tmpArray=tmpStr.split("]");
        return tmpArray[tmpArray.length-1];
    }
    catch(e)
    {
    };
    return"";
};
function getLyrcTime(tmpStr)
{
    try
    {
        tmpChar=tmpStr.split("]")[0].split("[")[1];
        tmpVar=tmpChar.split(":");
        if(tmpVar.length<2)return 0;
        min=tmpVar[1].split(".")[0];
        tmpInt=parseInt(tmpVar[0])*60+parseFloat(min);
        if(!isNaN(tmpInt))return tmpInt;
    }
    catch(e)
    {
    };
    return 0;
};
function LRCItem()
{
    var lrcTime=-1;
    var lrcContent="";
    if(arguments.length>=2)
    {
        this.lrcTime=arguments[0];
        this.lrcContent=arguments[1];
    };
};
bdSyncLRC.prototype.Exchange=function()
{
    var xmlhttp=null;
    if(window.XMLHttpRequest)
    {
        xmlhttp=new XMLHttpRequest();
    };
    else
    {
        if(window.ActiveXObject)
        {
            try
            {
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (ee)
            {
                xmlhttp=new ActiveXObject("MSXML.XMLHTTP");
            };
        };
    };
    var tmpURL=this.getURL();
    thisObj=this;
    var tmpStr="";
    try
    {
        xmlhttp.open("GET",tmpURL,false);
        xmlhttp.onreadystatechange=function()
        {
            if((xmlhttp.readyState==4)&&(xmlhttp.status==200))
            {
                tmpStr=bdBytes2Str(xmlhttp.responseBody);
                thisObj.setContent(tmpStr);
            };
        };
        xmlhttp.send(null);
    }
    catch(ee)
    {
    };
};
bdSyncLRC.prototype.begin=function()
{
    thisObj=this;
    tmpPlayerObj=thisObj.getPlayer();
    var tmpOutput=document.getElementById('LrcShower');
    var tmpI=setInterval(getlrc,100);
    var count=0;
function getlrc()
{
    if(typeof(thisObj.getContent())!="undefined")
    {
        clearInterval(tmpI);
        thisObj.preSyncLRC();
        var tmp,i,tmpArray;
        tmpArray=thisObj.getLRC();
        tmp="<br>"+"<br>"+"<br>"+"<br>"+"<br>"+"<br>"+"<br>";
        for(i=0;i<tmpArray.length;i++)tmp+="<span style='font-size:12px;margin-left:12px'> <font color=#000000>"+replaceStr(tmpArray.lrcContent)+"</font></span><br>";
        thisObj.getOutput().innerHTML=tmp;
        getPlayingTime(thisObj.getPlayer(),thisObj);
    };
    else
    {
        if(count==50)
        {
            clearInterval(tmpI);
            tmpOutput.innerHTML="<br><br><br><br><br><br><span style='font-size:12px;margin-left:12px'> 可能是因为网络的原因,系统没有找到合适的 歌词。请稍后重试";
        };
        else count++;
    };
};
};
function getPlayingTime(playerObj,bdLRCObj)
{
    try
    {
        tmpbdLRCObj=bdLRCObj;
        var tmpPlayerObj=playerObj;
        if(typeof(tmpPlayerObj)=="string")tmpPlayerObj=document.getElementById(tmpPlayerObj);
        window.setTimeout("getPlayingTime(tmpPlayerObj,tmpbdLRCObj)",1000);
        bdsyncLyrc(tmpbdLRCObj);
    }
    catch(e)
    {
        document.title="getPlayingTime..."+e.toString();
    };
};
var preMatchLrcLine=-1;
function bdsyncLyrc(bdLRCObj)
{
    try
    {
        tmpPlayer=bdLRCObj.getPlayer();
        if(playerTypeStr=="MediaPlayer1")playerStatus=tmpPlayer.PlayState;
        else playerStatus=tmpPlayer.GetPlayState();
        if(playerStatus!=2&&playerTypeStr=="MediaPlayer1")return;
        if(tmpPlayer)
        {
            if(playerTypeStr=="MediaPlayer1")currentTime=tmpPlayer.CurrentPosition;
            else        currentTime=tmpPlayer.GetPosition()/1000;
            bdLRCObj.preSyncLRC();
            tmpLrcs=bdLRCObj.getLRC();
            tmpScroll=bdLRCObj.getOutput();
            tmpScrollId=bdLRCObj.getOutput();
            perLength=bdLRCObj.scrollMoveLen;
            var tmpLrcContent=new Array(20);
            var color=new Array(21);
            var lineCount=new Array(tmpLrcs.length);
            var perLineCount=new Array(tmpLrcs.length);
            var i;
            for(i=0;i<tmpLrcs.length;i++)
            {
                lineCount=Math.floor(tmpLrcs.lrcContent.length/67);
                perLineCount=0;
                for(j=0;j<i;j++)perLineCount+=lineCount[j];
            };
            color[0]="#000000";
            color[1]="#0d0500";
            color[2]="#1a0a00";
            color[3]="#270f00";
            color[4]="#341400";
            color[5]="#411900";
            color[6]="#4e1e00";
            color[7]="#5b2300";
            color[8]="#682800";
            color[9]="#752d00";
            color[10]="#823200";
            color[11]="#8f3700";
            color[12]="#9c3c00";
            color[13]="#a94100";
            color[14]="#b64600";
            color[15]="#c34b00";
            color[16]="#d05000";
            color[17]="#dd5500";
            color[18]="#ea5a00";
            color[19]="#f75f00";
            color[20]="#ff5a00";
            for(i=0;i<20;i++)tmpLrcContent="<br>"+"<br>"+"<br>"+"<br>"+"<br>"+"<br>"+"<br>";
            var tmpMatchLrcLine=0;
            for(j=0;j<tmpLrcs.length;j++)
            {
                nowLrc=tmpLrcs[j];
                nextLrc=tmpLrcs[(j<tmpLrcs.length-1)?j+1:j];
                nowTime=nowLrc.lrcTime+bdLRCObj.offsetTime;
                nextTime=nextLrc.lrcTime+bdLRCObj.offsetTime;
                if(nowTime<=currentTime&&currentTime<nextTime)
                {
                    tmpMatchLrcLine=j;
                    for(i=0;i<20;i++)tmpLrcContent+="<span style='font-weight:bold;font-size:12px;margin-left:12px'> <font color="+color[i+1]+">"+replaceStr(tmpLrcs[j].lrcContent)+"</font></span><br>";
                    j+=1;
                    tmpInt=tmpLrcs.length-j;
                    for(;j<tmpLrcs.length;j++)for(i=0;
                    i<20;
                    i++)tmpLrcContent+="<span style='font-size:12px;margin-left:12px'> <font color=#000000>"+replaceStr(tmpLrcs[j].lrcContent)+"</font></span><br>";
                    if(tmpInt<8)for(j=0;
                    j<=8-tmpInt;
                    j++)for(i=0;
                    i<20;
                    i++)tmpLrcContent+="<span style='font-size:12px;margin-left:12px'> <font color=#000000></font></span><br>";
                    break;
                };
                else
                {
                    if(j==preMatchLrcLine)for(i=0;
                    i<20;
                    i++)tmpLrcContent+="<span style='font-size:12px;margin-left:12px'> <font color="+color[19-i]+">"+replaceStr(tmpLrcs[j].lrcContent)+"</font></span><br>";
                    else for(i=0;i<20;i++)tmpLrcContent+="<span style='font-size:12px;margin-left:12px'> <font color=#000000>"+replaceStr(tmpLrcs[j].lrcContent)+"</font></span><br>";
                };
            };
            if(preMatchLrcLine!=tmpMatchLrcLine)
            {
                if(Math.abs(tmpMatchLrcLine-preMatchLrcLine)>1)
                {
                    tmpScroll.innerHTML=tmpLrcContent[19];
                    tmpScrollId.scrollTop=(tmpMatchLrcLine+perLineCount[tmpMatchLrcLine]+1)*perLength;
                    tmpScrollId.scrollTop=(tmpMatchLrcLine+perLineCount[tmpMatchLrcLine]+1)*perLength;
                };
                else
                {
                    var count=0;
function scrollAdd()
{
    tmpScroll.innerHTML=tmpLrcContent[19];
    tmpScrollId.scrollTop+=2*(1+lineCount[preMatchLrcLine]);
    count++;
    if(count==10)clearInterval(loaderInterval);
};
var loaderInterval=setInterval(scrollAdd,25);
};
};
preMatchLrcLine=tmpMatchLrcLine;
};
}
catch(e)
{
document.title="bdsyncLyrc="+e.toString();
};
};

[/code]
还有一个VBScript函数,供上面函数中调用,用来解决乱码问题

<br>
[code]
<SCRIPT language=VBScript>
Function bdBytes2Str(vIn)
        strReturn = ""
        For i = 1 To LenB(vIn)
ThisCharCode = AscB(MidB(vIn,i,1))
               If ThisCharCode < &H80 Then
          strReturn = strReturn & Chr(ThisCharCode)
               Else
          NextCharCode = AscB(MidB(vIn,i+1,1))
          strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))
        i = i + 1
               End If
           Next
    bdBytes2Str = strReturn
        End Function
</SCRIPT>
[/code] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值