在iPad上播放HTML5视频并搜索

Playing HTML5 Video on IPad and seeking

本文关键字:视频 搜索 HTML5 播放 iPad      更新时间:2023-09-26

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

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

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

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

更奇怪的是,如果我在设定的超时时间内进行this.currentTime = X调用,比如说 1 秒,它可以在 iPad 上运行(有时)。

在 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);
}

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

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

基本上,您首先必须等待初始playing事件,然后为canplaythrough添加一次性绑定器,然后为progress添加绑定程序 - 只有这样才能实际更改currentTime值。在此之前的任何尝试都将失败!

视频

必须首先开始播放,这使得视频元素顶部的黑色层有点方便。不幸的是,视频中的声音不能通过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();
        }
    });
}

整个事情可以从我的GitHub存储库下载

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));
        }
    }
}

感谢下面对答案的尝试。不幸的是,不得不求助于在 timeupdate 内部检查当前时间是否> 0 和 <1,如果它随后转到视频的该部分并删除了 timeupdate 的听众。

尝试将X限制为1个小数

X.toFixed(1);

正如您提到的,它有时会在 1 秒后工作。您是否尝试过在playing事件触发后设置位置?甚至可能是canplaythrough事件

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