详解vue2.0+vue-video-player实现hls播放全过程


Posted in Javascript onMarch 02, 2018

起因

最近公司想做一套视频点播服务,因为考虑到成本问题,领导希望一切都用开源系统来完成。基于这个出发点,那就肯定排除了各大云视频平台(腾讯云 音视频点播VOD、网易云视频、七牛云、阿里云 视频服务等)。其实这里我还是建议购买云视频平台,因为自己造轮子肯定没有别人造的好(专门研发团队除外、以此业务为生的公司除外),再说,云视频平台服务商提供的都是一整套解决方案:收集、存储、转码、播放器等,并且在cdn和弹性扩容上都能得到最大保障。

准备

视频点播最少需要两样东西:流媒体服务、视频播放器。 因为这是一篇讲述前端播放器的帖子,关于流媒体服务的搭建我就pass了,以后有时间再补充新帖。

因为公司前端架构用的是vue全家桶,所以还是希望能够找一款基于vue封装的视频播放器。

首先到vue社区找到了vue-dplayer,于是就install到本地测试了一下,这时候出现个问题:此播放器在播放基于hls协议的m3u8文件时(视频文件在流媒体服务已经成功部署),在ios上能够正常播放(自家协议支持良好),但是在pc的chrome上是不支持的。然后我去github上找了找资料,资料显示Dplay(vue-dplayer就是依据Dplay封装的)是支持hls的,只是需要引入hls.js,然后用hls对video对象进行处理。因为hls.js与Dplayer示例代码是针对video对象处理的,引入到项目中还需要修改vue-dplayer的一个属性,时间紧迫,先放弃之(之后我会有一篇专门介绍Dplayer播放hls的帖子,已补充),转身投入vue-video-player的怀抱。

为什么会用vue-video-player

1. 我搭建的流媒体服务的管理页面内的播放器就是用的videoJs(vue-video-player是依据videoJs封装的),使用之后感觉良好。
2. 百度输入“vue video”,vue-video-player就在顶部。(哈哈,就是这么随意)
3. 当然还是看了demo页,支持的协议齐全。
4. 虽然vue-video-player的github上还有些issues没有关闭,但是自己觉得守着videoJs强大的库与万千使用者,总能解决问题。(迷之自信啊)

开整

安装依赖

npm install vue-video-player --save

引入样式

// 第一个是videoJs的样式,后一个是vue-video-player的样式,因为考虑到我其他业务组件可能也会用到视频播放,所以就放在了main.js内
require('video.js/dist/video-js.css')
require('vue-video-player/src/custom-theme.css')

把VueVideoPlayer导入并挂在到vue上

//在main.js内
import VideoPlayer from 'vue-video-player'
Vue.use(VideoPlayer);

编写业务组件 myPlayer.vue

<template>
 <div class="container">
 <div class="player">
  <video-player class="video-player vjs-custom-skin"
      ref="videoPlayer"
      :playsinline="true"
      :options="playerOptions"
      @play="onPlayerPlay($event)"
      @pause="onPlayerPause($event)"
  >
  </video-player>
 </div>
 </div>
</template>

