|
|
|
|
@ -1,56 +1,83 @@
|
|
|
|
|
<template>
|
|
|
|
|
<view class="container">
|
|
|
|
|
<picker mode="selector" :range="cameras" range-key="name" @change="handleCameraChange">
|
|
|
|
|
<button>选择相机</button>
|
|
|
|
|
<button>{{ currentCamera ? currentCamera.name : '选择相机' }}</button>
|
|
|
|
|
</picker>
|
|
|
|
|
<video id="myVideo" ref="videoPlayer" :src="streamUrl" autoplay muted controls
|
|
|
|
|
style="width: 100%; height: 50%;" @fullscreenchange="handleFullscreenChange"></video>
|
|
|
|
|
<video id="myVideo" ref="videoPlayer" :src="streamUrl" autoplay muted controls style="width: 100%; height: 50%;"
|
|
|
|
|
@fullscreenchange="handleFullscreenChange"></video>
|
|
|
|
|
|
|
|
|
|
<!-- 云台控制面板 -->
|
|
|
|
|
<view class="ptz-control" :class="{ 'ptz-control-fullscreen': isFullscreen }">
|
|
|
|
|
<view class="direction-list">
|
|
|
|
|
<view class="operation-item">
|
|
|
|
|
<u-icon name="minus" :size=" 40" @touchstart="handleControl('zoomSub', 'start')" @touchend="handleControl('zoomSub', 'stop')" @touchcancel="handleControl('zoomSub', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="minus" :size="40" @touchstart="handleControl('zoomSub', 'start')"
|
|
|
|
|
@touchend="handleControl('zoomSub', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('zoomSub', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<span>变倍</span>
|
|
|
|
|
<view class="operation-item">
|
|
|
|
|
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('zoomAdd', 'start')" @touchend="handleControl('zoomAdd', 'stop')" @touchcancel="handleControl('zoomAdd', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('zoomAdd', 'start')"
|
|
|
|
|
@touchend="handleControl('zoomAdd', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('zoomAdd', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="operation-item">
|
|
|
|
|
<u-icon name="minus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusSub', 'start')" @touchend="handleControl('focusSub', 'stop')" @touchcancel="handleControl('focusSub', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="minus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusSub', 'start')"
|
|
|
|
|
@touchend="handleControl('focusSub', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('focusSub', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<span>变焦</span>
|
|
|
|
|
<view class="operation-item">
|
|
|
|
|
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusAdd', 'start')" @touchend="handleControl('focusAdd', 'stop')" @touchcancel="handleControl('focusAdd', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusAdd', 'start')"
|
|
|
|
|
@touchend="handleControl('focusAdd', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('focusAdd', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<image src="@/static/tabbar/icon/箭头_左上.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('leftUp', 'start')" @touchend="handleControl('leftUp', 'stop')" @touchcancel="handleControl('leftUp', 'stop')"></image>
|
|
|
|
|
<image src="@/static/tabbar/icon/l_u.png"
|
|
|
|
|
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px', opacity: activeButton === 'leftUp' ? 0.7 : 1 }"
|
|
|
|
|
@touchstart="handleControl('leftUp', 'start')" @touchend="handleControl('leftUp', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('leftUp', 'stop')"></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<u-icon name="arrow-up" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('up', 'start')" @touchend="handleControl('up', 'stop')" @touchcancel="handleControl('up', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="arrow-up" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('up', 'start')"
|
|
|
|
|
@touchend="handleControl('up', 'stop')" @touchcancel="handleControl('up', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<image src="@/static/tabbar/icon/箭头_右上.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('rightUp', 'start')" @touchend="handleControl('rightUp', 'stop')" @touchcancel="handleControl('rightUp', 'stop')"></image>
|
|
|
|
|
<image src="@/static/tabbar/icon/r_u.png"
|
|
|
|
|
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
|
|
|
|
|
@touchstart="handleControl('rightUp', 'start')" @touchend="handleControl('rightUp', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('rightUp', 'stop')"></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<u-icon name="arrow-left" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('left', 'start')" @touchend="handleControl('left', 'stop')" @touchcancel="handleControl('left', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="arrow-left" :size="isFullscreen ? 40 : 40"
|
|
|
|
|
@touchstart="handleControl('left', 'start')" @touchend="handleControl('left', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('left', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<u-icon :size="isFullscreen ? 40 : 40" @click="refresh"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<u-icon name="arrow-right" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('right', 'start')" @touchend="handleControl('right', 'stop')" @touchcancel="handleControl('right', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="arrow-right" :size="isFullscreen ? 40 : 40"
|
|
|
|
|
@touchstart="handleControl('right', 'start')" @touchend="handleControl('right', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('right', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<image src="@/static/tabbar/icon/箭头_左下.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('leftDown', 'start')" @touchend="handleControl('leftDown', 'stop')" @touchcancel="handleControl('leftDown', 'stop')"></image>
|
|
|
|
|
<image src="@/static/tabbar/icon/l_d.png"
|
|
|
|
|
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
|
|
|
|
|
@touchstart="handleControl('leftDown', 'start')" @touchend="handleControl('leftDown', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('leftDown', 'stop')"></image>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<u-icon name="arrow-down" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('down', 'start')" @touchend="handleControl('down', 'stop')" @touchcancel="handleControl('down', 'stop')"></u-icon>
|
|
|
|
|
<u-icon name="arrow-down" :size="isFullscreen ? 40 : 40"
|
|
|
|
|
@touchstart="handleControl('down', 'start')" @touchend="handleControl('down', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('down', 'stop')"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="direction-item">
|
|
|
|
|
<image src="@/static/tabbar/icon/箭头_右下.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('rightDown', 'start')" @touchend="handleControl('rightDown', 'stop')" @touchcancel="handleControl('rightDown', 'stop')"></image>
|
|
|
|
|
<image src="@/static/tabbar/icon/r_d.png"
|
|
|
|
|
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
|
|
|
|
|
@touchstart="handleControl('rightDown', 'start')" @touchend="handleControl('rightDown', 'stop')"
|
|
|
|
|
@touchcancel="handleControl('rightDown', 'stop')"></image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
@ -103,11 +130,11 @@
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
updateStreamUrl() {
|
|
|
|
|
const currentIp = window.location.hostname;
|
|
|
|
|
const ipAddres = uni.getStorageSync('IP_ADDRESS');
|
|
|
|
|
const isH5 = uni.getSystemInfoSync().platform === 'h5';
|
|
|
|
|
const protocol = isH5 ? 'http' : 'rtmp';
|
|
|
|
|
const ext = isH5 ? '.m3u8' : '';
|
|
|
|
|
this.streamUrl = `${protocol}://${currentIp}/live/camera${this.currentCamera.id}${ext}`;
|
|
|
|
|
this.streamUrl = `${protocol}://${ipAddres}/live/camera${this.currentCamera.id}${ext}`;
|
|
|
|
|
console.log(this.streamUrl)
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.videoPlayer.play();
|
|
|
|
|
@ -119,9 +146,19 @@
|
|
|
|
|
this.updateStreamUrl();
|
|
|
|
|
},
|
|
|
|
|
// 云台控制方法
|
|
|
|
|
handleControl(action, state) {
|
|
|
|
|
async handleControl(action, state) {
|
|
|
|
|
console.log(`${action}-${state}`);
|
|
|
|
|
const data = { id: this.currentCamera.id };
|
|
|
|
|
const data = {
|
|
|
|
|
id: this.currentCamera.id
|
|
|
|
|
};
|
|
|
|
|
const res = await request({
|
|
|
|
|
url: '/admin-api/camera/control/' + action + '/' + state,
|
|
|
|
|
method: 'POST',
|
|
|
|
|
data: {
|
|
|
|
|
id: this.currentCamera.id
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 刷新画面
|
|
|
|
|
refresh() {
|
|
|
|
|
@ -141,6 +178,7 @@
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 85vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 云台控制面板样式 */
|
|
|
|
|
.ptz-control {
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
@ -149,6 +187,7 @@
|
|
|
|
|
padding: 5px;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ptz-control-fullscreen {
|
|
|
|
|
position: fixed;
|
|
|
|
|
bottom: 10px;
|
|
|
|
|
@ -157,19 +196,24 @@
|
|
|
|
|
width: 80%;
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.direction-list {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
gap: 3px;
|
|
|
|
|
justify-items: center;
|
|
|
|
|
}
|
|
|
|
|
.operation-item, .direction-item {
|
|
|
|
|
|
|
|
|
|
.operation-item,
|
|
|
|
|
.direction-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin: 3px;
|
|
|
|
|
}
|
|
|
|
|
.operation-item span, .direction-item span {
|
|
|
|
|
|
|
|
|
|
.operation-item span,
|
|
|
|
|
.direction-item span {
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
margin-top: 3px;
|
|
|
|
|
}
|
|
|
|
|
|