最近有个需求,需要在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
<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: ` `,
// 截图
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