uniapp使用mui-player插件播放m3u8/flv视频流示例代码
作者:翘翘红
在小程序里播放视频是很常见的功能,下面这篇文章主要给大家介绍了关于uniapp使用mui-player插件播放m3u8/flv视频流的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
背景
uniapp 开发的h5项目,需要播放m3u8/flv后缀的视频,网上有很多视频插件,但是样式和效果不尽如人意,博主最后选择mui-player插件,定制化稍微强一点以及有官方文档可以阅读,官网文档https://muiplayer.js.org/zh/guide/
tips:建议先阅读官方文档,再在页面进行引入
博主最后实现的效果如下,pc端和移动端为两种展示样式,pc可以设置声音、播放速度、分辨率、全屏、画中画等功能,具体还有其他的功能自定义可以参照官网,官网的说明很详细以及有示例进行参考;移动端和pc端的功能大差不差,只是展现形式略有差别。
1、安装mui-player插件
npm i mui-player --save
2、页面引入,可选择在需要展示视频的页面直接引入
也可以放入一个公共组件,这样方便多个页面都会使用播放器的情况,博主这里将播放器作为一个公共组件,在组件里面引入
// 播放器样式文件 import 'mui-player/dist/mui-player.min.css' // npm安装方式引入mui-player import MuiPlayer from 'mui-player' // 要播放m3u8的视频就必须要引入hls.js import Hls from 'hls.js' // 要播放flv的视频就必须要引入flv.js import Flv from 'flv.js' // 要设置pc端视频的清晰度需要引入pc端扩展 import MuiPlayerDesktopPlugin from 'mui-player-desktop-plugin'
3、template模板
<template> <view id="mui-player"> <!-- 可在这里添加你想要覆盖在视频上面的内容,这里我加了一个关闭按钮,层级最高,不会影响视频的播放 --> <image v-if="showCloseIcon" src="@/sub-live/static/close.png" class="pos-a full-close" @click.stop="videoClose"> </view> </template>
4、data定一个空的mp对象
data() { return { mp: {} } },
5、需要向使用的页面传递的参数
props: { // 视频流地址,必传 src: { type: String, default: '' }, // 视频封面图,可选 poster: { type: String, default: '' }, // 是否要展示关闭视频图标 showCloseIcon: { type: Boolean, default: false }, // 当前视频是否是直播模式 live: { type: Boolean, default: false }, // 兼容音频m3u8(有些音频地址也是m3u8,但是音频不需要播放样式,所以需要兼容) isZero: { type: Boolean, default: false }, // 设置pc/移动端清晰度选择 childConfig: { type: Array, default: () => [{ functions: '高清', selected: true }, { functions: '标清' }, { functions: '流畅' }, ] } }
6、mounted生命周期初始化
mounted() { // 防止this的改变 const _this = this; // 根据视频路径后缀判断当前为m3u8还是flv的视频流 var flieArr = _this.src.split('.'); var suffix = flieArr[flieArr.length - 1]; // m3u8格式 var a = suffix.indexOf('m3u8') !== -1 // flv格式 var b = suffix.indexOf('flv') !== -1 var c = {} // m3u8格式的视频配置 if (a) { c = { type: 'hls', loader: Hls, config: { debug: false, } } } // flv格式的视频配置 if (b) { c = { type: 'flv', loader: Flv, config: { cors: true }, } } // 设置宽高,兼容音频,音频时高度为1,必须设置高度,不然音频没发播放,初始化会失败 var sWidth = uni.getSystemInfoSync().screenWidth; // 获取屏幕宽度 var width = 1; if (!_this.isZero) { // 不为音频 if (_this.$util.isMobile()) { // 移动端动态获取 width = sWidth; } else { width = 640; // pc端固定宽度为640 } } var height = 1; if (!_this.isZero) { height = parseInt(width * 9 / 16) // 可改成你想设置的视频的高度,博主这里设置为宽高比为16:9的视频 } _this.mp = new MuiPlayer({ // 指定播放器容器 container: '#mui-player', // 视频播放的资源地址 src: _this.src, // 是否自动播放,亲测在ios某些机型上自动播放失效 autoplay: false, // 是否静音播放 muted: false, // 初始化播放器宽度 width: width, // 初始化播放器高度 height: height, // 播放器容器是否自适应视频高度 autoFit: false, // 是否循环播放 loop: false, // 视频封面的资源地址 poster: _this.poster, // 是否开启直播模式,直播模式默认菜单配置不允许控制播放速度以及循环播放 live: _this.live, // 配置声明启用同层播放 videoAttribute: [{ attrKey: 'webkit-playsinline', attrValue: 'webkit-playsinline' }, { attrKey: 'playsinline', attrValue: 'playsinline' }, { attrKey: 'x5-video-player-type', attrValue: 'h5-page' }, ], // flv以及m3u8视频资源的配置 parse: c, // 自定义主题颜色 themeColor: _this.$config.INFO.THEME_COLOR, // 非全屏模式下,是否显示播放器头部操作控件,具体可参考官方文档 pageHead: false, plugins: [ // pc端清晰度设置 new MuiPlayerDesktopPlugin({ customSetting: _this.childConfig.length > 0 ? [{ functions: '清晰度', model: 'select', show: true, zIndex: 0, childConfig: _this.childConfig, onToggle: function(data, selected) { let onToggleLoad = function(state) { _this.mp.once('ready', function() { let _video = _this.mp.video(); let _execute = function() { _video.currentTime = state .currentTime; state.paused ? _video.pause() : _video.play(); } if (_video.readyState == 0) { _video.addEventListener( 'durationchange', function(e) { _execute(); }, { once: true }) } else { _execute(); } }) } // 选择清晰度后重载视频 selected(function() { let _video = _this.mp.video(); onToggleLoad({ currentTime: _video.currentTime, paused: _video.paused }); // 将当前选择的清晰度传递给父组件 _this.$emit('onToggleFn', data.functions) }); } }] : [] }) ] }); // 必须放在nextTick里面,等待dom渲染完成再监听视频的播放事件等,视频的其他事件也可在此处进行监听 _this.$nextTick(() => { // 监听播放器已创建完成 _this.mp.on('ready', function(event) { let _video = _this.mp.video(); _video.addEventListener("play",function(e){ //播放事件 _this.$emit('onPlayFn') }); _video.addEventListener("ended",function(e){ //播放完成事件 _this.$emit('onEndedFn') }); }); // 播放发生错误 _this.mp.on('error', function(event) { console.log('error', event); }); }) }
7、组件销毁,视频播放器也要销毁
destroyed() { this.mp.destroy(); },
8、可在组件内定义一些播放/暂停的事件供父组件调用(按需写入)
// 关闭视频,返回上一页 videoClose() { uni.navigateBack(); }, // 播放视频 playVideo() { let _video = this.mp.video(); // 获取视频示例 _video.paused ?_video.play(): _video.pause(); // 和原生video事件一致 }, // 暂停视频 pauseVideo(){ let _video = this.mp.video(); _video.pause(); }
9、播放视频组件完整代码,可按需进行增删改
<template> <view id="mui-player"> <image v-if="showCloseIcon" src="@/sub-live/static/close.png" class="pos-a full-close" @click.stop="videoClose"> </view> </template> <script> import 'mui-player/dist/mui-player.min.css' import MuiPlayer from 'mui-player' import Hls from 'hls.js' import Flv from 'flv.js' import MuiPlayerDesktopPlugin from 'mui-player-desktop-plugin' export default { props: { src: { type: String, default: '' }, poster: { type: String, default: '' }, showCloseIcon: { type: Boolean, default: false }, live: { type: Boolean, default: false }, // 兼容音频m3u8 isZero: { type: Boolean, default: false }, childConfig: { type: Array, default: () => [{ functions: '高清', selected: true }, { functions: '标清' }, { functions: '流畅' }, ] } }, data() { return { mp: {} } }, watch: { src(newVal, oldVal) { this.mp.reloadUrl(newVal); } }, mounted() { const _this = this; var flieArr = _this.src.split('.'); var suffix = flieArr[flieArr.length - 1]; // m3u8格式 var a = suffix.indexOf('m3u8') !== -1 // flv格式 var b = suffix.indexOf('flv') !== -1 var c = {} if (a) { c = { type: 'hls', loader: Hls, config: { debug: false, } } } if (b) { c = { type: 'flv', loader: Flv, config: { cors: true }, } } var sWidth = uni.getSystemInfoSync().screenWidth; var width = 1; if (!_this.isZero) { if (_this.$util.isMobile()) { width = sWidth; } else { width = 640; } } var height = 1; if (!_this.isZero) { height = parseInt(width * 9 / 16) } _this.mp = new MuiPlayer({ // 指定播放器容器 container: '#mui-player', // 视频播放的资源地址 src: _this.src, autoplay: false, muted: false, width: width, // 初始化播放器高度 height: height, // 播放器容器是否自适应视频高度 autoFit: false, // loop loop: false, // 视频封面的资源地址 poster: _this.poster, // 是否开启直播模式,直播模式默认菜单配置不允许控制播放速度以及循环播放 live: _this.live, // 配置声明启用同层播放 videoAttribute: [{ attrKey: 'webkit-playsinline', attrValue: 'webkit-playsinline' }, { attrKey: 'playsinline', attrValue: 'playsinline' }, { attrKey: 'x5-video-player-type', attrValue: 'h5-page' }, ], parse: c, // 自定义主题颜色 themeColor: _this.$config.INFO.THEME_COLOR, // 非全屏模式下,是否显示播放器头部操作控件 pageHead: false, plugins: [ new MuiPlayerDesktopPlugin({ customSetting: _this.childConfig.length > 0 ? [{ functions: '清晰度', model: 'select', show: true, zIndex: 0, childConfig: _this.childConfig, onToggle: function(data, selected) { let onToggleLoad = function(state) { _this.mp.once('ready', function() { let _video = _this.mp.video(); let _execute = function() { _video.currentTime = state .currentTime; state.paused ? _video.pause() : _video.play(); } if (_video.readyState == 0) { _video.addEventListener( 'durationchange', function(e) { _execute(); }, { once: true }) } else { _execute(); } }) } selected(function() { let _video = _this.mp.video(); onToggleLoad({ currentTime: _video.currentTime, paused: _video.paused }); _this.$emit('onToggleFn', data.functions) }); } }] : [] }) ] }); _this.$nextTick(() => { // 监听播放器已创建完成 _this.mp.on('ready', function(event) { let _video = _this.mp.video(); _video.addEventListener("play",function(e){ //播放事件 _this.$emit('onPlayFn') }); _video.addEventListener("ended",function(e){ //播放完成事件 _this.$emit('onEndedFn') }); }); // 播放发生错误 _this.mp.on('error', function(event) { console.log('error', event); }); }) }, destroyed() { console.log('destroyed'); this.mp.destroy(); }, methods: { videoClose() { uni.navigateBack(); }, playVideo() { let _video = this.mp.video(); _video.paused ?_video.play(): _video.pause(); }, pauseVideo(){ let _video = this.mp.video(); _video.pause(); } }, } </script> <style lang="scss" scoped> #mui-player{ z-index: 2; } .full-close { top: 22rpx; right: 22rpx; width: 44rpx; height: 44rpx; cursor: pointer; z-index: 8; } </style>
10、父组件调用播放器,按需进行修改
<!-- #ifdef H5 --> <common-player ref="muiplayer" :showCloseIcon="true" :poster="liveDetailInfo.thumb" :live="liveDetailInfo.start_time <= nowTime && nowTime <= liveDetailInfo.end_time ? true : false" :src="liveDetailInfo.rewriteVideoUrl" :childConfig="liveDetailInfo.qxdConfig" @onToggleFn="qxdToggle" @onEndedFn="ended" @onPlayFn="playFn"> </common-player> <!-- #endif -->
总结:
此播放器还是使用了开源的mui-player,所以尽量先去看文档,文档写的很详细,只是需要大面积的增删改操作,最后定制为自已想要的样子。
到此这篇关于uniapp使用mui-player插件播放m3u8/flv视频流的文章就介绍到这了,更多相关uniapp播放m3u8/flv视频流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!