在iPad上播放HTML5视频并寻求

时间:2012-06-28 20:06:12

标签: javascript ios ipad html5 video

非常奇怪的错误我似乎无法弄明白。

我正在尝试在用户点击播放时从某个位置播放HTML5视频。我试图让它在视频开始播放时正确寻找。

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

在浏览器上它运行正常。但是在iPad上,当我播放视频时,视频没有寻找正确的位置(从零开始)。

更奇怪的是,如果我在setTimeout中执行this.currentTime = X调用,比方说1秒,它可以在IPad上工作(有时)。

5 个答案:

答案 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。