parent
5c2ed7256a
commit
e19fe4f585
@ -0,0 +1,215 @@ |
|||||||
|
<script setup> |
||||||
|
import { reactive,onMounted } from 'vue' |
||||||
|
import { getRtspUrl,getDevicePage,getPlaybackByTimeRtspUrl,getRegularVideoRecords } from './api' |
||||||
|
import { ElMessage } from 'element-plus' |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
currentCameraIndex: 0, |
||||||
|
cameraList: [], |
||||||
|
cameraInfo: null |
||||||
|
}) |
||||||
|
const switchCamera = (index)=>{ |
||||||
|
state.currentCameraIndex = index; |
||||||
|
startVideo(); |
||||||
|
} |
||||||
|
const startVideo = () => { |
||||||
|
let index = state.currentCameraIndex; |
||||||
|
let channelCode = state.cameraList[index].units && state.cameraList[index].units[0].channels[0].channelCode; |
||||||
|
if(!channelCode){ |
||||||
|
ElMessage({ |
||||||
|
message: '设备异常', |
||||||
|
type: 'error' |
||||||
|
}) |
||||||
|
return; |
||||||
|
} |
||||||
|
getRtspUrl({ |
||||||
|
data: { |
||||||
|
channelId: channelCode, |
||||||
|
dataType: "1", |
||||||
|
streamType: "1" |
||||||
|
} |
||||||
|
}).then(res=>{ |
||||||
|
state.cameraInfo = { |
||||||
|
channelId: channelCode, |
||||||
|
url: res.data.url, |
||||||
|
token: res.data.token |
||||||
|
} |
||||||
|
//发送消息给子页面 |
||||||
|
let video = document.getElementById('video') |
||||||
|
video.contentWindow.postMessage({ |
||||||
|
type: 'startVideo', |
||||||
|
data: {...state.cameraInfo} |
||||||
|
}, '*') |
||||||
|
}) |
||||||
|
} |
||||||
|
const playRecord = (date) => { |
||||||
|
let index = state.currentCameraIndex; |
||||||
|
let channelCode = state.cameraList[index].units && state.cameraList[index].units[0].channels[0].channelCode; |
||||||
|
if(!channelCode){ |
||||||
|
ElMessage({ |
||||||
|
message: '设备异常', |
||||||
|
type: 'error' |
||||||
|
}) |
||||||
|
return; |
||||||
|
} |
||||||
|
//获取当日的开始时间和结束时间 |
||||||
|
let current = new Date(date); |
||||||
|
let startTime = parseInt(current.setHours(0, 0, 0, 0)/1000); |
||||||
|
let endTime = parseInt(current.setHours(23, 59, 59, 999)/1000); |
||||||
|
getRegularVideoRecords({ |
||||||
|
data: { |
||||||
|
channelId: channelCode, |
||||||
|
recordSource: '1', |
||||||
|
startTime, |
||||||
|
endTime, |
||||||
|
streamType: "1", |
||||||
|
recordType: "1" |
||||||
|
} |
||||||
|
}).then(res=>{ |
||||||
|
console.log('res :>> ', res); |
||||||
|
let records = res.data.records; |
||||||
|
getPlaybackByTimeRtspUrl({ |
||||||
|
data: { |
||||||
|
channelId: records[0].channelId, |
||||||
|
recordSource: records[0].recordSource, |
||||||
|
startTime: records[0].startTime, |
||||||
|
endTime: records[0].endTime, |
||||||
|
streamType: records[0].streamType, |
||||||
|
recordType: records[0].recordType |
||||||
|
} |
||||||
|
}).then(res=>{ |
||||||
|
let recordInfo = { |
||||||
|
records: records, |
||||||
|
channelId: records[0].channelId, |
||||||
|
url: res.data.url, |
||||||
|
token: res.data.token, |
||||||
|
startTime: records[0].startTime, |
||||||
|
endTime: records[0].endTime, |
||||||
|
streamType: records[0].streamType, |
||||||
|
recordType: records[0].recordType |
||||||
|
} |
||||||
|
//发送消息给子页面 |
||||||
|
let video = document.getElementById('video') |
||||||
|
console.log('video :>> ', video); |
||||||
|
video.contentWindow.postMessage({ |
||||||
|
type: 'playRecord', |
||||||
|
data: JSON.parse(JSON.stringify(recordInfo)) |
||||||
|
}, '*') |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
onMounted(() => { |
||||||
|
getDevicePage({ |
||||||
|
"pageNum": 1, |
||||||
|
"pageSize": 100, |
||||||
|
}).then((res) => { |
||||||
|
state.cameraList = res.data.pageData |
||||||
|
}).catch((err) => { |
||||||
|
|
||||||
|
}); |
||||||
|
// 监听子页面的消息 |
||||||
|
window.addEventListener('message', (event) => { |
||||||
|
console.log('event :>> ', event.data); |
||||||
|
if (event.data.type === 'startVideo') { |
||||||
|
startVideo(); |
||||||
|
}else if(event.data.type ==='playRecord'){ |
||||||
|
playRecord(event.data.date); |
||||||
|
} |
||||||
|
}); |
||||||
|
}) |
||||||
|
|
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="app-container"> |
||||||
|
<!-- 监控摄像头名称列表 --> |
||||||
|
<div class="camera-name-list"> |
||||||
|
<template v-for="(camera, index) in state.cameraList" :key="index"> |
||||||
|
<span |
||||||
|
class="camera-name" |
||||||
|
@click="switchCamera(index)" |
||||||
|
:class="{ active: state.currentCameraIndex === index }" |
||||||
|
> |
||||||
|
{{ camera.deviceName }} |
||||||
|
<el-tag style="scale: 0.8;position: absolute;top: -10px;right:-15px;border-radius: 20px;" :type="camera.isOnline == 1 ? 'success':'danger'">{{ camera.isOnline == 1 ? '在线' : '离线' }}</el-tag> |
||||||
|
</span> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
<!-- 摄像头展示区域 --> |
||||||
|
<div class="camera-display"> |
||||||
|
<iframe id="video" src="/dahua/demo.html?real=true" style="width:100%;height:100%;" frameborder="0"></iframe> |
||||||
|
<!-- <video |
||||||
|
v-if="state.currentCameraIndex !== -1" |
||||||
|
:src="cameraList[state.currentCameraIndex].source" |
||||||
|
controls |
||||||
|
autoplay |
||||||
|
muted |
||||||
|
></video> --> |
||||||
|
<!-- <p v-else>请选择摄像头</p> --> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.app-container { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
align-items: center; |
||||||
|
padding: 20px; |
||||||
|
height: calc(100vh - 135px); |
||||||
|
} |
||||||
|
|
||||||
|
.camera-name-list { |
||||||
|
display: flex; |
||||||
|
gap: 15px; |
||||||
|
margin-bottom: 20px; |
||||||
|
flex-wrap: wrap; |
||||||
|
justify-content: center; |
||||||
|
width: 130px; |
||||||
|
height: 100%; |
||||||
|
overflow-y: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.camera-name { |
||||||
|
padding: 8px 32px; |
||||||
|
border: 1px solid #ccc; |
||||||
|
border-radius: 20px; |
||||||
|
cursor: pointer; |
||||||
|
transition: all 0.3s ease; |
||||||
|
background-color: white; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.camera-name:hover { |
||||||
|
background-color: #e0e0e0; |
||||||
|
transform: translateY(-2px); |
||||||
|
} |
||||||
|
|
||||||
|
.camera-name.active { |
||||||
|
background-color: #2196F3; |
||||||
|
color: white; |
||||||
|
border-color: #2196F3; |
||||||
|
} |
||||||
|
|
||||||
|
.camera-display { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
box-sizing: border-box; |
||||||
|
background-color: #fff; |
||||||
|
padding: 20px; |
||||||
|
border-radius: 8px; |
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
||||||
|
} |
||||||
|
|
||||||
|
video { |
||||||
|
width: 100%; |
||||||
|
height: auto; |
||||||
|
} |
||||||
|
|
||||||
|
p { |
||||||
|
text-align: center; |
||||||
|
color: #666; |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue