html5 video 标签在不同的浏览器里,解析有差异,所以使用 videojs 来处理兼容性问题
videojs 官网
videojs Github
1. 引入
1.1 全局引入
页面里全局引入 videojs 即可,js文件建议放在 body 底部位置
如果在 PC 端使用,还需要引入 videojs-flash.js(flash模式播放)、videojs-contrib-hls.js(解析流媒体 m3u8)
1 2 3 4
| <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet"> <script src="https://unpkg.com/video.js/dist/video.js"></script> <script src="https://unpkg.com/videojs-flash/dist/videojs-flash.js"></script> <script src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script>
|
1.2 构建工具内局部引入
安装依赖
1
| npm install video.js --save-dev
|
1 2
| import videojs from 'video.js'; window.videojs = videojs || videojs.default;
|
注意 videojs-contrib-hls
依赖包并不支持 import 模块方式引入,所以想兼容 PC 时需要按上小节方式全局引入
2. 使用
以下场景为,正方形流媒体视频 m3u8 格式,点击开始,再次点击暂停
videojs初始化完毕后,.vjs-tech 为DOM结构里的实际的video标签
src 为父组件传过来的视频地址,poster 为视频未加载时显示的图片
videojs 的初始化参数有多重配置方式,建议以标签属性的方式来配置
2.1 标签属性的说明
注意 html 行内的属性,写了就生效了,controls="true"
、controls="false"
都是错误地写法,写完整必须写为controls="controls"
x5 开头的标签只对腾讯 x5 内核的浏览器有效,即微信、QQ浏览器,所有的属性见 H5同层播放器接入规范
显示控制条 controls
行内播放(不自动全屏播放)webkit-playsinline playsinline x5-playsinline
【安卓】启用H5同层播放器 x5-video-player-type=”h5”
启用后微信、QQ浏览器里,不会使用腾讯的默认播放器
这里如果不启用,则使用腾讯的播放器,videojs 控制不了,会显示播放控件
如果启用了,则使用 html5 默认行为来播放,videojs 可以控制,但一定会全屏播放
2.2 一般页面的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <video id="my-video" class="video-js vjs-default-skin only-play-button" webkit-playsinline playsinline x5-playsinline controls poster="https://testec.ghs.net/public/images/8d/69/0e/0bf26ca05396e726ad05540d582580bc322c20b9.jpg" data-setup="{}" preload="auto" > <source src="http://cdn.ghs-tv.readtv.cn/video/ebeefe116c9aa4835e18b53b15a8cd26/stream.m3u8" type="application/x-mpegURL"> </video> <button id="play-btn">播放</button> <button id="pause-btn">暂停</button>
<script type="text/javascript"> var player = videojs(window.document.querySelector('#my-video'),{},function(){ let v = this.el_.querySelector('.vjs-tech'); v.removeAttribute('z-index'); v.addEventListener('click', () => { if (this.paused()) { this.play(); } }); v.addEventListener('touchstart', () => { if (!this.paused()) { this.pause(); } }); });
window.document.querySelector('#play-btn').addEventListener('click',function(){ player.play(); }); window.document.querySelector('#pause-btn').addEventListener('click',function(){ player.pause(); }); </script>
|
2.3 vuejs组件内的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <template> <video id="my-video" class="video-js vjs-default-skin only-play-button" controls webkit-playsinline playsinline style="object-fit:fill" x5-playsinline :poster="poster" data-setup='{}' > <source :src="src" type="application/x-mpegURL"/> </video> </template>
<script> import videojs from 'video.js'; window.videojs = videojs || videojs.default;
export default { props: ['src', 'poster'], mounted() { if (!this.player) { this.player = videojs(this.$el, {}, function playerReady() { let v = this.el_.querySelector('.vjs-tech'); v.removeAttribute('z-index'); v.addEventListener('click', () => { if (this.paused()) { this.play(); } }); v.addEventListener('touchstart', () => { if (!this.paused()) { this.pause(); } }); }); } }, beforeDestroy() { if (this.player) { this.player.dispose(); } }, }; </script>
<style> @import url('/static/css/video-js.min.css'); <style>
|
父组件中
1
| <video-player :src="m3u8视频地址" :poster="视频预览图"></video-player>
|
3.样式优化
只在视频中央显示一个圆按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| .video-js { width: 100vw; height: 100vw; }
.only-play-button { .vjs-big-play-button { top: 50%; left: 50%; margin-top: -1.5em; margin-left: -1.5em; z-index: 10; }
.vjs-icon-placeholder { font-size: 2em; }
&.vjs-paused .vjs-big-play-button { display: block; height: 3em; line-height: 3em; border-radius: 1.5em; }
&.vjs-controls-disabled.vjs-paused .vjs-big-play-button, &.vjs-using-native-controls.vjs-paused .vjs-big-play-button, &.vjs-error.vjs-paused .vjs-big-play-button { display: none; }
.vjs-control-bar, .vjs-error-display, .vjs-text-track-display { display: none; } }
|
4. 自动播放
只有 iOS 微信里,可以调用微信客户端的 JSBridge 方法,实现自动播放
1 2 3
| document.addEventListener("WeixinJSBridgeReady", function (){ player.play(); }, false)
|
5. 部分浏览器兼容问题
360浏览器,它会自动给video标签加z-index值,导致点击不到videojs播放控件
解决方式:移除 video 标签的 style 属性,使 z-index 修正为正常。
1 2 3
| $("video").on("play",function(){ $(this).attr("style",""); });
|
baidu浏览器,播放时loading图闪烁
解决方式:判断是百度浏览器时,不显示 loading 图
1 2 3
| if(window.navigator && (window.navigator.userAgent).match(/baidu/i)) { $(".vjs-loading-spinner").hide(); }
|