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、1 回限りのバインダーを追加してから、実際に値を変更する必要があります。それより前の試行はすべて失敗します。canplaythroughprogresscurrentTime

ビデオは最初に再生を開始する必要があります。これにより、ビデオ要素の上に黒いレイヤーが少し便利になります。残念ながら、ビデオ内のサウンドは 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 リポジトリからダウンロードできます

于 2012-12-11T19:06:30.407 に答える
1

アプシラーズは正しいです。ビデオの再生が開始されると、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

以下の回答の試みに感謝します。残念ながら、currenttime が > 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 に答える