HTML5 audio ,在chrome中设置currentTime无效
ringa_lee
ringa_lee 2017-04-17 11:37:11
0
3
1626

打算用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);
                        };
                    }
                }
            })
ringa_lee
ringa_lee

ringa_lee

全部回覆(3)
小葫芦

多謝用戶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 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伺服器】

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";

一會兒再試一下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-LengthAccept-Ranges必須都有才可更改 currentTime。

也就是說ie需要response header 有正確的Content-TypeContent-Length
chrome需要頭部有Content-LengthAccept-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 mediao from the seek target position. In adusedition, Geck 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, wsers can Part't be all byte range requests; otherwise, wsers can Part't be s can'sup sally s can'n wsperers can'sup sallys scann sup; requests.

Your server must also return "206: Partial Content" for the request "Range: bytes=0-" as well.
...

以上,
第一次在segmentfault回答問題,如有錯漏,歡迎指正。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板