打算用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自带服务器】

HTTP/1.1 200 OKContent-Type: audio/mpegserver: IntelliJ IDEA 14.1.7date: Thu, 02 Feb 2017 12:03:10 GMTX-Frame-Options: SameOriginX-Content-Type-Options: nosniffx-xss-protection: 1; mode=blockcache-control: private, must-revalidatelast-modified: Sat, 28 Jan 2017 14:37:02 GMTcontent-length: 3694385

【hfs服务器】

HTTP/1.1 200 OKContent-Type: application/octet-streamContent-Length: 3694385Accept-Ranges: bytesServer: HFS 2.3dLast-Modified: Sat, 28 Jan 2017 14:37:02 GMTContent-Disposition: attachment; filename="%CB%B3%C1%F7%B6%F8%CF%C2 - %D5%C5%F6%A6%D3%B1 %CD%F2%BC%D2%C3%FA.mp3";

一会儿再试一下tomcat和nginx。QQ号码拍卖地图后面有发现的话再更新这个答案。

刚正好遇到这个问题,错误发生在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中有更详细的描述:

Handle HTTP 1.1 byte range requests correctly

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.

以上,
第一次在segmentfault回答问题,如有错漏,欢迎指正。

请问你解决这个问题了吗?我尝试了很多办法,没找到原因。但是发现可能跟router有关,我用的symfony框架,如果是简单的本地文件不会出现这种情况,一到symfony体系里面就不行,求解

video currentTime属性无效果问题
视频地址不能带IP
http://127.0.0.1:8080/smallScreen/file/video/test2.Ogg:错误
http://localhost:8080/smallScreen/file/video/test2.Ogg:正确

同问,怎么解决啊


更多相关文章

  1. 【前端】新手使用uikit-幻灯片,但是在播放时图片会闪烁,检查了半天
  2. 在您自己的 PC 机上建立 PHP
  3. PHP 服务器组件和变量
  4. 电商直播发展正夯,搭建电商网站需要怎样的云服务器配置?
  5. 云服务器的操作系统一般怎么选?选错了可以重装吗?
  6. 研招网崩了?网络崩溃的原因有哪些?怎么维护网站?
  7. 不安全的HTTP方法
  8. 浏览器输入域名网址访问后的过程详解
  9. 服务器4块sas硬盘组成raid5扩容导致的数据丢失如何恢复

随机推荐

  1. eclipse的dx问题
  2. Android 笔记
  3. Settings.System 和 SystemProperties
  4. Android初级教程_onKeyDown监听返回键无
  5. android中的handler
  6. Android AIDL使用
  7. Android 如何获取keyboard和TP消息 分享
  8. 升级Android(安卓)Sdk Tools时遇到Failed
  9. Android常用屏幕适配方式
  10. Android(安卓)SDK版本号和名称对应表