网上已经可以找到和歌词同步的不少方法,但是刚刚接触H5的小白,也想写上一些自己歌词同步时一些想法。我由于只考虑前端,所以就没有涉及服务器的问题了,浏览器本身请求本地文件比较严格,会出现如下错误
所以你就需要修改浏览器的相关配置,这里奉上链接
http://www.w3dev.cn/article/20141031/file-protocol-config-chrome-support-ajax-request.aspx
首先呢,我先附上自己做的网站,因为自己比较喜欢看霹雳布袋戏,所以我就用霹雳布袋戏的歌曲测试啦(哈哈,扯远啦),附上图
好的,看完了效果图,哈,知道自己做的水水的,不喜勿喷。
那么首先我们就是要先使用标签
<audio id="musicAudio" controls="controls" style="width:800px;" class="audioCss">
你的浏览器不兼容.
audio>
好的,使用了标签,那么现在我们就要开始导入歌单啦。
因为我想多复习下ajax,所以处理ajax的数据就比较多啦
首先是自动生成歌单,歌单文件名是music.xml内容如下
然后使用ajax处理数据,并且在网页上面生成歌单,同时给每个li加上点击事件,代码如下
$.ajax({
type:"GET",
url:"order/music.xml",
success: function(order){
var li = "";
$(order).find("music").each(function(){
var title = $(this).find("title").text();
var id = $(this).find("author").text();
li=li+"" +title+"";
});
$("#musicOl").append(li);
$("#musicOl li").each(function(){
$(this).mousemove(function(e){
if($(this).attr("key")!='yes')
$(this).css("color","black");
});
$(this).mouseout(function(e){
if($(this).attr("key")!='yes')
$(this).css("color","white");
});
});
}
});
值得一提的是mousemove和mouseout是我为了添加特效,所以才加上去的,不需要可以不用,还有就是我请求的文件是本地文件,编辑工具是sublime Text3。
然后就是获得歌词,这里的歌词文件是xx.lrc,而且要按照歌词文件的一般格式,如
然后我用的是javascript的ajax,代码如下
function ajaxMusic(obj){
$("li[id][key$='yes']").css("color","white").attr("key","no");
$("#"+obj.id).attr("key","yes").css("color","red");
var audio = document.getElementById("musicAudio");
audio.pause();
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==0){
audio.src = "music/"+obj.title+".mp3";
audio.play();
if(xmlhttp.responseText==''){
document.getElementById("musicText").innerHTML = "没有找到歌词
";
musicT.splice(0,musicT.length-1);
}
else{
xmltext = xmlhttp.responseText;
musicT = parseLyric(xmlhttp.responseText);
parseStart(musicT);
musicLrc(musicT);
}
}
}
xmlhttp.open("GET","lrc/"+obj.id+".lrc",true);
xmlhttp.send();
}
好的,我来解释一下其中
("li[id][key =’yes’]”).css(“color”,”white”).attr(“key”,”no”);
$(“#”+obj.id).attr(“key”,”yes”).css(“color”,”red”);
也是为了标注选择的歌曲目标特效罢了,可以不加。
对了,再说明一下,当javascript请求本地文件的时候,如果成功,xmlhttp.status = =0,
还有尽管你没有找到该文件名,浏览器会这样的错误
不过这没有关系啦,对于前端你无法知道服务器的东西,可是值得一提的是,由于没有找到文件,所以xmlhttp.responseText得到的值是”(空格)”,即xmlhttp.responseText==“(空格)”然后我们就可以根据空格来判断是否有歌词。
好的,然后你得到了歌词,那么你就必须对他进行处理,由于我是小白,所以想到的就是存储在二维数组上,代码和方法名如下:
function parseLyric(txt){
var lines = txt.split("\n");
var resy = new Array();
var j = lines.length-1;
for(var i=0;inew Array();
var line = lines[j].split("]");
var Tm = line[0].substring(1,line[0].length).split(":");
resy[i][0] = parseInt(Tm[0],10)*60+parseFloat(Tm[1]);
resy[i][1] = line[1];
j--;
}
return resy;
}
好的,当然啦,歌曲在没有播放前,总是要有一些歌词先显示出来,所以这里我就先截取前七行歌词,代码如下
function parseStart(resy){
var res = "";
var left=200,top=300;
var i = resy.length-1;
for(var j=0;j<7;j++){
res = res +""
+resy[i][1]+"
";
top=top+40;
i--;
}
document.getElementById("musicText").innerHTML=res;
return res;
}
其中top指的是离包含DIV的高度,之后就是重头戏,,你得到了处理后歌词数组,然后你就要与播放的歌曲同步,同步的方法就是根据歌次文件前面的时间与播放的当前时间做对比,代码如下
function musicLrc(result){
var audioEvent = document.getElementById("musicAudio");
var resText=document.getElementById("musicText");
var j =result.length-1,n = result.length-1;
var top = 300,isback = false;
var backtop = 300;
audioEvent.ontimeupdate =function(e){
if(result.length!=0){
console.log("result="+result[j][0]);
if(this.currentTime>result[j][0]){
currenttime=this.currentTime;
var ltop = $("#musicText p").last().css("top").split("px");
var Ntop = parseInt(ltop[0])+40;
if(j>=7&&j-7>=0){
$("#musicText").append(""
+result[j-7][1]+"
");
}
$("#musicText p").each(function(){
var lineTop=$(this).css("top").split("px");
$(this).css("top",(lineTop[0]-40)+"px");
$(this).css("color","black").css("font-size","200%");
if($(this).attr("key")==j){
$(this).css("color","red").css("font-size","300%");
}
});
j=j-1;
}
else {
if(this.currentTimeif(this.currentTime>1){
j++;
$("#musicText p").each(function(){
var lineTop=$(this).css("top").split("px");
$(this).css("top",(parseInt(lineTop[0])+40)+"px");
$(this).css("color","black").css("font-size","200%");
if($(this).attr("key")==j){
$(this).css("color","red").css("font-size","300%");
}
});
}
}
}
}
};
return ;
}
只需要和歌词进行对比,判断是否大于和小于,这样就可以实现快进和快退啦,还有值得一提的是我使用了currenttime这个全局变量来记录当前播发的时间,这样可以判断你是否是快退,快进还是切歌。怎么样是不是很简单呢?