您的位置:首页 > Web前端 > HTML5

html5 audio实现歌词同步

2015-09-11 17:02 525 查看
audio标签用于播放音频文件,很不幸,歌词文件并没有相应接口

addTextTrack() 向音频添加新的文本轨道。//各大浏览器都没有支持

有两种方法可以实现歌词同步:

1. 使用setInterval();

2. 监听timeupdate

两种方法,个人觉得都不是很完美,暂时找不到更好的方法

function media(dom,src){
this.dom = dom;
this.src = src;
this.audio = this.dom.getElementsByTagName('audio')[0];
this.control = $(this.dom).find(".control")[0];
this.lyrbox = $(this.dom).find(".lyrics")[0];
this.timer = this.dom.getElementsByTagName('span')[0];
this.timepoint = $(this.dom).find(".time-point")[0];
this.timebardiv = $(this.dom).find('.time-bar div')[0];
this.formatlyr = [];
this.intval = null;
this.init();

formattime = function(t){
var min = parseInt(t/60);
var ss = parseInt(t)%60 ;
ss = ss>9?ss:"0"+ss;
return min+":"+ss;
}
}
media.prototype.init = function() {
var self = this;
self.dom.style["background"] = "url("+self.src.img+") no-repeat";
self.dom.style["background-size"] = "100% 100%";
self.audio.src = self.src.mp3;
self.audio.autoplay = true;
self.lyr();

self.audio.addEventListener("canplay",function(){
self.timer.innerHTML = formattime(0)+ "/"+ formattime(self.audio.duration) ;
self.control.style.display="block";
// self.control.style["transition"]="all 4s;"

// self.audio.autoplay = true;

self.audio.play();
if(self.intval) self.intval = null;
self.intval = setInterval(function(){
var len = self.formatlyr.length;
var _c = self.audio.currentTime;
var p =$(self.lyrbox).find('p')
for(var i=0;i<p.length;i++){
if(p[i].style['color'] != ''){
p[i].style['color'] = '';
break;
}
}
for(var i=0;i<len;i++){
var _t = i?self.formatlyr[i-1][0]:0;
var _t1 =i<len-1? self.formatlyr[i+1][0] :9999;
if(_c >= _t && _c < _t1){
self.lyrbox.getElementsByTagName('p')[i].style['color'] = "#1D94E1";
$(self.lyrbox).css("transform","translateY(-"+(i?i-1:0)*32+"px)").css("transition-duration","0.5s");

break;
}
}

var a=_c/self.audio.duration * (self.timebardiv.clientWidth - self.timepoint.clientWidth) ;

$(self.timepoint).css("transform","translateX("+parseInt(a) +"px)");
self.timer.innerHTML = formattime(self.audio.currentTime)+ "/"+ formattime(self.audio.duration) ;
},1000) ;
});

self.ctrltime();
self.togglepause();
self.audio.canplay = function(){
alert('canplay');

}

};

media.prototype.togglepause = function() {
var self = this;
$(".ctrl-pause ").on('click',function(){
$this = $(this).find('a');
if($this.hasClass("play")){
$this.addClass("pause");
$this.removeClass("play");
self.audio.pause();
}else if($this.hasClass("pause")){
$this.removeClass("pause");
$this.addClass("play");
self.audio.play();
}else{

}
});
};

media.prototype.lyr = function() {
var self = this;

function parselyr(d){
var lines = d.split("\n"),pattern=/\[\d{2}:\d{2}.\d{2}\]/g,_l=[];
var fg = document.createDocumentFragment();
lines.forEach(function(i){
if(i.match(pattern)){
_l.push(i);
}
});

_l.forEach(function(i,index){
var s1 = i.split(']'),s2 = s1[0].slice(1),s3 = s2.split(':');
var second  = parseInt(s3[0])*60 + parseFloat(s3[1]);
var p = document.createElement('p');
p.innerHTML = s1[1];
fg.appendChild(p);
self.formatlyr.push([second,s1[1]]);

});

self.lyrbox.appendChild(fg);
}

$.get(this.src.lyrics,function(data){
parselyr(data);
});
};

media.prototype.ctrltime = function() {
// body...
var self =this;

self.timebardiv.addEventListener('click',function(e){
var dx = e.pageX - this.offsetLeft;
var ct= parseInt(self.audio.duration*dx/this.clientWidth);
self.audio.currentTime = ct;
},false);

};

$(document).ready(function(){

var m = new media(document.getElementById('playerbox'),sources[0]);
});


只在firefox chorme&& android测试

注意理解canplay事件,这个事件可能会多次触发。例如当你设置currentTime的时候,

也会触发canplay事件,这个不好解释 :(

第二种方法也差不多。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: