打算用audio自己做个播放器,需要用audio标签的currentTime属性,来控制播放进度。但是这个属性在FireFox及ie11下都有效,但就是在chrome下面,设置了无效,不知道各位大神知道原因吗?
代码如下:
.directive('mediaPlayer',function(mediaPlayerConfig,$interval,$timeout){
return {
restrict:'EA',
templateUrl:'template/player.html',
scope:{
playList:'='
},
controller:function($scope){
var player=this;
var conf=mediaPlayerConfig;
var playList=$scope.playList||[];
var $audio,isPlaying=false;
var timer=null;
var index=0;
var audioLike={
currentTime:0,
duration:0,
volume:0
};
player.initialize=function(){
$scope.audioLike=audioLike;
audioLike.volume=$audio.volume;
player.play(index)
};
player.setAudio=function(element){
$audio=element[0];
player._bindEvents(element);
};
player.play=function(file){
var idx;
if(angular.isNumber(file)){
idx=file;
file=playList[idx];
}
if(file){
$audio.src=file[conf.fileUrlProp];
$scope.currentFile=file;
}
$interval.cancel(timer);
timer=$interval(function(){
audioLike.currentTime=$audio.currentTime.toFixed(0);
},1000);
$audio.play();
isPlaying=true;
};
player.pause=function(){
$audio.pause();
isPlaying=false;
$interval.cancel(timer);
};
//播放上一首,如果已经是第一首,则跳到最后一首
player.prev=function(){
index=index===0?
playList.length-1:
index-1;
player.play(index);
};
//播放下一首,如果已经是最后一首,则跳到第一首
player.next=function(){
index=index===(playList.length-1)?
0:
index+1;
player.play(index);
};
player.skipTo=function(sec){
$audio.currentTime=sec;
};
player.togglePlay=function(){
var method=isPlaying?'pause':'play';
player[method]();
};
player.isPlay=function(){
return isPlaying;
};
player.random=function(){
var min=0;
var max=playList.length-1;
var range=max-min;
var rand=Math.random();
rand=min + Math.round(rand * range);
player.play(rand);
};
player._bindEvents=function(element){
element
.on('canplay',function(e){
$scope.$apply(function(){
audioLike.duration=$audio.duration.toFixed(0);
});
})
.on('ended',function(){
//如果允许循环
if(conf.loop){
}
if(conf.random){
player.random();
return;
}
$scope.$apply(function(){
player.next();
});
})
.on('progress',function(e){
console.log(e);
});
};
player.volume=function(volume){
if(angular.isNumber(volume)){
$audio.volume=volume;
}else{
return $audio.volume;
}
};
},
link:function(scope,element,attr,mediaPlayerCtrl){
mediaPlayerCtrl.initialize();
scope.skipTo=function(){
mediaPlayerCtrl.skipTo(250);
};
}
}
})
多謝用戶just_do_it_5811fcecc2979的提示,我發現這個問題確實是和伺服器有關的。
具體來說,我用Intellij IDEA自帶的伺服器時(即IDEA直接打開html文件,滑鼠移到編輯器的右上區域,出現一個有若干瀏覽器圖標的橫條,點擊chrome圖標,會使用idea自備的檔案伺服器用chrome打開,連接埠是63342),在chrome下拖曳進度條也會出現跳到開頭0S重新播放的問題,用IE11卻正常。
然後我試了另外一個hfs伺服器(Http file server,是一個軟體,並不是tomcat apache nginx之類的一個新的伺服器,正好有這個軟體順便試試看),chrome下拖曳完全正常。所以猜測原因是跟伺服器有關,具體來說可能是下載mp3檔時的http response header有關。下面是以上兩種伺服器的response header:
【IDEA自帶伺服器】
【hfs伺服器】
一會兒再試一下tomcat和nginx。後面有發現的話再更新這個答案。
請問你解決這個問題了嗎?我嘗試了很多辦法,沒找到原因。但發現可能跟router有關,我用的symfony框架,如果是簡單的本地文件不會出現這種情況,一到symfony體系裡面就不行,求解
剛好遇到這個問題,錯誤發生在idea自帶server在播放本地音頻,soundmanager setPosition時自動歸零。
經驗證是和response header有關的。我透過對MP3資源set不同的
response header
來驗證,結果如下(貌似segmentfault不支援markdown的表格,所以下面排版有點亂。):ie
Content-Type
必須,當我設為audio/mpeg
時才能播放,設為application/octet-stream
不能。Content-Length
必須。和Accept-Ranges
無關。chrome
Content-Type
無關,設為application/octet-stream
可以播放。Content-Length
,Accept-Ranges
必須都有才可更改 currentTime。也就是說ie需要response header 有正確的
Content-Type
,Content-Length
。chrome需要頭部有
Content-Length
和Accept-Ranges
。 (Firefox沒測)還有,MDN上的Configuring servers for Ogg media中有更詳細的描述:
以上,
第一次在segmentfault回答問題,如有錯漏,歡迎指正。