H5视频播放踩坑记录

本文记录了在H5页面中实现视频播放时遇到的问题,包括Android和iOS app Webview下的播放异常,以及微信环境下的全屏播放问题。通过对样式调整和全屏逻辑的优化,解决了大部分问题,但在安卓微信环境中仍存在自动播放的偶发故障,通过延时方案暂时缓解。
场景

某H5页面,页面由图片组成,其中某张图片点击后将全屏播放视频(其中视频定位到非可视区域)。视频播放组件采用的第三方库video-react

问题

app webview下安卓视频无法播放、ios需要点击两次才播放,微信环境下全屏播放问题

1.居然是样式

首先测试的时候pc浏览器以及手机浏览器环境下测试都是ok,所以初步判断问题出在webview上,通过debug,打印点击事件以及相关视频的信息,发现都是正常的并且没有发生报错情况。

后猜测是否跟全屏播放有关,将视频取消定位后正常展示,此时播放正常。

这时对比前面异常情况发现有个变量定位,遂找到对应样式,发现其中某个属性z-index: -1,去掉后一切正常了,Android和iOS均正常播放。

2.关于全屏自动播放

视频点击后全屏播放,取消全屏播放后视频暂停(因为视频不在可视区域,没有对应的操作可点)。组件提供了播放以及切换全屏方法,但是并没有切换全屏后的回调事件,好在组件额外提供了subscribeToStateChange方法,可以监听组件的所有状态,一波操作后:

imgClick (item) {
  const v = this.player // 视频组件实例
  v.toggleFullscreen()  // 切换全屏
  this.showVideoAndPlay = true
}

/** 监听视频信息变化 */
handleStateChange(state) {
  const v = this.player.player
  if (!state.isFullscreen) {
    v.pause()
    this.showVideoAndPlay = false
    return
  }
  if (state.isFullscreen && this.showVideoAndPlay){
    v.play()
    /** 这里要重置 不然会无限播放暂停循环*/
    this.showVideoAndPlay = false
    return
  }
  if (state.paused) {
    v.pause()
  }
}

componentDidMount() {
  this.player.subscribeToStateChange(this.handleStateChange.bind(this));
}

看到app表现良好,暗暗点了点头,表面很冷静,心里美滋滋。

但是,打脸这事,会迟到但是不会缺席,很快测试告知微信环境下播放有问题…

  • 微信视频播放
    微信浏览器的视频播放采用了自带的播放器,所以如果按照前面那个方式,点击打开后出现的是个黑屏,需要再次点击播放才能正常播放。经过一波调试,点击播放代码修改如下:

     imgClick (item) {
        const v = this.player // 视频组件实例
        v.play()
        v.toggleFullscreen()  // 切换全屏
      }
    

    但是又发现安卓跟ios表现又是不一样

    1. ios下正常,安卓下视频播放变为横屏,且没有自动播放,在点击播放然后退出全屏或者直接退出全屏后再次重新播放,正常竖屏并且自动播放。
    2. 同时,在app 安卓环境下,全屏后无法自动播放。
      上诉两个问题在调整播放跟切换全屏两个方法后各自解决,于是代码修改为:
    imgClick (item) {
        const v = this.player
        // 全屏跟播放顺序在app环境跟微信下是两个结果 ios默认播放全屏
        if (bridge.isInApp()) {
          !this.$os.ios && v.toggleFullscreen()   // 切换全屏
          v.play()
        } else {
          v.play()
          !this.$os.ios && v.toggleFullscreen() // 切换全屏
        }
      }
    

    其中对全屏方法做了环境判断是因为 iso 下默认播放全屏

    至此,app与微信环境下全屏展示基本一致,只剩下安卓微信环境下自动播放问题。这个问题最终采用延时方案解决,但并不是完美解决,还是会存在偶发的不能自动播放的情况。具体什么原因全靠猜,其中机制并不是特别清楚,有待后续研究。所以最后代码修改如下:

    imgClick (item) {
        const v = this.player
        // 全屏跟播放顺序在app环境跟微信下是两个结果 ios默认播放全屏
        if (bridge.isInApp()) {
          !this.$os.ios && v.toggleFullscreen()   // 切换全屏
          v.play()
        } else {
          v.play()
          !this.$os.ios && setTimeout(() => {v.toggleFullscreen()},500)  // 切换全屏
        }
      }
    
补充
  • ios 微信环境下视频初始化黑屏解决方案:
    // react ref
    ...
    ref={player => {
        this.player = player
        // 微信sdk
        this.$JSBridge({
          success: () => {
            this.player.pause();
          }
        }, "getNetworkType");
    }}
    ...
  • 前面讲到的都是全屏模式下,全屏模式某些浏览器默认是以浏览器自身播放器去操作(比如Safari,微信),其实也可以通过某些属性比如playsInline去控制使用html5的播放器,不过这样设置之后,上诉的一些方法将不再生效,需要通过其他方式再去处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值