打算用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);
};
}
}
})
高洛峰2017-04-17 11:39:11
Thanks to user just_do_it_5811fcecc2979 for the tip. I found that this problem is indeed related to the server.
Specifically, when I use the server that comes with Intellij IDEA (i.e. IDEA directly opens the html file, move the mouse to the upper right area of the editor, a horizontal bar with several browser icons will appear, click on the chrome icon, it will use The file server that comes with IDEA is opened with chrome (the port is 63342). When dragging the progress bar under chrome, there will be a problem of jumping to the beginning 0S and replaying. However, it is normal when using IE11.
Then I tried another hfs server (Http file server, it is a software, not a new server like tomcat apache nginx, I just have this software to try), and dragging under chrome was completely normal. So I guess the reason is related to the server, specifically it may be related to the http response header when downloading mp3 files . The following is the response header of the above two servers:
[IDEA’s own server]
HTTP/1.1 200 OK
Content-Type: audio/mpeg
server: IntelliJ IDEA 14.1.7
date: Thu, 02 Feb 2017 12:03:10 GMT
X-Frame-Options: SameOrigin
X-Content-Type-Options: nosniff
x-xss-protection: 1; mode=block
cache-control: private, must-revalidate
last-modified: Sat, 28 Jan 2017 14:37:02 GMT
content-length: 3694385
【hfs server】
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 3694385
Accept-Ranges: bytes
Server: HFS 2.3d
Last-Modified: Sat, 28 Jan 2017 14:37:02 GMT
Content-Disposition: attachment; filename="%CB%B3%C1%F7%B6%F8%CF%C2 - %D5%C5%F6%A6%D3%B1 %CD%F2%BC%D2%C3%FA.mp3";
Try tomcat and nginx again later. I will update this answer if I find anything later.
阿神2017-04-17 11:39:11
Have you solved this problem? I tried many ways but couldn't find the reason. But I found that it may have something to do with the router. The symfony framework I use will not cause this problem if it is a simple local file. Once it is in the symfony system, it will not work. Please solve it
高洛峰2017-04-17 11:39:11
I just encountered this problem. The error occurred when idea's own server was playing local audio, and the soundmanager automatically reset to zero when it setPosition.
It is verified that it is related to the response header. I verified it by setting different response header
for MP3 resources, and the results are as follows (it seems that segmentfault does not support markdown tables, so the layout below is a bit messy.):
ieContent-Type
Must, when I set it to < It can only be played when 🎜> is set, but cannot be played when set to audio/mpeg
. application/octet-stream
Must. It has nothing to do with Content-Length
. Accept-Ranges
is irrelevant, set to Content-Type
to play. application/octet-stream
, Content-Length
must both be present to change currentTime. Accept-Ranges
, Content-Type
. Content-Length
Chrome requires
and Content-Length
in the header. (Not tested on Firefox) Accept-Ranges
Handle HTTP 1.1 byte range requests correctlyAbove,In order to support seeking and playing back regions of the media that aren't yet downloaded, Gecko uses HTTP 1.1 byte-range requests to retrieve the media from the seek target position. In addition, Gecko uses byte-range requests to seek to the end of the media (assuming you serve the Content-Length header) in order to determine the duration of the media.
Your server should accept the Accept-Ranges: bytes HTTP header if it can accept byte-range requests. It must return 206: Partial content to all byte range requests; otherwise, browsers can't be sure you actually support byte range requests.
Your server must also return "206: Partial Content" for the request "Range: bytes=0-" as well.
...
This is my first time answering a question on segmentfault. If there are any mistakes, please correct me.