<script>
import { videoPlayer } from 'vue-video-player';
export default {
 data () {
 return {
  playerOptions: {
//  playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
  autoplay: false, //如果true,浏览器准备好时开始回放。
  muted: false, // 默认情况下将会消除任何音频。
  loop: false, // 导致视频一结束就重新开始。
  preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
  language: 'zh-CN',
  aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
  fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
  sources: [{
   type: "application/x-mpegURL",
   src: "video.m3u8" //你的m3u8地址(必填)
  }],
  poster: "poster.jpg", //你的封面地址
  width: document.documentElement.clientWidth,
  notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
//  controlBar: {
//   timeDivider: true,
//   durationDisplay: true,
//   remainingTimeDisplay: false,
//   fullscreenToggle: true //全屏按钮
//  }
  }
 }
 },
 components: {
 videoPlayer
 },
 methods: {
 onPlayerPlay(player) {
  alert("play");
 },
 onPlayerPause(player){
  alert("pause");
 },
 },
 computed: {
 player() {
  return this.$refs.videoPlayer.player
 }
 }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style type="text/css" scoped>
 .container {
 background-color: #efefef;
 min-height: 100%;
 }
</style>

注意:

1. video-player标签的class必须设置成“video-player vjs-custom-skin”,你引入的样式才能起作用。我刚开始做时,直接拷贝的github页的代码,那个代码的class是video-player-box。
2. 根据videoJS Api修改属性。我这里加了一些注释,可以参考。
3. 修改src、poster属性为你的服务器资源地址。

增加hls支持

//安装依赖
npm install --save videojs-contrib-hls

//在main.js内引入
require('videojs-contrib-hls/dist/videojs-contrib-hls');

启动服务,查看效果

npm run dev

详解vue2.0+vue-video-player实现hls播放全过程

videoJs的播放按钮默认为椭圆形,我个人有点不习惯,所以修改成了圆形。

增加css样式

.video-js .vjs-big-play-button{
  /*
  播放按钮换成圆形
  */
 height: 2em;
 width: 2em;
 line-height: 2em;
 border-radius: 1em;
 }

注意:

直接在 myPlayer.vue组件内增加样式会被覆盖,不论你有没有增加scoped属性,这取决于vue加载样式的顺序,之前查资料看了一个帖子,讲的很好,可惜找不着了。

我最终的解决方案是:自定义了一个css文件,使用require引入到了main.js内,放在上述样式引入之后。

require('video.js/dist/video-js.css');
require('vue-video-player/src/custom-theme.css');
require('@/../static/css/myVideoCss.css');

大bug: 播放按钮与fastclick冲突

冲突是这样的:播放器在手机浏览器或者chrome开发者工具(手机尺寸)内,点击播放按钮,播放与暂停事件会被触发多次。

刚开始不知道什么原因,在github上提了个issure,刚提完就发现上一个关闭的issure解决的就是这个问题,这里得向作者道个歉,给您添堵了。哈哈。于是我看了另外一个人给的答案:与fastclick插件冲突……,但是….. 没有解决方案。然后我尝试注释掉了fastclick,果然是它影响的。

然后我去fastclick github 地址看了看 ,页面说的很清楚,只要在触发的元素上增加一个needsclick的class就可以了。

但是我试了好久都没有成功。这时候看到了神贴,大体浏览了一下fastclick的源码过程,并且作者提到“Fastclick 把 this.needsClick 放到了 ontouchEnd 末尾去执行,才导致前面说的加上了“needsclick”类名也无效的问题。”所以我想尝试修改fastclick的源码,并且验证一下。

我把整个faseclick.js拷贝了出来,并采用require的方式引用。

const FastClick = require('@/../static/js/fastclick.js');
FastClick.attach(document.body);

打开代码,猜想为什么needsclick没有起到作用,所以就直接检索了一下这个单词,在 FastClick.prototype.needsClick方法的最后,有一个验证:

return (/\bneedsclick\b/).test(target.className);

首先FastClick.prototype.needsClick方法是判断元素是否要保留穿透功能,而最后一行肯定是验证触发的元素的class是不是含有needsclick。所以我先猜测是不是我触发的元素没有加上class,所以console了target.className:

详解vue2.0+vue-video-player实现hls播放全过程

果然没有,并且发现一个规律,我需要控制的按钮都是以vjs开头的,所以,在验证上再增加一个验证。

return ((/\bneedsclick\b/).test(target.className) || (/\bvjs/).test(target.className));

问题解决,当然解决问题的方式暴力了一些,所以这里我希望看到并觉得此帖有帮助的同学能够在此基础上继续补充完善。我就先趟到这。最后贴个版本

"fastclick": "^1.0.6",
 "videojs-contrib-hls": "^5.12.2",
 "vue": "^2.2.2",
 "vue-router": "^2.2.0",
 "vue-video-player": "^4.0.6",

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
window.onbeforeunload方法在IE下无法正常工作的解决办法
Jan 23 Javascript
js select option对象小结
Dec 20 Javascript
jquery实现的鼠标拖动排序Li或Table
May 04 Javascript
JS简单计算器实例
Jan 20 Javascript
javascript html5 canvas实现可拖动省份的中国地图
Mar 11 Javascript
vue强制刷新组件的方法示例
Feb 28 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
Apr 26 Javascript
Vue-cli3生成的Vue项目加载Mxgraph方法示例
May 31 Javascript
实例讲解React 组件
Jul 07 Javascript
写一个Vue loading 插件
Nov 09 Javascript
Vue项目打包部署到apache服务器的方法步骤
Feb 01 Vue.js
Javascript中Microtask和Macrotask鲜为人知的知识点
Apr 02 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
Mar 02 #Javascript
浅谈FastClick 填坑及源码解析
Mar 02 #Javascript
利用vue和element-ui设置表格内容分页的实例
Mar 02 #Javascript
vue将时间戳转换成自定义时间格式的方法
Mar 02 #Javascript
Element-ui table中过滤条件变更表格内容的方法
Mar 02 #Javascript
使用vue-aplayer插件时出现的问题的解决
Mar 02 #Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
Mar 02 #Javascript
You might like
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
PHP扩展编写点滴 技巧收集
2010/03/09 PHP
解析php多线程下载远程多个文件
2013/06/25 PHP
PHP6 中可能会出现的新特性预览
2014/04/04 PHP
thinkphp常见路径用法分析
2014/12/02 PHP
php实现概率性随机抽奖代码
2016/01/02 PHP
javascript 学习之旅 (3)
2009/02/05 Javascript
Javascript 类与静态类的实现
2010/04/01 Javascript
eclipse如何忽略js文件报错(附图)
2013/10/30 Javascript
简单实现jQuery进度条轮播实例代码
2016/06/20 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
小程序中canvas的drawImage方法参数使用详解
2019/07/04 Javascript
javascript面向对象程序设计实践常用知识点总结
2019/07/29 Javascript
微信小程序云函数使用mysql数据库过程详解
2019/08/07 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
浅谈Vue 函数式组件的使用技巧
2020/06/16 Javascript
JavaScript 几种循环方式以及模块化的总结
2020/09/03 Javascript
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
Python的Flask框架及Nginx实现静态文件访问限制功能
2016/06/27 Python
CentOS 7下安装Python3.6 及遇到的问题小结
2018/11/08 Python
Python提取特定时间段内数据的方法实例
2019/04/01 Python
Python中常见的数制转换有哪些
2020/05/27 Python
Python操控mysql批量插入数据的实现方法
2020/10/27 Python
浅析python实现动态规划背包问题
2020/12/31 Python
python 制作本地应用搜索工具
2021/02/27 Python
NFL官方在线商店:NFLShop
2020/07/29 全球购物
升职自荐书范文
2013/11/28 职场文书
简历里的自我评价
2014/01/31 职场文书
健康家庭事迹材料
2014/05/02 职场文书
蛋糕店创业计划书
2014/05/06 职场文书
大学生暑期实践报告
2015/07/13 职场文书
考研经验交流会策划书
2015/11/02 职场文书
高中语文教学反思范文
2016/02/16 职场文书
新学期小学班主任工作计划
2019/06/21 职场文书
PyQt5实现多张图片显示并滚动
2021/06/11 Python