最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 仿抖音视频全屏播放&滑动切换

    正文概述 掘金(大转转FE)   2020-12-18   498

    仿抖音视频全屏播放&滑动切换

    1 前言

    随着移动技术的快速迭代,数据流量费用的快速下降,视频、直播正成为全民的媒体盛宴,我司必然也不会缺席此次盛宴,这里讲述的是通过h5实现仿抖音视频全屏播放&滑动切换的效果,供我司直播鉴定回放视频使用。

    2 实现效果

    仿抖音视频全屏播放&滑动切换

    3 设计方案

    • 视频播放video标签
    `video`标签是HTML5新增的用于视频播放的标签,MDN对其介绍如下:
    

    兼容性如下(来自Can I Use): 仿抖音视频全屏播放&滑动切换 其在移动端较好的兼容性,成为目前我们的首选方案之一

    • 单视频缓冲

    关于video标签的preload属性: 此属性用于定义视频是否预加载。属性有三个可选择的值:nonemetadataauto

    - None:不进行预加载。使用此属性值,可能是页面制作者认为用户不期望此视频,或者减少HTTP请求。
    - Metadata:部分预加载。使用此属性值,代表页面制作者认为用户不期望此视频,但为用户提供一些元数据(包括尺寸,第一帧,曲目列表,持续时间等等)。
    - Auto:用户需要这个视频优先加载;换句话说就是提示:如果需要的话,可以下载整个视频,即使用户并不一定会用它。
    

    但是在实际情况下,其实只预加载了一部分。它并没有自动进行全部视频内容的下载,这样的策略实际有利于节约用户宽带造成不必要的请求。

    假如不设置,默认值就是浏览器定义的了 (即,不同浏览器会选择自己的默认值),即使规范建议设置为 metadata。

    由于各个浏览器实现不同,有些浏览器是处于auto默认设置,在其处于auto设置下,如果页面内存在多个视频,会同时缓冲,造成资源浪费以及低端安卓机器的白屏和崩溃。

    所以,为了尽量保证当前视频的快速、流畅播放,尽量保证仅有当前视频处于资源加载中。

    • 无限加载实现
      • 简单方案:使用列表进行无限加载,和实现无限下拉列表类似,实现简单,但是在无限加载情况必然会出现页面性能问题
      • 复杂方案:参考轮播图最后一页循环加载方案,使用三个大的节点,每次动画后进行隐式切换,示意图如下:

    仿抖音视频全屏播放&滑动切换

    4 实现

    4.1 模板层代码实现

    代码由vue进行实现,目前使用上下排列的三个主要节点构成,上下放置视频封面等信息,中间放置实际视频信息,上下节点主要用于用户滑动视频时候预览视频封面等相关信息,在移动端通过监听touch相关事件进行切换实现,其主要代码如下:

    <div
      :class="[isMove && 'wrap-animation']"
      :style="{ transform: `translateY(${translateY}px)`}"
      @touchstart="onTouchStart"
      @touchmove.prevent="onTouchMove"
      @touchend="onTouchEnd"
    >
      <div><!-- 一些除开视频外的点赞信息等 --></div>
      <div><!-- 视频信息 --></div>
      <div><!-- 一些除开视频外的点赞信息等 --></div>
    </div>
    

    4.2 自动切换动画实现

    • js实现 PK CSS实现

    在用户触摸结束后,如果达到切换条件,则需要切换到下一个视频,需要切换动画,动画的实现主要有requestAnimationFrame/setTimeout等传统的方法实现,也有css3新增的transition/animation过渡效果和动画实现本实例中为了低端安卓机的流畅性,故采用的css过渡transition进行实现,通过isMove判断进行动画类wrap-animation的添加,动画类实现如下:

    .wrap-animation {
      transition: transform .6s;
    }
    
    • 是否切换视频判断

    由用户滑动距离&滑动速度决定,满足其一即可,主要实现是通过translateY参数在滑动开始和滑动进行中记录滑动距离,同时在滑动中实现页面拖拽跟随效果,以及使用startTime参数在滑动开始时的时间戳,滑动结束时候进行判断,如果需要进入下一个视频,则将通过isMove参数开启动画,然后通过修改translateY参数进行切换。

    onTouchEnd () {
      if (this.isMove || this.translateY == 0) return
      // 计算滑动速度
      const speed = Math.abs(this.translateY / (Date.now() - this.startTime));
      // 判断移动距离和滑动速度是否达到界限 如果达到界限
      if (Math.abs(this.translateY) > this.maxY || speed > this.maxSpeed) {
        // 开启切换动画 
        this.isMove = true;
        this.translateY = this.translateY < 0 ? -this.clientHeight : this.clientHeight;
        // 动画结束处理 去除动画参数,进行隐式界面切换
        setTimeout(() => {
          // 关闭切换动画 切换数据
          this.isMove = false
          this.videoIndex = this.translateY < 0 ? this.videoIndex + 1 : this.videoIndex - 1;
          this.translateY = 0;
          // 判断获取推荐视频列表信息
          // 切换视频等操作
        }, 500)
      } else {
        // 恢复原位
      }
    }
    

    在动画结束后的下一帧,去除动画,进行隐式界面数据切换,如此重复,达到无限加载的效果。同时在判断动画结束时间这块,本实例使用了setTimeout实现,该操作是不准确的,建议使用transitionend事件进行实现。

    5 各类问题

    在实现的时候的各种问题,欢迎吐槽

    5.1 视频全屏

    据MDN介绍:

    总的来说,使用全屏的方式有两个,一个是模拟全屏,一个是web原生的。模拟全屏的好处是可以自定义相关控件,以达到统一多端样式的目的,固然需要复杂一些;原生全屏相对比较方便,处理起来会比较轻松,缺点是全屏后,几乎不能做什么干预。因此采用模拟全屏

    5.1.1 防止iOS上默认全屏播放

    在iOS上播放视频将会默认使用系统全屏进行播放,几乎不能做什么干预,因此需要禁止该能力,采取模拟全屏播放。在ios10及以后的版本,可以通过给video标签加playsinline属性防止iOS默认全屏播放,ios9之前加webkit-playsinline属性,如果要兼容,则把两个属性都加上。

    5.2 视频自动播放

    在进入页面后自动播放视频能够极大的提升用户体验。该功能主要由video元素autoplay属性实现,其在MDN上的提示如下:

    由于没有强制浏览器去遵循该属性的值,所以在移动端,有些浏览器支持添加autoplay属性后自动播放,有些设置 autoplaymuted属性也能自动播放,比如IOS 10+、Chrome。

    但是,经过实践,在安卓客户端,多数时候都是不能实现自动播放,经过多方调研,web端无法处理,最终求助客户端,通过修改webview容器相关参数,配合添加autoplay属性实现自动播放,其处理如下:

    webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
    

    5.3 play方法错误排查

    当调用视频标签的play方法时候,如果不支持播放,将会报错,且无法使用try catch捕获,是因为videoplay() 方法会返回一个Promise对象,如果播放失败,可以通过返回的Promise catch到相关错误信息,这对我们来说至关重要,当出现js调用播放失败的时候,我们可以对用户进行友好引导,同时上报相关错误信息以及机型,在千奇百怪的安卓机型兼容上显得尤其重要。

    6 思考

    连续滑动流畅性
    由于该方案需要在每一次切换完成后的下一帧进行一次隐式数据修改,所以是不支持不间断连续滑动的,是否有更好的方案呢?

    欢迎大家在评论区提出自己的想法!


    起源地下载网 » 仿抖音视频全屏播放&滑动切换

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元