瀏覽代碼

fixed audio player with safari

Bachir Soussi Chiadmi 6 年之前
父節點
當前提交
fff698433f

+ 31 - 8
sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js

@@ -749,7 +749,7 @@
       this.fid;
       this.audio = new Audio();
       // audio events
-      this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended","error"];
+      this.audio_events = ["loadedmetadata","playing","pause","timeupdate","ended","error"]; // ,"canplay"
 
       // UI dom objects
       this.$container   = $('<div id="audio-player">');
@@ -907,6 +907,8 @@
       setSRC(url){
         console.log('AudioPlayer setSRC : url', url);
         this.audio.src = url;
+        // need to trigger play right now to prevent safari blocking auto-play
+        this.play();
       },
       onLoadedmetadata(){
         var rem = parseInt(this.audio.duration, 10),
@@ -916,29 +918,50 @@
         this.updateLoadingBar();
       },
       updateLoadingBar(){
+        console.log("updateLoadingBar");
+
+        // var that = this;
         // if (this.audio.readyState === 4){
         if(this.audio.buffered.length>0){
+          // debugger;
           this.$loader.css({
             'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
           });
           if( this.audio.buffered.end(0) < this.audio.duration ){
             // loop through this function until file is fully loaded
-            var that = this;
-            window.requestAnimationFrame(that.updateLoadingBar.bind(that));
+            window.requestAnimationFrame(this.updateLoadingBar.bind(this));
           }else{
-            //console.log('Audio fully loaded');
+            console.log('Audio fully loaded');
           }
+        }else{
+          // as audio buffer is not ready, recall updateLoadingBar in next frame
+          window.requestAnimationFrame(this.updateLoadingBar.bind(this));
         }
       },
-      onCanplay(){
-        this.play();
-      },
+      // onCanplay(){
+      //   // this.play();
+      // },
       onError(){
         console.warn("Audio Error " + this.audio.error.code + "; details: " + this.audio.error.message);
       },
       play(){
         this.clearTimeOutToHide();
-        this.audio.play();
+        // this.audio.play();
+
+        // Not really needed has we trigger play right after setting the source https://stackoverflow.com/questions/47431439/mp4-video-safari-showing-unhandled-promise-rejection-object-domerror-in-c
+        var promise = this.audio.play();
+        // console.log('promise', promise);
+        if (promise !== undefined) {
+          promise.catch(error => {
+              // Auto-play was prevented
+              // Show a UI element to let the user manually start playback
+              console.warn('autoplay failed, ask for playing', error);
+
+          }).then(() => {
+              // Auto-play started
+              console.log('autoplay succeed');
+          });
+        }
       },
       playPrevious(){
         if(this.currentHistoricIndex > 0){

+ 31 - 8
sites/all/themes/custom/edlptheme/assets/scripts/main.js

@@ -749,7 +749,7 @@
       this.fid;
       this.audio = new Audio();
       // audio events
-      this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended","error"];
+      this.audio_events = ["loadedmetadata","playing","pause","timeupdate","ended","error"]; // ,"canplay"
 
       // UI dom objects
       this.$container   = $('<div id="audio-player">');
@@ -907,6 +907,8 @@
       setSRC(url){
         console.log('AudioPlayer setSRC : url', url);
         this.audio.src = url;
+        // need to trigger play right now to prevent safari blocking auto-play
+        this.play();
       },
       onLoadedmetadata(){
         var rem = parseInt(this.audio.duration, 10),
@@ -916,29 +918,50 @@
         this.updateLoadingBar();
       },
       updateLoadingBar(){
+        console.log("updateLoadingBar");
+
+        // var that = this;
         // if (this.audio.readyState === 4){
         if(this.audio.buffered.length>0){
+          // debugger;
           this.$loader.css({
             'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
           });
           if( this.audio.buffered.end(0) < this.audio.duration ){
             // loop through this function until file is fully loaded
-            var that = this;
-            window.requestAnimationFrame(that.updateLoadingBar.bind(that));
+            window.requestAnimationFrame(this.updateLoadingBar.bind(this));
           }else{
-            //console.log('Audio fully loaded');
+            console.log('Audio fully loaded');
           }
+        }else{
+          // as audio buffer is not ready, recall updateLoadingBar in next frame
+          window.requestAnimationFrame(this.updateLoadingBar.bind(this));
         }
       },
-      onCanplay(){
-        this.play();
-      },
+      // onCanplay(){
+      //   // this.play();
+      // },
       onError(){
         console.warn("Audio Error " + this.audio.error.code + "; details: " + this.audio.error.message);
       },
       play(){
         this.clearTimeOutToHide();
-        this.audio.play();
+        // this.audio.play();
+
+        // Not really needed has we trigger play right after setting the source https://stackoverflow.com/questions/47431439/mp4-video-safari-showing-unhandled-promise-rejection-object-domerror-in-c
+        var promise = this.audio.play();
+        // console.log('promise', promise);
+        if (promise !== undefined) {
+          promise.catch(error => {
+              // Auto-play was prevented
+              // Show a UI element to let the user manually start playback
+              console.warn('autoplay failed, ask for playing', error);
+
+          }).then(() => {
+              // Auto-play started
+              console.log('autoplay succeed');
+          });
+        }
       },
       playPrevious(){
         if(this.currentHistoricIndex > 0){