video同层级、禁用进度条等兼容问题

基于video.js使用问题

这些问题都是我项目遇到的,我项目是视频设置问题点, 用户观看时不能点击进度条快进,看过的可快进,遇到问题点会暂停弹出问题,回答正确才能继续观看,回答错误返回上一个问题的位置重新观看,并且要记录用户观看位置,下次进来提示 是否 要跳转到上次观看的位置,包括pc端和手机web端, 目前遇到最大问题就是测试移动端兼容问题,花了很多时间,稍作总结,总体可以。就是对于浏览器兼容效果还是不能全部兼容,因为video标签实在无解,后面也尝试换插件试试,比如西瓜播放器, 但是经过测试,也没有解决层级问题,我放弃了,下面总结少的,如有问题,多多交流。

下面问题是基于 video.js开发遇到的

1.禁用进度条

要求: 用户没看过的不许 点击或拖动 进度条快进, 已看过的部分 可以进行拖动或快进

pc端:

正常页面: 定时器 + 鼠标点击事件(多一个事件是为了防止用户一直点击有问题的那个点)

模拟器:只 用定时器 (监听窗口判断,模拟器就解绑鼠标事件,pc就再绑定)

移动端:

只用定时器就可以

// 1.绑定事件的处理
    // 点击进度条事件--绑定事件
   // 初始化时就绑定 
        window.owner.isBind = true;
        document
          .getElementsByClassName("vjs-progress-control")[0]
          .addEventListener("mousedown", window.owner.dot);

        document
          .getElementsByClassName("vjs-progress-holder")[0]
          .addEventListener("mousedown", window.owner.dot);
    
    dot() {
    
    
      window.owner.isSeek = true;// 标志跳转了
      window.owner.oldTime = this.player.getCache().currentTime; // 获得上一次点击 的时间(默认会缓存点击跳转前那个位置时间)
    },
 
      // 点击事件对应得监听 跳转 ,这个事件大约250ms执行一次
            that.on("timeupdate", function() {
    
    
          // 如果是点击进度条方式跳转到问题点的并且不是移动端模拟器的,这样禁止
          if (
            (that.currentTime() > window.owner.maxTime) &&
            window.owner.isSeek &&
            !window.owner.isMobile
          ) {
    
    
            that.currentTime(window.owner.oldTime); // 回到上一点
          } else {
    
    
          }
        }); 
        
// 2.定时器
     // 开启时刻 --在播放事件开启
      that.on("play", function() {
    
    
          window.owner.isSeek = false;
          // 开启进度条禁用定时器: 先清除再开启。保证每次只开一个
          clearInterval(window.owner.timeId1);
          window.owner.timeId1 = setInterval(window.owner.timer, 300);
        });

     // 定时器,判断用户是否快进或者拖动进度条
    timer() {
    
    
      let curTime = this.player.currentTime(); // 当前时间
      var apartTime = curTime - window.owner.oldTime; // 当前时间和 上次保存的时间差 ,两者差大于2代表是用户点击了 进度条 快进
      // 如果大于最长纪录时间并且不是教师预览,跳回原先学习的位置
      if (
        apartTime > 2 &&
        curTime > window.owner.maxTime &&
        !window.owner.isTeacherPreview
      ) {
    
    
        this.player.currentTime(window.owner.oldTime); // 重置回点击前位置
      } else {
    
    
        window.owner.oldTime = curTime; // 记录时间
        if (curTime > window.owner.maxTime) {
    
    
          window.owner.maxTime = curTime; // 记录最长时间
        }
      }
    },

// mounted 添加  监听窗口变化
window.onresize = function() {
    
    
      window.owner.isMobiles(); // 监听窗口变化,判断用户是否在pc端使用 调试模拟器打开页面
    };
    
   // 判断是否用户切换了浏览器的模拟器运行,是的话解绑事件,只用定时器
    isMobiles() {
    
    
      if (
        window.navigator.userAgent.match(
          /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
        )
      ) {
    
    
        window.owner.isMobile = true;
        if (window.owner.vData.isStudyDown != 1) {
    
    
          window.owner.isBind = false;
          document
            .getElementsByClassName("vjs-progress-control")[0]
            .removeEventListener("mousedown", window.owner.dot);

          document
            .getElementsByClassName("vjs-progress-holder")[0]
            .removeEventListener("mousedown", window.owner.dot);
        }
        console.log("移动端模拟器");
        return true; // 移动端
      } else {
    
    
        window.owner.isMobile = false;
        if (window.owner.vData.isStudyDown != 1 && !window.owner.isBind) {
    
    
          document
            .getElementsByClassName("vjs-progress-control")[0]
            .addEventListener("mousedown", window.owner.dot);

          document
            .getElementsByClassName("vjs-progress-holder")[0]
            .addEventListener("mousedown", window.owner.dot);
        }
        console.log("pc端");
        return false; // PC端
      }
    }

2.跳转播放问题

pc端:

这样就可以

this.player.currentTime(time); // 跳转

移动端:

移动端上面方法直接跳在 移动端浏览器支持不一致,qq、微信可以,但是 uc/qq浏览器就不行,我们需要先播放,初始化了视频再跳就没问题

解决:

