非常奇怪的错误我似乎无法弄明白。
我正在尝试在用户点击播放时从某个位置播放HTML5视频。我试图让它在视频开始播放时正确寻找。
在我的游戏活动中,我this.currentTime = X
在浏览器上它运行正常。但是在iPad上,当我播放视频时,视频没有寻找正确的位置(从零开始)。
更奇怪的是,如果我在setTimeout中执行this.currentTime = X
调用,比方说1秒,它可以在IPad上工作(有时)。
答案 0 :(得分: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 :(得分:3)
虽然这个问题已经很久了,但问题依然存在。我发现了一个适用于iOS 5和6(iOS3 + 4未经测试)的多个经过测试的iPad(1 + 2 + 3)的解决方案:
基本上,您首先必须等待初始playing
事件,然后为canplaythrough
添加一次性活页夹,然后为progress
添加 - 只有这样才能实际更改currentTime
{1}}价值。在此之前的任何尝试都将失败!
视频必须首先开始播放,这使得视频元素顶部的黑色层有点方便。很遗憾,视频中的声音无法通过JavaScript停用 - >不是一个完美的用户体验
// 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
下载答案 2 :(得分: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));
}
}
}
答案 3 :(得分:-2)
尝试将X
限制为1小数
X.toFixed(1);
正如您所提到的,它有时会在1秒后发挥作用。您是否尝试在playing
事件触发后设置位置?甚至可能是canplaythrough
事件
查看this page的来源,查看可以使用的整个事件列表(在javascript文件中)
答案 4 :(得分:-2)
欣赏以下答案的尝试。不幸的是,如果当前时间是>那么不得不求助于在timeupdate内部进行检查。 0和< 1,如果它然后转到视频的那一部分并将听众移除到timeupdate。