1 前言

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

2 实现效果

image

3 设计方案

视频播放video标签

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

复制代码

对于HTML 元素 用于在HTML或者XHTML文档中嵌入媒体播放器,用于支持文档内的视频播放。

兼容性如下(来自Can I Use):

image

其在移动端较好的兼容性,成为目前我们的首选方案之一

单视频缓冲

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

- None:不进行预加载。使用此属性值,可能是页面制作者认为用户不期望此视频,或者减少HTTP请求。

- Metadata:部分预加载。使用此属性值,代表页面制作者认为用户不期望此视频,但为用户提供一些元数据(包括尺寸,第一帧,曲目列表,持续时间等等)。

- Auto:用户需要这个视频优先加载;换句话说就是提示:如果需要的话,可以下载整个视频,即使用户并不一定会用它。

复制代码

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

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

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

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

无限加载实现

简单方案:使用列表进行无限加载,和实现无限下拉列表类似,实现简单,但是在无限加载情况必然会出现页面性能问题

复杂方案:参考轮播图最后一页循环加载方案,使用三个大的节点,每次动画后进行隐式切换,示意图如下:

image

4 实现

4.1 模板层代码实现

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

:class="[isMove && 'wrap-animation']"

:style="{ transform: `translateY(${translateY}px)`}"

@touchstart="onTouchStart"

@touchmove.prevent="onTouchMove"

@touchend="onTouchEnd"

>

复制代码

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介绍:

使用提供的API,让一个元素与其子元素,可以占据整个屏幕,并在此期间,从屏幕上隐藏所有的浏览器用户界面以及其他应用。

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

5.1.1 防止iOS上默认全屏播放

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

5.2 视频自动播放

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

使用备注:

autoplay 属性优先于 preload 假如用户想自动播放视频,那么很明显浏览器需要下载视频。同时设置autoplay 和 preload属性在规范里是允许的。

规范没有强制浏览器去遵循该属性的值;这仅仅只是个提示。

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

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

webView.getSettings().setMediaPlaybackRequiresUserGesture(false);

复制代码

5.3 play方法错误排查

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

6 思考

连续滑动流畅性

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

html5仿抖音全屏播放,仿抖音视频全屏播放滑动切换相关推荐

  1. JWPlayer Flash播放器如何实现视频分段载入播放从而节省带宽?

    近期由于一个项目的需要,对Flash版本的播放器JWPlayer做了一些改进以支持一些功能,这里把中间用到的一些思路和做法记录下. 首先一个功能是:客户的很多flv视频都是完整的一个大视频,希望JWP ...

  2. 电脑视频html5全屏掉帧,uwp看视频全屏掉帧或卡机怎么办-解决uwp看视频全屏掉帧或卡机的方法 - 河东软件园...

    不知道大家在使用UWP应用的时候有没有遇到这个奇怪的现象,播放视频的时候很流畅,但是每当我们将视频全屏播放时就会从出现视频掉帧或是卡死机的情况.最近就有位win10用户遇到过这个现象,并且在更新该应用 ...

  3. 微信视频播放器隐藏播放控件,视频全屏做法分享

    转自:https://www.haorooms.com/post/weixin_hidevideo_control 本人实测有效.为了防止以后还要用到,到时候找不到,所以转载一下. 前言 平时项目中视 ...

  4. android录视频花屏,拍大师录制视频花屏怎么办 拍大师录制视频花屏的解决方法...

    拍大师有一个非常好用的屏幕/摄像头录像功能,这也是这个软件的一大特色,我们大家平时在使用拍大师的时候有没有出现花屏现象?这可能用户电脑配置的显卡问题,那拍大师录制视频花屏怎么办呢?小编和大家分享下拍大 ...

  5. css3音乐播放器,CSS3-自定义视频与音乐播放器!

    今天说一下自定义视频和音乐播放器!直接先看看完成后的效果图把! 视频: video.jpg 音乐: 音乐.jpg 哈哈,是不是觉得太难看了,根本没心情往下继续看了?那就对了.我也觉得难看,但是重点来了 ...

  6. vue西瓜播放器xgplayer-vue实现视频倍速播放,自定义进度条样式

    介绍 npm网站:https://www.npmjs.com/package/xgplayer-vue 西瓜播放器官网:https://v2.h5player.bytedance.com/gettin ...

  7. android 视频录制花屏,拍大师录制视频时画面花屏怎么办?拍大师录制视频花屏的解决方法图解...

    拍大师有一个非常好用的屏幕/摄像头录像功能,这也是这个软件的一大特色,我们大家平时在使用拍大师的时候有没有出现花屏现象?这可能用户电脑配置的显卡问题,那拍大师录制视频花屏怎么办呢?小编和大家分享下拍大 ...

  8. Mac QuickTime Player X播放器打开电影视频后自动播放的方法

    打开终端(方法一:Finder-应用程序-实用工具-终端:方法二:点击屏幕右上角放大镜图标,搜索"终端").在里面输入以下命 令  "defaults write com ...

  9. 解决WIN10播放AVI等格式视频黑屏只有声音的问题

    需要用到的软件:K-Lite Codec Pack 下载地址: http://www.codecguide.com/download_kl.htm K-Lite Codec Pack是世界闻名,备受好 ...

  10. 电脑b站html加速播放,b站视频怎么加速播放-将B站视频调速播放的方法 - 河东软件园...

    B站是国内有名的视频播放网站,这个网站中有很多专业视频播放器中没有的资源,特别是喜欢动漫的用户对这个网站想必是非常熟悉的了.不知道大家有没有发现,现在很多的视频制作的剧情都很拖沓,明明两分钟可以演完的 ...

最新文章

  1. Hibernate- 子查询
  2. 小程序bindtap参数传递
  3. 多人互砍游戏的后台服务器的多线程架构
  4. 使用nhmicro提供的micro-datasource嵌入式的解决微服务架构中分布式事务问题
  5. root cause of error messagw for a mixed usage of 01 and 03
  6. 高并发大流量专题---6、独立图片服务器的部署
  7. 无线电频段属国家资源,不是你想用就能用
  8. java语言定义一个具备栈功能的类_Java学习笔记 第二章 Java语言基础
  9. DTD vs. XML Schema
  10. python核心数据类型
  11. 基于单片机的老人防摔GSM报警
  12. cefsharp 网页另存为图片,CefSharp获取页面截图
  13. Linux编辑器-vim的使用的 “打字练习“
  14. python中终结一个循环的保留字_【单选题】以下可以终结一个循环的保留字是() (2.0分) A. if B. break C. exit D. continue...
  15. linux常用桌面有两种,推荐!5款Linux常用桌面环境
  16. ethtool如何让接口闪灯_如何使用ethtool命令管理以太网卡
  17. 万字干货 | 如何从0到1搭建一套会员体系
  18. 八年,腾讯优图攒了多厚的技术“家底”?
  19. Ubuntu安装邮件服务器
  20. 基于SEIR模型对美国COVID-19疫情传播的预测和分析

热门文章

  1. 牛客网java编程题库
  2. 安装包没意思?带你手动下载OpenWrt源码编译安装!
  3. 【Fiddler Everywhere】2022最强抓包工具(安装 修改教程)
  4. 十套Substance视频教程
  5. BoCloud博云荣登中国云计算创新企业榜TOP50
  6. 刘强东:京东不是快递公司 但物流作用显而易见
  7. hive 如何解析包含 json 的字符串字段
  8. kali局域网常用攻击命令
  9. 呼叫中心系统的应用与价值
  10. (论文精读)PCANet:一种简单的图像分类的深度学习基线