检测移动Safari何时停止播放视频,因为第二个视频开始播放

时间:2014-05-11 11:16:17

标签: javascript html5-video mobile-safari

Mobile Safari只允许您play one audio or video stream at a time

  

多个同步音频或视频流

     

目前,运行iOS的所有设备仅限于播放单个设备   音频或视频流随时可用。播放多个视频端   边,部分重叠或完全覆盖 - 目前不是   iOS设备支持。

如果您播放第二个视频,则第一个视频停止。我需要检测何时发生这种情况,以便我可以在视频旁边的播放按钮中淡入淡出,我也想将其重置为第一帧,因为在动画片中间留下它看起来很糟糕。

不幸的是,当视频被强制停止时,<video>元素似乎没有触发'已结束'或'暂停'事件。

 $('video').off('ended pause').on('ended paused', function ()
 {
     alert('ended');   // don't get here except when the video naturally ends
 }

我似乎无法找到与“强制停止”相对应的任何其他事件。 (See Apple events for HTMLMediaElement

我是否必须自己完成此操作并在我的视频中添加.playing课程并在播放第二个视频时进行检查?如果我控制页面上的每个视频,这是可行的,但只要我在那里粘贴YouTube视频,它就变得复杂得多。任何更好的解决方案

2 个答案:

答案 0 :(得分:2)

这个解决方案感觉有点hackish但是如果Safari移动浏览器在视频停止时没有抛出事件,那么剩下的选项就不多了 -

要检测视频是否已停止,我们可以先确保脚本知道视频播放的时间,因此:

var isPlaying1 = false,
    isPlaying2 = false, // if more videos an array is better to use, or reuse
    lastTime1 = 0,
    lastTime2 = 0;      // etc.

$('video1').on('playing', function() {
    isPlaying1 = true;
});

$('video1').on('ended', function() {
    isPlaying1 = false;
});

这会在视频开始时设置播放标记。也可以使用ended事件,将其设置为false,以防它播放到最后或手动停止。

下一步是轮询播放视频的当前时间,看它是否发生变化。如果没有更改,则表示视频未播放(并且未被结束事件捕获):

function check() {

    if (isPlaying1) {
        var video = $('video1')[0];
        if (video.currentTime === lastTime1) {
            // video has stopped
            isPlaying1 = false;
            video.currentTime = lastTime1 = 0; //reset time
        }
        else {
            lastTime1 = video.currentTime;
        }
    }
}

var timerID = setInterval(check, 1000/15);  // start check

检查率不应高于30 fps。这是因为时间戳不会从对应于从一帧到另一帧的时间对应的时间戳改变。为了安全起见,使用一半的速率,例如最高已知帧率(视频很少超过美国的30 fps或欧洲的25 fps)。如果您知道视频将以较低的费率播放,则最低费率应为此处的值。它也可以降低以减少负载。

要停止检查,只需致电:

clearInterval(timerID); // timerID is in global scope

您可能会在结束事件和检查之间遇到竞争条件(因为两者都会产生异步行为)。如果重要取决于你如何处理这两种情况。

如上所述,感觉&#34; hackish&#34;,我没有经过测试(只是因为我目前无法为它设置完整的测试环境),但希望它会帮助您解决Safari移动浏览器的这种限制。

答案 1 :(得分:2)

如果事件仅在播放另一个视频时才会触发,那么当我们播放视频时,我们只需触发正在播放的所有其他视频的ended事件即可。要跟踪播放视频,我们可以使用附加到video对象的javascript属性。像

这样的东西
$("video").on("ended",function(){
    this.playing=false
    this.currentTime=0
    console.log(this.src+" has ended")
})


$("video").on("play",function(){
    var that=this
    this.playing=true //video that is playing is "playing"
    $("video").each(function(i,o){
        if(o.playing && !$(o).is($(that)) ){ //for all the other "playing" video
          o.pause()
          $(o).trigger("ended")
        }
    })

})

Example(在iPad mini上测试)

另一方面,这也适用于可能不太理想的桌面浏览器。对于嵌入在同一页面中的YouTube视频,我们可以使用Youtube's API。 API使用postMessage相互通信,因此我在播放YouTube视频时使用下面的代码来停止视频标记。

window.addEventListener('message',function(event) {
    //probably should check origin
    var data=JSON.parse(event.data)
    if(data.info && 
     ( data.info.playerState == 1   //buffering
       || data.info.playerState == 3 )){ //or playing
        $("video").each(function (i, o) {
            if(o.playing){
              o.pause()
              $(o).trigger("ended")
            }
        })
    }
},false);

Example