0


uniapp 使用 mui-player 插件播放 m3u8/flv 视频流

背景:uniapp 开发的h5项目,需要播放m3u8/flv后缀的视频,网上有很多视频插件,但是样式和效果不尽如人意,博主最后选择mui-player插件,定制化稍微强一点以及有官方文档可以阅读,官网文档https://muiplayer.js.org/zh/guide/

tips:建议先阅读官方文档,再在页面进行引入

博主最后实现的效果如下,pc端和移动端为两种展示样式,pc可以设置声音、播放速度、分辨率、全屏、画中画等功能,具体还有其他的功能自定义可以参照官网,官网的说明很详细以及有示例进行参考;移动端和pc端的功能大差不差,只是展现形式略有差别。
pc端
在这里插入图片描述
1、安装mui-player插件

npm i mui-player --save

2、页面引入,可选择在需要展示视频的页面直接引入,也可以放入一个公共组件,这样方便多个页面都会使用播放器的情况,博主这里将播放器作为一个公共组件,在组件里面引入

// 播放器样式文件import'mui-player/dist/mui-player.min.css'// npm安装方式引入mui-playerimport MuiPlayer from'mui-player'// 要播放m3u8的视频就必须要引入hls.jsimport Hls from'hls.js'// 要播放flv的视频就必须要引入flv.jsimport Flv from'flv.js'// 要设置pc端视频的清晰度需要引入pc端扩展import MuiPlayerDesktopPlugin from'mui-player-desktop-plugin'

3、template模板

<template><viewid="mui-player"><!-- 可在这里添加你想要覆盖在视频上面的内容,这里我加了一个关闭按钮,层级最高,不会影响视频的播放 --><imagev-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')!==-1var 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 =newMuiPlayer({// 指定播放器容器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端清晰度设置newMuiPlayerDesktopPlugin({customSetting: _this.childConfig.length >0?[{functions:'清晰度',model:'select',show:true,zIndex:0,childConfig: _this.childConfig,onToggle:function(data, selected){letonToggleLoad=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'exportdefault{props:{src:{type: String,default:''},poster:{type: String,default:''},showCloseIcon:{type: Boolean,default:false},live:{type: Boolean,default:false},// 兼容音频m3u8isZero:{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')!==-1var 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 =newMuiPlayer({// 指定播放器容器container:'#mui-player',// 视频播放的资源地址src: _this.src,autoplay:false,muted:false,width: width,// 初始化播放器高度height: height,// 播放器容器是否自适应视频高度autoFit:false,// looploop: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:[newMuiPlayerDesktopPlugin({customSetting: _this.childConfig.length >0?[{functions:'清晰度',model:'select',show:true,zIndex:0,childConfig: _this.childConfig,onToggle:function(data, selected){letonToggleLoad=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-playerref="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,所以尽量先去看文档,文档写的很详细,只是需要大面积的增删改操作,最后定制为自已想要的样子。


本文转载自: https://blog.csdn.net/qiaoqiaohong/article/details/129554288
版权归原作者 翘翘红 所有, 如有侵权,请联系我们删除。

“uniapp 使用 mui-player 插件播放 m3u8/flv 视频流”的评论:

还没有评论