如何快速开发一个自定义的视频播放器(4)——调试

调试问题

实际上我们在浏览器端调试时,移动端网页的有些问题很难发现,样式问题只是次要的。比较容易出现的问题就是浏览器提供的媒体组件,浏览器通常使用操作系统提供的API来实现一些功能,如音频和视频播放。不同的操作系统可能提供了不同的API,或者即使是相同的API,它们的实现也可能有所不同,这也可能导致不同的表现。这里我们主要在以下环境做了测试,也是我们常用的几个环境:安卓浏览器、ios浏览器、微信浏览器。然后本篇文章主要展示几个出现的问题及其解决方案。

1.全屏播放问题

本问题主要分为两种,一是移动端的video播放基本都是默认全屏播放,当视频开始播放的时候,视频默认进入全屏模式;二是当我们修改了视频默认不全屏播放时,在微信浏览器端想要进入全屏播放模式得需要特殊的处理。 第一个问题在本系列的第二篇文章的模板说明种已说明了解决方法:

正常的video在手机端播放的时候都是默认全屏播放,因此我们需要控制视频初始内联播放,因此需要设置一下属性: webkit-playsinline="true" playsinline="true" x5-playsinline 这里同时设置了3个playsinline主要是兼容不同的设备 使视频默认为内联播放即可解决这个问题。

第二个问题,目前仅在微信端的浏览器复现,实际上我们在实现SetFullScreen方法的时候已经对大部分浏览器做了兼容:

javascript 复制代码
const video = this.video.target
     if (video.requestFullscreen) {
       video.requestFullscreen()
     } else if (video.mozRequestFullScreen) {
       /* Firefox */
       video.mozRequestFullScreen()
     } else if (video.webkitRequestFullscreen) {
       /* Chrome, Safari 和 Opera */
       video.webkitRequestFullscreen()
     } else if (video.msRequestFullscreen) {
       /* IE/Edge */
       video.msRequestFullscreen()
     }

但是在微信浏览器中,video元素上都没有这些方法,也没有提供进入全屏模式的方法,而仅仅提供了两个关于全屏模式进入和退出的监听方法,实际上也不是很好使,这里不展示了,感兴趣的大家自行搜索。这里说一下我们的解决思路,是根据第一个问题产生的方案,因为微信端其实也是默认播放视频的,所以当我们检测到微信环境,我们在设置全屏的时候,把内联播放取消,然后播放即可进入全屏播放;然后当我们退出全屏时,再点播放按钮进入播放时,再把我们的video标签设置为内联播放即取消了全屏播放。完美解决全屏播放的问题:

javascript 复制代码
 SetFullScreen() {
      // other codes...
      if (
        navigator.userAgent.toLocaleLowerCase().indexOf('micromessenger') !== -1
      ) {
        video.pause()
        video.removeAttribute('webkit-playsinline')
        video.removeAttribute('playsinline')
        video.removeAttribute('x5-playsinline')
        video.removeAttribute('x-webkit-airplay')
        video.play()
      }
    }
   
     PlayVideo() {
      if (this.video.target.paused) {
        if (
          navigator.userAgent.toLocaleLowerCase().indexOf('micromessenger') !==
          -1
        ) {
          this.video.target.setAttribute('webkit-playsinline', 'true')
          this.video.target.setAttribute('playsinline', 'true')
          this.video.target.setAttribute('x5-playsinline', 'x5-playsinline')
          this.video.target.setAttribute('x-webkit-airplay', 'true')
        }
        this.video.target.play()
      } else {
        this.video.target.pause()
      }
    }

2.开始播放白屏问题

