开发背景

最近有个需求,需要在app中展示对应站房的实时监控画面,因为uniapp原有的video组件功能比较少就考虑到引入西瓜播放器的视频组件

开发准备

因为是直播流就选择了flvjs, 项目安装xgplayer-flv

npm install xgplayer-flv

通过render.js去做视图层,要注意的是nvue无法使用renderjs
详细文档可以自己去查看用法 https://uniapp.dcloud.net.cn/tutorial/renderjs.html

​renderjs 是一个运行在视图层的js。它比WXS更加强大。它只支持app-vue和web。
renderjs 的主要作用有2个:
1. 大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
2. 在视图层操作dom,运行 for web 的 js库

基础代码

monitor.vue

<!-- monitor.vue -->
<template>
	<view class="uni-padding-wrap monitor_box list_box">
		<uni-row style="background-color: #fff;" class="list_video_box">
			<uni-col :span="8" class="list_video_item" v-for="(item,i) in videoLlist" :key="i">
				<xgplayer :id='`myVideo${i}`' :videoData="item"></xgplayer>
				<text class="text">{{item.mpName}}</text>
			</uni-col>
		</uni-row>
	</view>
</template>
<script>
	import xgplayer from './xgplayer.vue'
	export default {
		components: { xgplayer },
		data(){
			return {
				videoList: [], // 视频列表
			}
		}
	}
</script>

xgplayer.vue

<template>
	<view class="media-box" style="width: 264px;height: 160px;" :start='startUrl' :change:start="xgplayer.startPlay" >
		<view :id="id" :detail="videoData" :change:detail="xgplayer.initJs"></view>
	</view>
</template>

<script>
	// 逻辑层
	export default {
		props: ['id', 'videoData'],
		data(){
			return {
				startUrl:1
			}
		},
		methods: {
			onPlay(){
				console.log('响应视图层方法')
			}
		}
	}
</script>

<script module="xgplayer" lang="renderjs">
	// 视图层
	import FlvPlayer from 'xgplayer-flv';
    export default{
		data(){
			return {
				xgPlayer: null
			}
		},
        mounted(){},
		onunload() {
			this.xgPlayer.destroy()
		},
        methods:{
            initJs(newVal,old,ownerInstance,instance){
				if (typeof window.Player === 'function') {
					this.initPlayer(newVal)
				} else {
					// 动态引入较大类库避免影响页面展示
					const script = document.createElement('script')
					// view 层的页面运行在根目录
					script.src = 'static/xgplayer.js'
					document.head.appendChild(script)
					script.onload = this.initPlayer.bind(this,newVal,ownerInstance)
				}
            },
            
            initPlayer(detail,ownerInstance){
				const _this = this
				_this.xgPlayer = new FlvPlayer({
					id: 'myVideo' + detail.index, // 容器ID
					poster: 'https://xxx/xxx.png', // 封面图不支持本地资源
					isLive: true, // 是否直播
					url: detail.videourl + '?url=' + detail.SteamName, // 直播流地址
					autoplay: false, // 是否自动播放
					height: 160,
					width: 264,
					// 播放错误后的站位图
					errorTips: `<image src='http://xxx/xxx.png' id='videoErr${detail.index}' style='width: 50%;'><image>`,
					// 截图
					screenShot: {
						saveImg: true,
						quality: 0.92,
						type: 'image/png',
						format: '.png'
					},
					ignores: ['time', 'progress', 'replay', 'volume'], // 关闭内置控件
					closeInactive: true, // 播放器控制栏常驻不隐藏
					closeVideoClick: true, // video触发click事件后视频切换播放/暂停状态
				})
                
                _this.xgPlayer.once('play',()=>{
                    console.log('播放成功')
                    // 调用逻辑层方法
                    ownerInstance.callMethod('onPlay')
                })
				_this.xgPlayer.on('error',(err)=>{
				    console.log('播放出错', err)
					let videoErr = document.getElementById(`videoErr${detail.index}`)
					// 重新播放
					videoErr.onclick = function () {
						_this.xgPlayer.destroy()
						_this.initPlayer(detail,ownerInstance)
					}
				})
				_this.xgPlayer.on('screenShot',(DOMString)=>{
				    console.log(DOMString);
				    _this.saveScreenshot(new Date().getTime(), DOMString, 100)
				})
            },
			saveScreenshot(fileName, base64, quality) { // fileName:自定义文件名 ,base64:图片base64码, quality: 图片质量1-100
			  const bitmap = new plus.nativeObj.Bitmap()
			  // 从本地加载Bitmap图片
			  bitmap.loadBase64Data(base64, () => {
			    bitmap.save("_doc/" + fileName + ".jpg", {
			      overwrite: true,
			      quality: quality
			    }, (i) => {
			      // callback(i);
			      console.log("保存图片成功:" + JSON.stringify(i))
			      this.capture(i.target)
			    }, (e) => {
			      console.log("保存图片失败:" + JSON.stringify(e))
			    })
			  }, (e) => {
			    console.log("加载图片失败:" + JSON.stringify(e))
			  })
			},
			
			// 保存视频截图到相册
			capture(file) {
			  plus.gallery.save(file, () => {
			    console.log("图片已保存到相册")
			  }, (e) => {
			    if (e.code === -3310 || e.code === 8) {
			      console.log("您已禁止访问相册,请设置开启权限")
			    } else {
			      console.log("图片保存失败:" + JSON.stringify(e))
			    }
			  })
			},

            // 逻辑层触发视图层函数
            startPlay(){
				this.xgPlayer.play()
            },
        }
    }
</script>

完成效果图
在这里插入图片描述

相关文档

uniapp官网组件 https://uniapp.dcloud.net.cn/component
西瓜播放器配置项 https://v2.h5player.bytedance.com/config/#%E5%BF%85%E9%80%89%E9%85%8D%E7%BD%AE

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