详解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 相关文章推荐
修改发贴的编辑功能
Mar 07 Javascript
javascript动态添加表格数据行(ASP后台数据库保存例子)
May 08 Javascript
各种常用的JS函数整理
Oct 25 Javascript
toggle()隐藏问题的解决方法
Feb 17 Javascript
JS控制表单提交的方法
Jul 09 Javascript
利用jQuery对无序列表排序的简单方法
Oct 16 Javascript
Vue响应式原理详解
Apr 18 Javascript
Angular2使用Angular CLI快速搭建工程(一)
May 21 Javascript
Three.js利用Detector.js插件如何实现兼容性检测详解
Sep 26 Javascript
浅析前端路由简介以及vue-router实现原理
Jun 01 Javascript
JS实现的类似微信聊天效果示例
Jan 29 Javascript
微信小程序左右滚动公告栏效果代码实例
Sep 16 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
PHP函数nl2br()与自定义函数nl2p()换行用法分析
2016/04/02 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
PHP实现动态获取函数参数的方法示例
2018/04/02 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
jQuery 连续列表实现代码
2009/12/21 Javascript
JQuery从头学起第一讲
2010/07/04 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
JS中如何设置readOnly的值
2013/12/25 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
2016/02/15 Javascript
使用JQuery中的trim()方法去掉前后空格
2016/09/16 Javascript
JavaScript仿支付宝6位数字密码输入框
2016/12/29 Javascript
angular分页指令操作
2017/01/09 Javascript
AngularJS折叠菜单实现方法示例
2017/05/18 Javascript
关于vue单文件中引用路径的处理方法
2018/01/08 Javascript
js canvas实现画图、滤镜效果
2018/11/27 Javascript
npm qs模块使用详解
2020/02/07 Javascript
[03:04]DOTA2超级联赛专访ZSMJ “莫名其妙”的逆袭
2013/05/23 DOTA
[02:16]深扒TI7聊天轮盘语音出处2
2017/05/11 DOTA
使用python绘制3维正态分布图的方法
2018/12/29 Python
python3使用matplotlib绘制条形图
2020/03/25 Python
python实现屏保程序(适用于背单词)
2019/07/30 Python
Python面向对象之私有属性和私有方法应用案例分析
2019/12/31 Python
python实现模拟器爬取抖音评论数据的示例代码
2021/01/06 Python
Python爬虫入门教程01之爬取豆瓣Top电影
2021/01/24 Python
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
台湾菁英交友:结识黄金单身的台湾人
2018/01/22 全球购物
美国最佳在线航班预订网站:LookupFare
2019/03/26 全球购物
奥地利体育网上商店:Gigasport
2019/10/09 全球购物
类成员函数的重载、覆盖和隐藏区别
2016/01/27 面试题
UNIX文件系统分类
2014/11/11 面试题
2014医学院领导干部四风对照检查材料思想汇报
2014/09/16 职场文书
简单通用的简历自我评价
2014/09/21 职场文书
文明单位申报材料
2014/12/23 职场文书
法律服务所工作总结
2015/08/10 职场文书
javascript实现计算器功能详解流程
2021/11/01 Javascript
CSS 实现角标效果的完整代码
2022/06/28 HTML / CSS