2012-06-28 49 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)); 
     } 
    } 
}