import Player from 'xgplayer'import FlvPlugin from 'xgplayer-flv'import "xgplayer/dist/index.min.css"new Player({ id:'dom-id', // 播放器实例化所需的dom url: 'test.flv', // 视频源 width: '100%', height: '100%'})
2.多实例初始化时可以使用选择器id或容器el但对于同时实例化多个播放器的场景,使用Id很容易导致最终只实例化成功一个,虽然你可以通过ID+索引的方式避免,但使用容器el还是更为简洁的<div ref="playerRef"></div>const playerRef = ref()new Player({ el: playerRef.value,...})
3.常用属性new Player({ poster // 封面 autoplay // 自动播放,基本上不支持有声自动播放; autoplayMuted // 自动静音播放,需要自动播放可使用改属性 playsinline // 对于移动 Safari 浏览器来说是必需的,它允许视频播放时不强制全屏模式 loop // 循环播放 fitVideoSize // 根据视频内容调整容器宽高 videoFillMode // 视频画面填充模式 controls // 是否展示进度条 videoAttributes // 透传给video标签的属性 })
关于自动播放的限制还是很多的,所以把预期降低到大部分设备可以静音播放即可...关于自动播放4.直播能力「FLV协议:」使用xgplayer-flv,可用于PC、安卓import FlvPlugin from 'xgplayer-flv'if (FlvPlugin.isSupported()) { // 第一步,检测当前环境是否支持 const player = new Player({ id: 'dom-id', url: 'test.flv', // flv 流地址 isLive: true, plugins: [FlvPlugin] // 第二步 })}
「HLS协议:」使用xgplayer-hls,可用于PC、安卓、IOS(ios&部分andr不需要插件,原生支持)在原生支持hls的情况下尽可能不使用xgplayer-hls,IOS浏览器原生即支持hls格式播放,但是缺少xgplayer-hls运行所需的Media Source Extensionsimport Player from 'xgplayer'import HlsPlugin from 'xgplayer-hls'let playerif (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) { // 原生支持 hls 播放 player = new Player({ el: document.querySelector('.player'), url: 'test.m3u8' })} else if (HlsPlugin.isSupported()) { // 第一步,检测当前环境是否支持 player = new Player({ el: document.querySelector('.player'), isLive: true, url: 'test.m3u8', // hls 流地址 plugins: [HlsPlugin] // 第二步 })}
5.样式自定义xgplayer提供了十分便捷的方式去配置iconconst playerConfig = { icons: { // 1.通过function方式 返回一个dom play: () => { const dom = Util.createDom('div', '<img src="./start"/>', {}, 'customclass') return dom }, // 2.直接html代码 pause: `<div class='customclass'><img src="./start"/></div>`, // 3.直接一张图片链接 startPlay: 'https://xxx.zhuanzhuan.com/xxx.png' }}
但是很多地方的icon大小尺寸是固定死的,如果想要修改还是要去覆盖xgplayer默认的样式image-202311231638025516.自定义插件xgplayer支持插件的扩展机制,无论是简单的功能按钮还是复杂的播放逻辑都可以通过插件的形式来实现这里实现一个简单的插件,结合我们的通用组件库,用于在视频暂停时,展示一些提示// demoPlugin.jsimport Vue from 'vue'import { Events, Plugin } from 'xgplayer'import Demo from './demoPlugin.vue'const { POSITIONS } = Pluginexport default class DemoPlugin extends Plugin { // 插件的名称,将作为插件实例的唯一key值 static get pluginName() { return 'demoPlugin' } static get defaultConfig() { return { // 挂载在播放器最上方 position: POSITIONS.ROOT_TOP } } constructor(args) { super(args) this.vm = null } // 插件实例化之后 afterCreate() { // 使用vue组件 const Component = Vue.extend(Demo) this.vm = new Component().$mount('.demo-plugin') // 视频播放时 this.on(Events.PLAY, () => { this.vm.hide() }) // 视频暂停时 this.on([Events.PAUSE], () => { this.vm.show() }) } destroy() { // 播放器销毁的时候一些逻辑 } render() { return '<div class="demo-plugin"></div>' }}
// demoPlugin.vue<template> <NoticeBar v-show="visible" swipe> <span style="padding-right: 50px;">我一定会回来的~我一定会回来的~我一定会回来的~</span> </NoticeBar></template><script setup lang="ts">import { ref, defineExpose } from 'vue'import { NoticeBar } from '@zz-common/zz-ui';const visible = ref(true)const show = () => { visible.value = true}const hide = () => { visible.value = false}defineExpose({ show, hide})</script>
// 使用import DemoPlugin from './demoPlugin.js'...new Player({ ..., plugins: [DemoPlugin]})
image五、遇到的问题1.事件监听相关在播放器的事件中有两个与播放操作相关的事件——play、canplay「play」表示播放已开始「canplay」表示浏览器可以播放媒体文件了,但估计没有足够的数据来支撑播放到结束,不必停下来进一步缓冲内容简单区分下这两个事件:play可以具象的理解为点击播放按钮或者自动播放成功,canplay则表示视频资源已经开始加载并缓冲了一部分数据达到了启播的条件这两个事件的先后顺序不固定——如果没有设置自动播放、也没有设置预加载,那应该是play、canplay如果设置了预加载,但没有设置自动播放,则应该是canplay、play,到目前按照事件的定义来看,还是能抓住一些规律的但是呢经过我测试发现,同样的设置,在原生video标签和xgplayer上执行顺序不同另外在不同的操作系统上也会导致执行顺序不同,比如 ios Safari 从不预加载导致无法在未播放时触发canplay事件所以十分不建议根据这两个事件的执行时机来做一些事(不过目前也想不到这种场景,只是无意中发现的)2.跨域问题问题的起因是当时的直播流内容总是会间隔性的黑屏,而且后端无法监控到并调整视频源于是需要前端通过截取画面并分析截图的像素点来判断是否黑屏,以实现黑屏自动切换视频源的能力但是当通过canvas获取图片数据时getImageData报了一个SecurityError异常经查阅发现这是浏览器的安全策略,不通过CORS使用其他来源的资源,会污染画布在"被污染"的 canvas 中调用以下方法将会抛出安全错误:在 canvas 的上下文上调用getImageData()在canvas元素本身调用toBlob()、toDataURL()、captureStream()所以如果要对视频内容进行截图或者对视频画面做一些操作处理,需要给video标签设置crossOrigin属性,在xgplayer中可以通过videoAttributes属性传入const player = new Player({ ..., videoAttributes: { crossOrigin: 'anonymous' }})
3.内存溢出当不需要播放器时,记得及时销毁,否则可能会导致内存溢出(尤其是多实例、切换播放的场景)player.destroy() // 销毁播放器player = null // 将实例引用置空
「无需单独销毁插件实例,xgplayer自动会帮我们执行该操作」—— xgplayer将所有注册的插件维护在pluginGroup对象中,当我们调用播放器的destroy方法时,遍历所有插件并依次执行插件的销毁方法imageimageimage4.兼容性问题???在测试的时候发现,iPhone 14Pro机型,直播播放的时候,如果跳转到其他页面,再返回到直播页,会导致视频播放错误;该问题暂时没有思路,不清楚原因...目前的解决办法是,在页面不可见时,记录并销毁该播放器,在页面展现时再重新实例化之前的播放器六、最终效果目前线上正常运行,暂时没有发现其他问题七、参考资料1.允许图片和 canvas 跨源使用(https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image)2.西瓜播放器(https://h5player.bytedance.com/guide/)3.Safari HTML5 Audio and Video Guide(https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/AudioandVideoTagBasics/AudioandVideoTagBasics.html)作者:杨双星 来源:微信公众号:大转转FE出处:https://mp.weixin.qq.com/s/Q7XZIOLH-nSYtZ4F6MKs8w(图片来源网络,侵删)
0 评论