记一次vue2.0+vue-video-player实现hls播放全过程
起因
最近公司想做一套视频点播服务,因为考虑到成本问题,领导希望一切都用开源系统来完成。基于这个出发点,那就肯定排除了各大云视频平台(腾讯云 音视频点播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
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:
果然没有,并且发现一个规律,我需要控制的按钮都是以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",
最最后
写贴不易,转发请注明原地址。谢谢!!
记一次vue2.0+vue-video-player实现hls播放全过程相关推荐
- Vue2.0 Vue组件 单文件组件
聊到单文件就要写道xxx.vue,但是.vue文件浏览器是不认识的得处理和加工成.js怎么处理和加工 渠道一: webpack 渠道二: 借助Vue官方提供的脚手架(官方给你搭建的整个webpack编 ...
- Vue2.0 Vue脚手架 scopde样式
学习scoped样式 问题 School.vue <template><div class="demo"> <h2>学校名称:{{name}}& ...
- Vue2.0 Vue路由_路由的几个注意点
1.一般组件和路由组件 一般用import引入组件.components注册组件.<组件名 />或<组件名></组件名>这样的写法被我们称为一般组件 而我们没像上面 ...
- 前端学习小demo:使用HTML+CSS+bootstrap+Vue2.0编写一个简易的音乐播放器(仿网易云)
具体的操作流程(实现步骤): 1.歌曲搜索 2.歌曲播放 3.歌曲评论 4.播放歌曲的MV(有的歌曲没有MV) 代码编写过程: 1.创建一个Vue项目(前提是安装好了node.js.npm.vue) ...
- 【Vue】双向数据绑定原理 vue2.0 与 vue3.0
目录 一.什么是双向数据绑定? 二.双向数据绑定原理 vue2.0 三.Vue 3.0使用ES6的新特性porxy 四.思考 一.什么是双向数据绑定? vue是一个mvvm框架,即数据双向绑定,即当数 ...
- Unity流水账2:视频播放之Video Player
VideoPlayer组件 使用VideoPlayer组件可以将视频文件附加到GameObjecs,并在运行时,在GameObject的Texture上播放它们. 默认情况下,Video Pl ...
- b站黑马的Vue快速入门案例代码——【axios+Vue2】悦听player(音乐播放器)
目录 本文中修改的原代码中的BUG: 修改方法: 本文案例代码仍有的BUG:(欢迎大家献计献策) 目标效果: 悦音player案例--效果展示视频: 更换的新接口/参数: 1.歌曲搜索接口:https ...
- vue2.0聊天室vue-chatRoom|仿微信界面vue+vuex+vueRouter
Vue2.0+Vuex+VueRouter仿微信界面聊天室|仿微信聊天窗口|仿微信群聊 基于vue2.0+vuex+webpack2.0+es6+wcPop等技术开发的仿微信聊天室vue-weChat ...
- vue 专题 vue2.0各大前端移动端ui框架组件展示
Vue 专题 一个数据驱动的组件,为现代化的 Web 界面而生.具有可扩展的数据绑定机制,原生对象即模型,简洁明了的 API 组件化 UI 构建 多个轻量库搭配使用 请访问链接: https://ww ...
最新文章
- 轻松搞定Retrofit不同网络请求方式的请求参数配置,及常用注解使用
- 闪存技术论坛即将召开 产业链领军企业齐聚谈变革
- [LGP4707] 重返现世
- 鸿蒙系统出来没有,呜呼哀哉!历尽艰辛研发出鸿蒙系统,却无厂商敢用
- 为什么你应该尝试@reach/router
- C#实现像微信PC版一样的扫码登录功能
- 如何在SQL Server 2017中实现图形数据库
- 数据结构(十七)数组和矩阵
- 帮助开发者快速创建响应式布局的Boilerplate - Responsive Boilerp...
- C/C++ typedef用法!
- 全世界所有程序员都会犯的错误-蔡学镛
- HashSet为什么要设置PRESENT
- 【树形DP+DFS】Gym 100962J - Jimi Hendrix
- 斩波电路---视频课笔记
- 计算机内存怎么与频率匹配,怎么算cpu与内存频率匹配
- 服务器被黑 追寻ip_网站服务器被攻击了如何查找木马(webshell)IP 篡改的痕迹...
- 毕业设计-基于机器自动驾驶目标检测研究-YOLO
- SQL server数据库常用代码大全
- Linux中的tail命令
- 华山论剑之iOS中(数组,字典,SQLite,CoreData)的“增删改查“
热门文章
- Linux防火墙的关闭
- MATLAB中的左除和右除
- 使用filter()方法进行数据过滤
- 20180415字节跳动今日头条笔试题——后台研发方向
- MySQL第三方客户端工具
- 机器学习、深度学习中常用的优化算法详解——梯度下降法、牛顿法、共轭梯度法
- IDEA如何导入一个已有项目
- N-BEATS NEURAL BASIS EXPANSION ANALYSIS FOR INTERPRETABLE TIME SERIES FORECASTING
- OPC (OLE for Process Control)
- Java学习(4)—— 布尔类型、基本数据类型转换、基本数据类型和String类型的转换