一次播放 HTML5 个视频的多个部分

Playing multiple fractions of HTML5 videos at a time

我正在尝试编写一个函数,它将采用 div 的 ID 并播放给定的视频,例如从 2/10 到 3/10 和 return 一个活动,这样我就可以做点别的了。

我对事件还不是很聪明,视频时长也不适合我,感谢任何帮助。我安装了 jQuery。

自上次以来有所改进... 已更新,接下来只需要监听器工作即可。

var finished_event = new Event('finished');

$(document).ready(function(){

    class Player {

        constructor(pos, vid, part, parts){
            this.pos = pos;
            this.vid = vid;
            this.part = part;
            this.parts = parts;
        }

        start(){
            var it = this;

            var html = '<video class="video-fit" controls>';
            html += '<source src="';
            html += it.vid;
            html += '" type="video/mp4">';
            html += '</video>';
            $(it.pos).html(html);

            var video = $(it.pos + ' video')[0];

            video.addEventListener('loadeddata', function(){

              var dur = video.duration;
              var fra = dur / it.parts;
              var beg = it.part * fra;
              var end = it.part * (fra + 1);
              video.currentTime = beg;
              video.play();

              video.addEventListener('timeupdate', function() {

                 if (video.currentTime >= end) {
                   video.pause();
                   this.dispatchEvent(finished_event);
                 }

              }, false);

            }, false);

            return it;
        }
    }

  $('body').click(function(){
    let player_1 = new Player('#pos-1', 'videos/576p.mp4', 5, 10);
    player_1.start();
    let player_2 = new Player('#pos-2', 'videos/576p.mp4', 5, 10);
    player_2.start();
    let player_3 = new Player('#pos-3', 'videos/576p.mp4', 5, 10);
    player_3.start();
    let player_4 = new Player('#pos-4', 'videos/576p.mp4', 5, 10);
    player_4.start();

    //.addEventListener('finished', function(){ console.log('Finished'); }, false)

  });

});

我建议你给视频加上一个唯一的id,我这里选择vpos-1/2/3/4/... 我从头到尾显示视频:

var html = '<video ' + 'id="v' + it.pos + '" class="video-fit">';
            html += '<source src="';
            html += it.vid;
            html += '" type="video/mp4">';
            html += '</video>';
            $(it.pos).html(html);

var video = document.getElementById('v' + it.pos);

$(video).bind('timeupdate', function() {
    if(video.currentTime > end){
       video.pause();
    }
});

$(video).on('play', function() {
    video.playbackRate = 1.0;
    //calcul the value of beg
    video.currentTime = beg;
    video.play();//suppress if you have autoplay
});

$(video).bind('ended', function() {
    // nothing yet      
});

如果你想自动播放and/or显示控件我建议你添加

controls="controls" autoplay

标记 video

如果您想删除视频:只需执行 src=''

停止视频并节省内存

timeupdate 事件多次触发,因此它可能会在 this.currentTime >= end 检查中触发多次。

不要过多更改您的代码,您需要设置播放 state/var 和 canplay 事件更改时间戳,然后播放,这反过来会触发 seeked 事件,然后您可以将视频设置为正在播放,然后在 timeupdate 上,检查您的时间以及视频是否正在播放..对于最后一个视频,您需要检查 ended 事件,因为它不会' t 输入您的支票 this.currentTime >= end 因为结束是 +1 秒。

然后为了将事件函数与 Player class 分开,id 将使用一个数组并观察它的变化,然后通过将函数推送到 array/stack,您可以在其中进行检查如果堆栈与视频长度匹配,则每次调用该函数时,假设您可以通过其他方式进行。

(function () {
  let video =
    'https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/twitter_cat.mp4';

  let videos = [
    { id: '#pos-1', video, part: 1, parts: 10 },
    { id: '#pos-2', video, part: 2, parts: 10 },
    { id: '#pos-3', video, part: 3, parts: 10 },
    { id: '#pos-4', video, part: 4, parts: 10 },
  ];

  const playqueue = [];
  Object.defineProperty(playqueue, 'push', {
    value: function (...args) {
      var arr = Array.prototype.push.apply(this, args)
      if (typeof args[0] === 'function') args[0]();
      return arr;
    }
  });

  function finished_event() {
    if (playqueue.length === videos.length) {
      console.log('Do something, all videos have stopped playing');
    }
  }

  function video_finished_event(player) {
    console.log(
      'Do something, ' + JSON.stringify(player) + ' has stopped playing'
    );

    playqueue.push(finished_event);
  }

  class Player {
    constructor(pos, vid, part, parts) {
      this.pos = pos;
      this.vid = vid;
      this.part = part;
      this.parts = parts;
    }

    start() {
      var it = this;

      var html = '<video class="video-fit" data-vid="' + it.pos + '" controls>';
      html += '<source src="';
      html += it.vid;
      html += '" type="video/mp4">';
      html += '</video>';
      $(it.pos).html(html);

      var video = $('[data-vid="' + it.pos + '"]')[0];

      video.addEventListener(
        'loadeddata',
        function () {
          var fra = video.duration / it.parts;
          var beg = it.part * fra;
          var end = it.part * (fra + 1);

          video.addEventListener('canplay', function () {
            if (!this.playing) {
              this.currentTime = beg;
              this.play();
            }
          });

          video.addEventListener('seeked', function () {
            this.playing = true;
          });

          video.addEventListener('timeupdate', function () {
            if (this.playing && this.currentTime >= end) {
              this.pause();
              this.playing = false;
              video_finished_event(it);
            }
          });

          video.addEventListener('ended', function () {
            if (this.playing) {
              this.pause();
              this.playing = false;
              video_finished_event(it);
            }
          })
        },
        false
      );

      return it;
    }
  }

  videos.forEach(video => {
    video.player = new Player(video.id, video.video, video.part, video.parts);
    video.player.start();
  });
})();
.videos div {
  display: inline-block;
  width: calc(25vw - 15px);
  height: 100%;
}

.videos div video {
  width: 100%;
  height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="videos">
  <div id="pos-1"></div>
  <div id="pos-2"></div>
  <div id="pos-3"></div>
  <div id="pos-4"></div>
</div>