feat(视频): 完成视频列表和视频详情页面,升级1.0.26版本

This commit is contained in:
风花一世月 2024-07-09 23:25:24 +08:00
parent 077e37990e
commit 73e26c8355
3 changed files with 270 additions and 79 deletions

View File

@ -2,8 +2,8 @@
"name" : "物联网可视化",
"appid" : "__UNI__604B8F1",
"description" : "",
"versionName" : "1.0.25",
"versionCode" : 1025,
"versionName" : "1.0.26",
"versionCode" : 1026,
"transformPx" : false,
/* 5+App */
"app-plus" : {

View File

@ -1,10 +1,22 @@
<template>
<view class="video-detail">
<nav-bar :is-back="true" title="视频监控"></nav-bar>
<!-- <nav-bar :is-back="true" title="视频监控"></nav-bar> -->
<view class="video-box">
<!-- #ifdef APP-PLUS -->
<!-- <video id="myVideo" :src="url" autoplay v-if="showVideo" show-mute-btn="true" vslide-gesture="true" :controls="btnToggle"> -->
<video id="myVideo" :src="dataObj.url" autoplay v-if="showVideo" controls="false">
<!-- #ifdef APP-PLUS -->
<video id="myVideo" :src="dataObj.flvUrl" autoplay v-if="showVideo" :controls="false">
<cover-view class="btn-toggle" v-if="btnToggle" @click="quitFullScreen">
退出全屏
</cover-view>
<view class="btn-toggle" v-if="btnToggle" @click="quitFullScreen">
退出全屏
</view>
</video>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<video id="myVideo" :src="dataObj.m3u8Url" autoplay v-if="showVideo" :controls="false">
<!-- <cover-view class="btn-toggle" v-if="btnToggle" @click="quitFullScreen">
退出全屏
</cover-view> -->
@ -13,20 +25,23 @@
</view> -->
</video>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<!-- <live-player id="live-video" src="http://al.flv.huya.com/src/78941969-2559461593-10992803837303062528-2693342886-10057-A-0-1-imgplus.flv?wsSecret=f61867c0ada81aceb02d7306fdd059a2&wsTime=6037810b&fm=RFdxOEJjSjNoNkRKdDZUWV8kMF8kMV8kMl8kMw%3D%3D&ctyp=huya_tars&txyp=o%3Aq5%3B&fs=bgct&&sphdcdn=al_7-tx_3-js_3-ws_7-bd2-hw2&sphdDC=huya&sphd=264-265&ratio=500" v-if="showVideo" autoplay> -->
<!-- #ifdef MP-WEIXIN
<live-player id="live-video" :src="dataObj.url" v-if="showVideo" autoplay @statechange="statechange"
@netstatus="netstatus">
<cover-view class="btn-toggle" v-if="btnToggle" @click="quitFullScreen">
退出全屏
</cover-view>
</live-player>
<!-- #endif -->
#endif -->
</view>
<view class="video-title">
{{dataObj.name}}
</view>
<view class="channe-name">
通道名称:{{dataObj.channeName}}
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="slider-box">
<!-- <view class="title">
@ -100,8 +115,12 @@
speed: 100,
btnToggle: false,
dataObj: {
url: '',
name: ''
flvUrl: '',
m3u8Url: '',
id:'',
name: '',
channeId:'',
channeName:'',
},
refreshdata: 11,
showVideo: true,
@ -118,40 +137,51 @@
id: '',
channel: '',
},
//
ptzTypeUrl:'',
ptzType: {}
};
},
onLoad(option) {
console.log("option",option)
this.ptzType = PTZ_TYPE;
console.log("PTZ_TYPE", PTZ_TYPE)
console.log("option: ", option);
console.log("optionobj: ", JSON.parse(decodeURIComponent(option.obj)));
let obj = JSON.parse(decodeURIComponent(option.obj));
if (obj.siteM7sHost && obj.siteM7sPort && obj.devId && obj.devChannel) {
if (obj.https) {
this.videoObj = {
url: 'https://' + obj.siteM7sHost + ':' + obj.siteM7sPort,
id: obj.devId,
channel: obj.devChannel,
}
this.pullVideoList('https://' + obj.siteM7sHost + ':' + obj.siteM7sPort, obj.devId, obj.devChannel)
this.dataObj.url = 'https://' + obj.siteM7sHost + ':' + obj.siteM7sPort + '/hdl/' + obj.devId + '/' +
obj.devChannel + '.flv'
} else {
this.videoObj = {
url: 'http://' + obj.siteM7sHost + ':' + obj.siteM7sPort,
id: obj.devId,
channel: obj.devChannel,
}
this.pullVideoList('http://' + obj.siteM7sHost + ':' + obj.siteM7sPort, obj.devId, obj.devChannel)
this.dataObj.url = 'http://' + obj.siteM7sHost + ':' + obj.siteM7sPort + '/hdl/' + obj.devId + '/' +
obj.devChannel + '.flv'
}
} else {
this.$u.toast('摄像头参数错误!');
}
this.dataObj.name = obj.label;
console.log("当前flv地址:" + this.dataObj.url)
let deviceObj = JSON.parse(decodeURIComponent(option.deviceObj));
let channeObj = JSON.parse(decodeURIComponent(option.channeObj));
this.videoObj.url = channeObj.hlsUrl;
this.dataObj.flvUrl = channeObj.hdlUrl;
this.dataObj.m3u8Url = channeObj.hlsUrl;
this.dataObj.id = channeObj.devId;
this.dataObj.name = deviceObj.name;
this.dataObj.channeId = channeObj.channelId;
this.dataObj.channeName = channeObj.name;
this.ptzTypeUrl = channeObj.baseUrl;
// if (obj.siteM7sHost && obj.siteM7sPort && obj.devId && obj.devChannel) {
// if (obj.https) {
// this.videoObj = {
// url: 'https://' + obj.siteM7sHost + ':' + obj.siteM7sPort,
// id: obj.devId,
// channel: obj.devChannel,
// }
// this.pullVideoList('https://' + obj.siteM7sHost + ':' + obj.siteM7sPort, obj.devId, obj.devChannel)
// this.dataObj.url = 'https://' + obj.siteM7sHost + ':' + obj.siteM7sPort + '/hdl/' + obj.devId + '/' +
// obj.devChannel + '.flv'
// } else {
// this.videoObj = {
// url: 'http://' + obj.siteM7sHost + ':' + obj.siteM7sPort,
// id: obj.devId,
// channel: obj.devChannel,
// }
// this.pullVideoList('http://' + obj.siteM7sHost + ':' + obj.siteM7sPort, obj.devId, obj.devChannel)
// this.dataObj.url = 'http://' + obj.siteM7sHost + ':' + obj.siteM7sPort + '/hdl/' + obj.devId + '/' +
// obj.devChannel + '.flv'
// }
// } else {
// this.$u.toast('!');
// }
console.log("当前flv地址:" + this.videoObj.url)
//
// uni.setInnerAudioOption({
// obeyMuteSwitch: false
@ -250,12 +280,12 @@
console.log("ptzcmd", ptzcmd)
this.btnToast(type);
let params = {
id: this.videoObj.id,
channel: this.videoObj.channel,
id: this.dataObj.id,
channel: this.dataObj.channeId,
ptzcmd: ptzcmd
}
let DefaultOpts = {
url: this.videoObj.url + '/api/gb28181/control',
url: this.ptzTypeUrl + '/gb28181/api/control',
data: params,
method: "GET",
}
@ -336,6 +366,12 @@
line-height: 100rpx;
text-indent: 30rpx;
}
.channe-name{
font-size: 28rpx;
line-height: 60rpx;
margin: 0 30rpx 0 20rpx;
}
.title {
font-size: 26rpx;

View File

@ -1,28 +1,67 @@
<template>
<view id="video-list">
<!-- <scroll-view scroll-y class="right-box"> -->
<view class="video-list-box">
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" :up="upOption" @up="upCallback">
<view class="page-view">
<u-collapse :accordion="false">
<u-collapse-item v-for="(item, index) in dataList"
:key="item.id" :open="true">
<template slot="title">
<view class="box-title">
<text>{{item.name}}</text>&nbsp;&nbsp;
<text>{{item.children?`(${item.children.length})`:''}}</text>
<view class="video-list">
<view class="video-item" v-for="(item,index) in dataList" :key="item.id">
<view class="item-header">
<view class="item-header-left">
设备编号{{item.deviceId}}
</view>
<view class="item-header-right" :style="{color:item.status==1?'#52c41a':'#ff4d4f'}">
{{item.status==1?'启用':'禁用'}}
</view>
</view>
<view class="item-content">
<view class="content-title-box">
<view class="content-title-box-left">
<view class="iconfont icon-jiankong"></view>
</view>
</template>
<view class="collapse-item">
<view class="box-item" v-for="(val,i) in item.children" :key="val.id"
@click="goDetail(val)">
{{val.label}}
<view class="content-title-box-right">
<view class="content-title-txt">
{{item.name}}
</view>
<view class="content-title-info">
设备型号{{item.model||'-'}}
</view>
</view>
</view>
</u-collapse-item>
</u-collapse>
<view class="item-content-list">
<view class="item-content-list-left">
<view class="item-content-item">
设备类型{{item.deviceType||'-'}}
</view>
<view class="item-content-item">
提供商{{item.provider||'-'}}
</view>
<view class="item-content-item">
厂家{{item.manufacturer||'-'}}
</view>
<view class="item-content-item">
创建时间{{item.createdAt}}
</view>
</view>
<view class="item-content-list-right">
<u-button type="primary" size="mini" :custom-style="customStyle" @click="getChanneList(item.id,index)">查询通道</u-button>
</view>
</view>
</view>
<view class="item-footer" v-if="item.channelList && item.channelList.length>0">
<view class="channel-item" v-for="(val,i) in item.channelList" :key="val.id">
<view class="channel-item-left">
<view class="iconfont icon-video-camera"></view>
<view class="channel-name">
{{val.name}}
</view>
<view class="channel-status" :style="{color:val.status==1?'#52c41a':'#ff4d4f'}">
{{val.status==1?'启用':'禁用'}}
</view>
</view>
<u-button type="primary" size="mini" :custom-style="customStyle2" @click.stop="goDetail(index,i)">播放</u-button>
</view>
</view>
</view>
</view>
</mescroll-body>
<!-- </scroll-view> -->
</view>
</template>
@ -59,11 +98,19 @@
mixins: [MescrollMixin],
data(){
return {
customStyle: {
padding: '30rpx 30rpx', //
margin:'0'
},
customStyle2: {
padding: '30rpx 40rpx', //
margin:'0'
},
upOption:{
noMoreSize: 4,
textNoMore: '---- 已经到底啦 ----',
empty:{
tip: '~ 搜索无数据 ~' //
tip: '~ 暂无监控设备 ~' //
}
},
dataList:[],
@ -84,6 +131,9 @@
let curPageData = res.data && res.data.list;
let curPageLen = curPageData && curPageData.length || 0;
let totalSize = res.data.totalCount;
curPageData.forEach((item,index)=>{
curPageData[index].channelList = []
})
this.$nextTick(()=>{
// ;
this.mescroll.endBySize(curPageLen, totalSize);
@ -101,32 +151,137 @@
this.$u.toast('服务器开小差了呢,请您稍后再试')
})
},
goDetail(item){
console.log("跳转详情",item);
let obj = {
url:encodeURIComponent(item.url),
name:item.label
}
uni.navigateTo({
url:'./video-detail?obj='+encodeURIComponent(JSON.stringify(item))
getChanneList(id,index){
console.log("id",id,index)
this.$api.videoApi.getVideoChannelList({pid: id,page:1,pageSize:999}).then(res => {
if(res.code == 0){
if(res.data.list && res.data.list.length>0){
console.log("this.dataList[index]",this.dataList[index])
this.$nextTick(()=>{
this.$set(this.dataList[index],'channelList',res.data.list)
})
}else{
this.$u.toast('通道为空');
this.$nextTick(()=>{
this.$set(this.dataList[index],'channelList',[])
})
}
}else{
this.$u.toast(res.msg);
}
}, error => {
this.$u.toast('服务器开小差了呢,请您稍后再试')
})
},
goDetail(index,i){
console.log("111")
let deviceObj = this.dataList[index];
let channeObj = this.dataList[index].channelList[i];
if(channeObj.hdlUrl){
uni.navigateTo({
url:'./video-detail?deviceObj='+encodeURIComponent(JSON.stringify(deviceObj))+ '&channeObj='+encodeURIComponent(JSON.stringify(channeObj))
})
}else{
this.$u.toast('获取通道地址错误')
}
}
}
}
</script>
<style lang="less">
.box-title{
padding: 10rpx 24rpx;
}
/deep/ .u-collapse-head{
border: 1px solid #f5f5f5;
}
/deep/ .u-collapse-content{
// padding: 20rpx;
}
.box-item{
<style lang="less" scoped>
.video-list-box{
min-height: 100%;
background: #f2f1f6;
padding: 20rpx;
font-size: 30rpx;
.video-list{
.video-item{
background: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
.item-header{
height: 80rpx;
border-bottom: 1px solid #f2f1f6;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20rpx;
}
.item-content{
padding: 20rpx;
.content-title-box{
display: flex;
align-items: center;
margin-bottom: 10rpx;
.content-title-box-left{
background: #f6f6f6;
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10rpx;
border-radius: 4px;
.iconfont{
font-size: 60rpx;
color: #2979ff;
}
}
.content-title-box-right{
display: flex;
flex-direction: column;
justify-content: space-around;
.content-title-txt{
font-weight: bold;
}
.content-title-info{
font-size: 22rpx;
color: #bbb;
}
}
}
.item-content-list{
display: flex;
align-items: center;
justify-content: space-between;
.item-content-list-left{
.item-content-item{
font-size: 24rpx;
line-height: 40rpx;
}
}
}
}
.item-footer{
width: 100%;
.channel-item{
width: 100%;
display: flex;
justify-content: space-between;
padding: 20rpx;
border-bottom: 1px dashed #f2f1f6;
&:last-child{
border-bottom: none;
}
.channel-item-left{
display: flex;
align-items: center;
.iconfont{
color: #2979ff;
margin-right: 10rpx;
}
.channel-name{
font-weight: bold;
margin-right: 10rpx;
}
.channel-status{
}
}
}
}
}
}
}
</style>