8

非常奇怪的错误,我似乎无法弄清楚。

当用户点击播放时,我试图让 HTML5 视频从某个位置播放。我试图让它在视频开始播放时正确搜索。

在我的游戏活动中,我做this.currentTime = X

在浏览器上它工作正常。但是在 iPad 上,当我播放视频时,视频不会找到正确的位置(它从零开始)。

更奇怪的是,如果我this.currentTime = X在 1 秒的 setTimeout 中进行调用,它可以在 iPad 上运行(有时)。

4

5 回答 5

4

在 iOS 上,视频在播放时加载(参见第 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);
}

您需要isIOSDevice根据当前访问是否来自 iOS 设备,在代码中的其他位置进行设置。

于 2012-06-28T20:26:09.113 回答
3

虽然这个问题很老,但问题仍然存在。我发现了一个适用于 iOS 5 和 6(iOS3+4 未测试)的多个经过测试的 iPad (1+2+3) 的解决方案:

基本上,您首先必须等待初始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();
        }
    });
}

整个东西可以从我的 GitHub repo下载

于 2012-12-11T19:06:30.407 回答
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));
        }
    }
}
于 2013-09-29T08:46:13.917 回答
-1

感谢以下答案的尝试。不幸的是,如果当前时间 > 0 并且 < 1,则不得不求助于检查内部 timeupdate,如果它随后转到视频的那部分并删除了 timeupdate 的侦听器。

于 2012-06-29T17:29:26.400 回答
-2

尝试将您限制在X小数点后 1 位

X.toFixed(1);

正如您所提到的,它有时会在 1 秒后起作用。您是否尝试在playing事件触发后设置位置?或者甚至是canplaythrough事件

查看此页面的来源以查看可以使用的事件的完整列表(在 javascript 文件中)

于 2012-06-28T20:15:35.710 回答