当我们的视频资源是从网络上或者cdn上动态加载的时候,总是在开始播放的时候白屏或者黑屏 1s左右,当网络差的时候这种白屏或者黑屏时间可能更长,当然这是由于视频资源加载缓慢的原因。首先想到的解决方案就是poster+preload,将preload设置为auto或者metadata,然后把poster设置好,确实在视频未播放的时候不会出现黑屏或者白屏。但是当我们点击播放的时候,还是会有黑屏或者白屏闪烁一下,所以这个并不能解决我们的体验问题。 因此思考我们需要把poster单独抽离出来,同时去监听canplay事件,当视频可以播放的时候再将poster隐藏,同时播放视频。 所以我们在start-play-btn和video之间放一层poster,同时控制它的展示状态即可:

模板

html 复制代码
 <video
        :src="videoSrc"
        id="video"
        class="player"
        style="object-fit:fill"
        webkit-playsinline="true"
        playsinline="true"
        x5-playsinline
        preload="auto"
        :poster="poster"
        x-webkit-airplay="true"
        ref="video"
      ></video>
      <div
        class="poster"
        id="poster"
        v-if="!video.canplay"
      >
        <img
          src="https://peiyinimg.qupeiyin.cn/2024-03-19/171083686254726059014.jpg-thumb"
          class="poster-icon"
        >
      </div>
      <div
        class="fz-player-controls-panel-wrapper"
        id="playerPanel"
        @click="ShowControl"
      >...</div>

逻辑代码

javascript 复制代码
     data() {
        return {
            // ... other params,
          video: {
            // ... other params,
            canplay: false
          }
        }
     },
     
    video.oncanplay = () => {
        // ... other code
        this.video.canplay = true
      }

虽然不知道媒体文件播放在各个浏览器的实现细节,但是我们可以通过宏观的方式解决一些看似不可能解决的问题。这就是编码的魅力。

3.关键帧问题

video播放在浏览器有一个细节问题,有些视频当我们seek的时候,我们的indicator总是在播放时或前或后的跳动一下,或者当我们拖动indicator之后松开的时候,也会或前或后的跳动一下然后再正常播放进度,很让人抓狂。其实还以为是我们计算的seek时间有那么零点几秒的差异。但是不管怎么去调接时间的精度,有些视频总是会出现这种问题。仔细调研一番才知道,这就是视频压缩中的"关键帧"问题。当我们进行seek的时候video会把帧定位到离我们seek时间最近的那个关键帧上,当我们视频的编码格式或分辨率不高的时候,也就会概率出现seek不准确的问题。解决这个办法,目前之后去修改我们播放的视频源了,暂时没有找到前端的解决方案。

总结

实际上在调试过程中我们可能会遇到了许多的问题,但是如果我们的编码足够细致且够优雅,实际上逻辑问题基本都遇不到,遇到的都是一些兼容和体验问题,而往往这些体验问题,其实占我们调试的大部分时间。毕竟产品都是给用户用的,如果体验不好,那么做出来又有什么意义呢。在调试过程中,其实我们也在不断的优化我们的代码,让自己的代码变的优雅,是一个优秀的程序员必备的技能之一,下一章我们就来结合本项目谈谈代码优化的话题。

相关推荐
赵锦川1 小时前
css相关:input输入框中加入搜索图标
java·前端·javascript
yunduor9093 小时前
从零开始搭建UVM平台(九)-加入reference model
前端
莘薪4 小时前
HTML的修饰(CSS) -- 第三课
前端·css·html·框架
某公司摸鱼前端5 小时前
uniapp 上了原生的 echarts 图表插件了 兼容性还行
前端·uni-app·echarts
2401_857297916 小时前
秋招内推--招联金融2025
java·前端·算法·金融·求职招聘
BHDDGT6 小时前
react-问卷星项目(5)
前端·javascript·react.js
小白求学17 小时前
CSS滚动条
前端·css
与妖为邻7 小时前
房屋水电费记账本:内置的数组数据击按钮不能删除,页面手动添加的可以删除
前端·javascript·css·html·localstorage·房租水电费记账本
miniwa8 小时前
JavaScript 中最快的循环是什么?
前端·javascript
阳树阳树8 小时前
Websocket 基本使用
前端·javascript·面试