设置一个标志位,在 timeupdate 监听跳转, 跳转前先播放视频

    // 跳转播放
    handleSkip() {
    
    
        clearInterval(window.owner.timeId1); // 先清除定时器
        window.owner.oldTime = Number.parseInt(this.vData.midVideoStudyLength);
       // this.player.currentTime(
         // Number.parseInt(this.vData.midVideoStudyLength)
        //); // 直接跳转,有些移动端浏览器跳转不了,比如qq浏览器...
        this.player.play(); // 播放
        this.skipFlag = true; // 设置可跳转
        this.showSkipToast = false;
        //   setTimeout(()=> { // 不建议使用定时器了,跳转会卡顿
        //   player.currentTime(ctime)
        // }, 500)
    },
        
        // 监听跳转和记录保存
           that.on("timeupdate", function() {
    
    
          let time = window.owner.getCurrentTime();
          localforage.setItem("videoLearnerTime", {
    
    
            midTime: time,
            maxTime: window.owner.maxTime
          }); // 保存记录
          // 跳转
          if (window.owner.skipFlag) {
    
    
            that.currentTime(
              Number.parseInt(window.owner.vData.midVideoStudyLength)
            );
            window.owner.skipFlag = false;// 跳转了设置false
          }
        });

对于跳转时间不准确问题,比如跳到2.5s会直接跳到3s,这里涉及到帧间距问题,大家可以百度一下这方面知识。

3.视频记录保存问题

pc和单页面移动端:

在组件销毁时调用保存api即可,不过还有一种情况,就是刷新和关掉页面时保存,这时候我采用的方法是监听页面卸载事件

1.页面销毁
beforeDestroy() {
    
    
    window.onbeforeunload = null;
    // 清除定时器
    this.showSkipToast = false;
    this.studyAll = false;
    clearTimeout(window.owner.timeId);
    clearInterval(window.owner.timeId1);
    let time = this.getCurrentTime();
    if (time > 0) {
    
     // 保存记录 保存当前时间和最大观看时间maxTime
      this.markVideoStudyLength(parseInt(time));
    }

    if (this.player) {
    
    
      this.player.dispose(); // //销毁video实例,避免出现节点不存在 但是flash一直在执行,也避免重新进入页面video未重新声明
    }
  },
      
 2.
// 页面卸载保存记录--针对pc端,移动端这样体验感不好
    window.onbeforeunload = function(e) {
    
    
      e = e || window.event;
      // 兼容IE8和Firefox 4之前的版本
      if (e) {
    
    
        e.returnValue = "关闭提示";
      }
      window.owner.isClose = true;
      let time = window.owner.getCurrentTime();

      if (time > 0) {
    
    
        window.owner.markVideoStudyLength(parseInt(time));
      }
      // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
      return "关闭提示";
    };

多页面移动端:

多页面形式,组件没有调用到destory函数, 所以不能在销毁时保存, 并且多页面跳到某个页面会重刷新页面,所以可以使用localstorage保存记录, 在timeupdate 中保存,然后再通过父组件生命周期函数中读取 localstorage的值进行保存(根据具体情况定在哪保存,这里只是提供思路,因为有的人组件调用方式不太一样)

4.video层级问题

video标签在某些浏览器中会被劫持,层级最高层,无法被覆盖,qq,微信,edge,safari没有这个问题,uc/qq浏览器(全屏时会有)等部分会有

这种情况就会影响到在视频播放过程弹出的 问题 弹框,被盖住了

解决思路:这个思路也只能大致解决了,因为只适配了qq,微信,edge,safari 这几个,其他真没办法

  1. 添加属性,设置支持x-h5内核的浏览器 同层,行内播放视频

  2. 通过隐藏元素标签,在遇到弹框时就设置 video标签的父标签 display:none, 弹框取消再设置回来block

     1. 
       <div
            class="video-player-container"
            ref="videoContainer"
            v-show="videoShow"
          >
           <video
              ref="videoPlayer"
              id="video_palyer"
              class="video-js vjs-default-skin vjs-big-play-centered "
              x5-video-player-type="h5" // 同层播放
              webkit-playsinline="true"
              playsinline="true" // 行内,不脱离文档流
              x-webkit-airplay="allow"
              x5-video-orientation="portrait" // 竖屏展示
              x5-video-player-fullscreen="true" 
            ></video>
        </div>
    2.
    
    

4.css一些样式设置

样式设置

// 暂停显示大按钮
::v-deep .vjs-paused .vjs-big-play-button,
::v-deep .vjs-paused.vjs-has-started .vjs-big-play-button {
    
    
  display: block;
  font-size: 3.5em;
}
// 正向播放,显示已播放时长
::v-deep .video-js .vjs-time-control {
    
    
  display: block;
}
::v-deep .video-js .vjs-remaining-time {
    
    
  display: none;
}
::v-deep .vjs-control-bar {
    
    
  font-size: 14px;
}
//5.暂停会出现黑边
给video标签加style=" outline:none"

5.一些事件执行顺序

一些事件触发顺序:

timeupdate这个只要视频播放,有改变播放时间都会触发,大概205ms执行一次

1.正常播放

play - timeupdate - pause

2.正常播放时点击进度条快进到另一个位置 (快退也一样过程)

播放时间改变–

暂停–pause
寻找中 --seeking
播放时间改变–timeupdate
寻找完毕–seeked
播放时间改变–timeupdate
播放时间改变–timeupdate
开始播放:–play

console.log打印过程:
播放时间改变:36.856077
v2.vue?9818:48 暂停 36.856077
v2.vue?9818:55 寻找中:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:59 寻找完毕:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:51 开始播放:play :36.856077

3.暂停时点击进度条快进(少了开头暂停和结尾播放)

寻找中
播放时间改变
寻找完毕
播放时间改变
播放时间改变

4. 拖动进度条(差不多,只是寻址过程会被多次触发)

暂停–pause
寻找中 --seeking (这3个会多次触发)
播放时间改变–timeupdate
寻找完毕–seeked
播放时间改变–timeupdate
播放时间改变–timeupdate
开始播放:–play

end:
大概稍微总结这么多,笔记可以做的不是很好,有问题可以交流哈

Guess you like

Origin blog.csdn.net/weixin_45295262/article/details/118613612