<template>
|
<div class="container">
|
<!-- 布局控制及播放地址选择 -->
|
<div class="layout-controls">
|
<el-select
|
v-model="selectedUrl"
|
placeholder="选择播放地址"
|
class="left-control"
|
style="width: 200px; margin-right: 20px"
|
@change="handleUrlChange"
|
:disabled="activeIndex === -1"
|
>
|
<el-option
|
v-for="item in playbackOptions"
|
:key="item.videoId"
|
:label="item.deviceName"
|
:value="item.videoId"
|
/>
|
</el-select>
|
<el-button-group class="right-control">
|
<el-button
|
:type="gridLayout === 1 ? 'primary' : ''"
|
@click="changeLayout(1)"
|
>
|
单格
|
</el-button>
|
<el-button
|
:type="gridLayout === 4 ? 'primary' : ''"
|
@click="changeLayout(4)"
|
>
|
四格
|
</el-button>
|
<el-button
|
:type="gridLayout === 9 ? 'primary' : ''"
|
@click="changeLayout(9)"
|
>
|
九格
|
</el-button>
|
</el-button-group>
|
</div>
|
|
<!-- 视频网格布局 -->
|
<el-row :gutter="5">
|
<el-col
|
v-for="(item, index) in showVideos"
|
:key="index"
|
:span="colSpan"
|
class="video-col"
|
:class="{ active: activeIndex === index }"
|
>
|
<div class="video-container"
|
@click="handleGridClick(index)">
|
<!-- 纯黑背景封面 -->
|
<div
|
class="video-cover"
|
v-show="!item.playing"
|
style="pointer-events: none"
|
/>
|
|
<!-- 视频播放器 -->
|
<iframe
|
v-show="item.playing"
|
class="video-iframe"
|
:src="item.url"
|
frameborder="0"
|
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
allowfullscreen
|
style="pointer-events: none"
|
></iframe>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</template>
|
|
<script>
|
import camera from "@/api/SurveyView"
|
export default {
|
name: 'cameraVideo',
|
data() {
|
return {
|
iframeUrl:'',
|
gridLayout: 1,
|
activeIndex: -1,
|
selectedUrl: '',
|
playbackOptions: [
|
{
|
label: '摄像头1',
|
value: 'rtsp://Admin:1234@192.168.1.209/h264'
|
},
|
{
|
label: '摄像头2',
|
value: 'http://example.com/another-video-source'
|
}
|
],
|
allVideos: Array(9).fill(null).map((_, i) => ({
|
title: `视频 ${i + 1}`,
|
url: '',
|
playing: false
|
}))
|
}
|
},
|
computed: {
|
showVideos() {
|
return this.allVideos.slice(0, this.gridLayout)
|
},
|
colSpan() {
|
return 24 / Math.sqrt(this.gridLayout)
|
}
|
},
|
mounted() {
|
this.fetchSelect();
|
this.fetchCameraInfo()
|
},
|
methods: {
|
async fetchCameraInfo() {
|
const response = await fetch('/config.json');
|
if (!response.ok) throw new Error(`请求失败: ${response.status}`);
|
const responseData = await response.json();
|
this.iframeUrl = responseData.iframeUrl;
|
console.info(this.iframeUrl)
|
},
|
async fetchSelect(){
|
const cameras = await camera.getCameras();//视频点位
|
this.playbackOptions = cameras.data
|
},
|
changeLayout(num) {
|
this.gridLayout = num
|
this.activeIndex = -1
|
this.resetAllVideos()
|
},
|
handleGridClick(index) {
|
this.activeIndex = index
|
console.info('点击事件生效')
|
},
|
handleUrlChange(val) {
|
console.info(process.env.NODE_ENV)
|
if (this.activeIndex === -1) return
|
// console.info('点击选中的数据:'+this.playbackOptions.find(item => item.videoId === val).rtspAddress)
|
const currentVideo = this.allVideos[this.activeIndex]
|
currentVideo.url = this.iframeUrl+`/view/cameraPlayer/index.html?rtspUrl=${encodeURIComponent(this.playbackOptions.find(item => item.videoId === val).rtspAddress)}`
|
currentVideo.playing = true
|
|
console.info("地址:"+currentVideo.url)
|
},
|
resetAllVideos() {
|
this.allVideos.forEach((video, index) => {
|
if (index >= this.gridLayout) {
|
video.playing = false
|
video.url = ''
|
}
|
})
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
/* 简化后的样式 */
|
.container {
|
padding-top: 80px;
|
position: relative;
|
}
|
|
.layout-controls {
|
position: absolute;
|
left: 60px;
|
right: 60px; /* 新增右侧对齐 */
|
top: 20px;
|
z-index: 1000;
|
display: flex;
|
justify-content: space-between; /* 关键属性 */
|
align-items: center;
|
}
|
/* 移除原有的 margin-right */
|
.el-select {
|
width: 200px;
|
}
|
/* 可选:防止按钮组换行 */
|
.el-button-group {
|
flex-shrink: 0;
|
}
|
|
.video-col {
|
position: relative;
|
margin-bottom: 5px;
|
transition: all 0.3s;
|
min-height: 100px;
|
}
|
|
.video-col.active::after {
|
content: '';
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
border: 3px solid #409EFF;
|
pointer-events: none;
|
z-index: 2;
|
}
|
|
.video-container {
|
position: relative;
|
width: 100%;
|
height: 0;
|
padding-top: 56.25%;
|
cursor: pointer;
|
background-color: #000;
|
overflow: hidden;
|
}
|
|
.video-cover {
|
pointer-events: none; /* 允许事件穿透 */
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background-color: #000; /* 纯黑背景 */
|
}
|
|
.video-iframe {
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background: #000;
|
pointer-events: none;
|
}
|
</style>
|