2012-06-28 48 views
8

非常奇怪的錯誤,我似乎無法弄清楚。在iPad上播放HTML5視頻並尋求

我試圖讓用戶點擊播放時從某個位置播放HTML5視頻。我試圖在視頻開始播放時尋求正確的方式。

在我的表演事件我this.currentTime = X

在它工作正常的瀏覽器。但在iPad上,當我播放視頻時,視頻無法找到正確的位置(它從零開始)。

更奇怪的是,如果我在setTimeout中調用this.currentTime = X,比如說1秒,它可以在IPad(有時)上工作。

回答

-2

欣賞以下答案。不幸的是,如果當前時間> 0和< 1,則不得不求助於僅在時間更新內部進行檢查,如果該時間到達視頻的該部分並且將時間更新的監聽器移除。

-2

儘量限制你的X至小數點後1

X.toFixed(1); 

正如你提到的這1秒的時間後,有時工作。您是否嘗試在playing事件觸發後設置位置?或者甚至在canplaythrough事件

看看的this page源地看到,可以使用事件的整個列表(在JavaScript文件)

+0

已經嘗試過: - \。沒有骰子。 – K2xL

4

在iOS上,視頻負載at play time(見項目#2 ),而不是在頁面加載時。我的猜測是,當你運行this.currentTime = X時,視頻不會被加載,所以它不起作用。這也解釋了爲什麼拖延操作有時可以解決問題:有時它在一秒鐘後加載,有時不加載。

我沒有iOS設備進行測試,但我建議一個loadeddata監聽綁定到視頻讓您currentTime操作僅僅是視頻後會開始加載:

// within the play event handler... 
if(!isIOSDevice) { 
    this.currentTime = X; 
} else { 
    function trackTo(evt) { 
     evt.target.currentTime = X; 
     evt.target.removeEventListener("loadeddata", trackTo) 
    }); 
    this.addEventListener("loadeddata", trackTo); 
} 

你根據當前訪問是否來自iOS設備,需要在代碼的其他地方設置isIOSDevice

+1

哇。它確實工作。結束了使用爆米花庫(對於那些也使用爆米花js,聽loadeddata事件) – K2xL

+0

+1不錯,但簡潔的回答 – steveax

+0

@ K2xL太棒了,很高興你修好了!我更新了我的答案,按照你的建議使用'loadeddata'。 (事實證明'loadeddata'是一個標準的HTML5事件,不只是一個自定義的爆米花事件。) – apsillers

3

雖然這個問題很老,但問題仍然存在。我發現,在多個測試ipad公司(1 + 2 + 3)的iOS 5和6(IOS3 + 4未測試)工作的解決方案:

基本上首先必須等待初始playing事件,再加入一的時間綁定爲canplaythrough,然後爲progress - 只有這樣您才能實際更改currentTime值。之前的任何嘗試都會失敗!

視頻首先要開始播放,這使視頻元素頂部的黑色圖層更方便。不幸的是,聲音中的視頻無法通過JavaScript停用 - >不是一個完美的UX

// https://github.com/JoernBerkefeld/iOSvideoSeekOnLoad/MIT License 
// requires jQuery 1.8+ 
// seekToInitially (float) : video-time in seconds 
function loadingSeek(seekToInitially, callback) { 
    if("undefined"==typeof callback) { 
     callback = function() {}; 
    } 
    var video = $("video"), 
     video0 = video[0], 
     isiOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/) !== null, 
     test; 
    if(isiOS) { // get the iOS Version 
     test =navigator.userAgent.match("OS ([0-9]{1})_([0-9]{1})"); 
     // you could add a loading spinner and a black layer onPlay HERE to hide the video as it starts at 0:00 before seeking 
     // don't add it before or ppl will not click on the play button, thinking the player still needs to load 
    } 
    video.one("playing",function() { 
     if(seekToInitially > 0) { 
      //log("seekToInitially: "+seekToInitially); 
      if(isiOS) { 
       // iOS devices fire an error if currentTime is set before the video started playing 
       // this will only set the time on the first timeupdate after canplaythrough... everything else fails 
       video.one("canplaythrough",function() { 
        video.one("progress",function() { 
         video0.currentTime = seekToInitially; 
         video.one("seeked",function() { 
          // hide the loading spinner and the black layer HERE if you added one before 

          // optionally execute a callback function once seeking is done 
          callback(); 
         }); 
        }); 
       }); 
      } else { 
       // seek directly after play was executed for all other devices 
       video0.currentTime = seekToInitially; 

       // optionally execute a callback function once seeking is done 
       callback(); 
      } 
     } else { 
      // seek not necessary 

      // optionally execute a callback function once seeking is done 
      callback(); 
     } 
    }); 
} 

整個事情可以從my GitHub repo下載

1

apsillers是正確的。一旦視頻開始播放,Quicktime播放器就會出現,直到觸發第一個「進度」事件纔會搜索視頻。如果您在此之前嘗試尋找,則會出現無效的狀態錯誤。這是我的代碼:

cueVideo = function (video, pos) { 
    try { 
     video.currentTime = pos; 

    // Mobile Safari's quicktime player will error if this doesn't work. 
    } catch(error) { 
     if (error.code === 11) { // Invalid State Error 

      // once 'progress' happens, the video will be seekable. 
      $(video).one('progress', cueVideo.bind(this, video, pos)); 
     } 
    } 
}