|
|
@@ -218,10 +218,10 @@
|
|
|
<a-button :icon="h(PoweroffOutlined)" @click="onDeviceStopLive" />
|
|
|
</a-tooltip>
|
|
|
</div>
|
|
|
- <div v-if="false">
|
|
|
+ <div v-if="deviceLive.cameraValue && deviceLive.playerUrl">
|
|
|
<div style="display: flex;margin-top: 10px;">
|
|
|
- <a-select style="width: 120px;margin-right: 5px;" placeholder="相机类型"
|
|
|
- v-model:value="payload.camera_type">
|
|
|
+ <a-select style="width: 120px;margin-right: 5px;" placeholder="镜头类型"
|
|
|
+ v-model:value="payload.camera_type" @change="onChangeCameraType">
|
|
|
<a-select-option value="wide">
|
|
|
广角
|
|
|
</a-select-option>
|
|
|
@@ -230,7 +230,7 @@
|
|
|
</a-select-option>
|
|
|
</a-select>
|
|
|
<a-select style="width: 120px;margin-right: 5px;" placeholder="重置云台"
|
|
|
- v-model:value="payload.reset_mode">
|
|
|
+ v-model:value="payload.reset_mode" @change="onChangeResetMode">
|
|
|
<a-select-option :value="0">
|
|
|
回中
|
|
|
</a-select-option>
|
|
|
@@ -244,7 +244,8 @@
|
|
|
俯仰向下
|
|
|
</a-select-option>
|
|
|
</a-select>
|
|
|
- <a-select style="width: 120px;" placeholder="相机模式" v-model:value="payload.camera_mode">
|
|
|
+ <a-select style="width: 120px;" placeholder="相机模式" v-model:value="payload.camera_mode"
|
|
|
+ @change="onChangeCameraMode">
|
|
|
<a-select-option :value="0">
|
|
|
拍照
|
|
|
</a-select-option>
|
|
|
@@ -258,18 +259,28 @@
|
|
|
</div>
|
|
|
<div style="display: flex;align-items: center;padding-left: 10px;margin-top: 10px;">
|
|
|
<a-slider style="width: 200px;" :marks="payload.marks" :included="false" :min="2" :max="56"
|
|
|
- v-model:value="payload.zoom_factor" />
|
|
|
+ v-model:value="payload.zoom_factor" :disabled="payload.camera_type !== 'zoom'"
|
|
|
+ @change="onChangeZoomFactor" />
|
|
|
<div style="margin-left: 40px;">
|
|
|
- <a-tooltip title="拍摄" v-if="payload.camera_mode === 1">
|
|
|
+ <a-tooltip title="全景拍照" v-if="payload.camera_mode === 3">
|
|
|
+ <img style="width:40px;height:40px;cursor: pointer;" :src="videoSrc"
|
|
|
+ v-if="!payload.take.pictureStatus" @click="startTakePhoto" />
|
|
|
+ <img style="width:40px;height:40px;cursor: pointer;" :src="videoStopSrc" v-else
|
|
|
+ @click="stopTakePhoto" />
|
|
|
+ </a-tooltip>
|
|
|
+ <a-tooltip title="录像" v-else-if="payload.camera_mode === 1">
|
|
|
<div style="text-align: center;">
|
|
|
- <img style="width:40px;height:40px;cursor: pointer;" :src="videoSrc">
|
|
|
+ <img style="width:40px;height:40px;cursor: pointer;" :src="videoSrc"
|
|
|
+ v-if="!payload.take.videoStatus" @click="startTakeVideo" />
|
|
|
+ <img style="width:40px;height:40px;cursor: pointer;" :src="videoStopSrc" v-else
|
|
|
+ @click="stopTakeVideo" />
|
|
|
<div style="margin-top: 5px;">
|
|
|
- 00:00
|
|
|
+ {{ formatTakeTime }}
|
|
|
</div>
|
|
|
</div>
|
|
|
</a-tooltip>
|
|
|
- <a-tooltip title="拍摄" v-else>
|
|
|
- <img style="width: 40px;height:40px;cursor: pointer;" :src="pictureSrc">
|
|
|
+ <a-tooltip title="拍照" v-else>
|
|
|
+ <img style="width: 40px;height:40px;cursor: pointer;" :src="pictureSrc" @click="startTakePhoto" />
|
|
|
</a-tooltip>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -422,7 +433,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { h, computed, reactive, ref, onMounted } from 'vue';
|
|
|
+import { h, computed, reactive, onMounted, watch } from 'vue';
|
|
|
import { message } from 'ant-design-vue';
|
|
|
import { CloseOutlined, PlaySquareOutlined, PoweroffOutlined } from '@ant-design/icons-vue'
|
|
|
import LivePlayer from '/@/components/livePlayer/index.vue';
|
|
|
@@ -442,6 +453,7 @@ import aircraftSrc from '../icons/aircraft.svg';
|
|
|
import aircraftSelectedSrc from '../icons/aircraft_selected.svg';
|
|
|
import pictureSrc from '../icons/info/picture.png';
|
|
|
import videoSrc from '../icons/info/video.png';
|
|
|
+import videoStopSrc from '../icons/info/video_stop.png';
|
|
|
import controllerSrc from '../icons/info/controller.svg';
|
|
|
import controllerErrorSrc from '../icons/info/controllerError.svg';
|
|
|
import fourGSrc from '../icons/info/fourG.svg';
|
|
|
@@ -463,6 +475,7 @@ import { getLiveCapacity, startLivestream, stopLivestream } from '/@/api/manage'
|
|
|
import DockControlPanel from '../../g-map/DockControlPanel.vue'
|
|
|
import DroneControlPanel from '../../g-map/DroneControlPanel.vue'
|
|
|
import { useDockControl } from '../../g-map/use-dock-control';
|
|
|
+import { usePayloadControl } from '../../g-map/use-payload-control';
|
|
|
import { useMyStore } from '/@/store';
|
|
|
import { getTextByModeCode, getTextByDockModeCode, getWindDirection } from '/@/utils/index'
|
|
|
import EventBus from '/@/event-bus'
|
|
|
@@ -482,6 +495,20 @@ const store = useMyStore()
|
|
|
// 机场控制面板
|
|
|
const { dockControlPanelVisible, setDockControlPanelVisible, onCloseControlPanel, sendDockControlCmd } = useDockControl();
|
|
|
|
|
|
+// 飞机负载控制
|
|
|
+const {
|
|
|
+ checkPayloadAuth,// 检查负载控制
|
|
|
+ authPayload,// 获取负载控制
|
|
|
+ changeLiveLens,// 设置直播镜头
|
|
|
+ resetGimbal,// 重置云台
|
|
|
+ changeCameraFocalLength,// 变焦
|
|
|
+ switchCameraMode,// 切换相机模式
|
|
|
+ startTakeCameraPhoto,// 开始拍照
|
|
|
+ stopTakeCameraPhoto,// 结束拍照
|
|
|
+ startCameraRecording,// 开始录像
|
|
|
+ stopCameraRecording,// 结束录像
|
|
|
+} = usePayloadControl()
|
|
|
+
|
|
|
const hmsInfo = computed(() => store.state.hmsInfo);
|
|
|
|
|
|
// 适合飞行
|
|
|
@@ -734,10 +761,24 @@ const deviceLive: DeviceLive = reactive({
|
|
|
playerUrl: '',
|
|
|
})
|
|
|
|
|
|
-const payload = reactive({
|
|
|
- camera_type: 'wide',// 相机类型
|
|
|
- reset_mode: 0,// 重置云台
|
|
|
- camera_mode: 0,// 相机模式
|
|
|
+interface Payload {
|
|
|
+ camera_type: 'wide' | 'zoom',
|
|
|
+ reset_mode?: number,
|
|
|
+ camera_mode?: number,
|
|
|
+ marks: any,
|
|
|
+ zoom_factor: number,
|
|
|
+ take: {
|
|
|
+ pictureStatus: boolean,
|
|
|
+ videoStatus: boolean,
|
|
|
+ time: number,
|
|
|
+ timer: any,
|
|
|
+ },
|
|
|
+}
|
|
|
+
|
|
|
+const payload = reactive<Payload>({
|
|
|
+ camera_type: 'wide',// 镜头类型
|
|
|
+ reset_mode: undefined,// 重置云台
|
|
|
+ camera_mode: undefined,// 相机模式
|
|
|
marks: {
|
|
|
2: '2倍',
|
|
|
14: '14倍',
|
|
|
@@ -746,6 +787,19 @@ const payload = reactive({
|
|
|
56: '56倍',
|
|
|
},
|
|
|
zoom_factor: 2,// 变焦倍数
|
|
|
+ take: {
|
|
|
+ pictureStatus: false,
|
|
|
+ videoStatus: false,
|
|
|
+ time: 0,
|
|
|
+ timer: undefined,
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const formatTakeTime = computed(() => {
|
|
|
+ const totalSeconds = payload.take.time;
|
|
|
+ const minutes = Math.floor(totalSeconds / 60);
|
|
|
+ const seconds = totalSeconds % 60;
|
|
|
+ return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
|
|
});
|
|
|
|
|
|
const fetchLiveCapacity = async () => {
|
|
|
@@ -858,6 +912,18 @@ const onDockStopLive = async () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 点击一键返航
|
|
|
+const onClickReturnHome = async () => {
|
|
|
+ try {
|
|
|
+ await sendDockControlCmd({
|
|
|
+ sn: props.osdInfo.gateway_sn,
|
|
|
+ cmd: 'return_home' as any,
|
|
|
+ }, false)
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const onDeviceCameraSelect = (record: SelectOption) => {
|
|
|
deviceLive.cameraValue = record.value;
|
|
|
if (!record.more) {
|
|
|
@@ -899,6 +965,12 @@ const onDeviceStartLive = async () => {
|
|
|
deviceLive.playerText = '';
|
|
|
deviceLive.playerUrl = playerUrl;
|
|
|
message.success('已开启直播');
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ // 获取负载控制
|
|
|
+ await authPayload(sn, cameraValue as string);
|
|
|
+ // console.log(props.deviceInfo?.device, 'props.deviceInfo');
|
|
|
+ // 更改镜头类型
|
|
|
+ await onChangeCameraType('wide');
|
|
|
}
|
|
|
} catch (e: any) {
|
|
|
console.error(e);
|
|
|
@@ -921,16 +993,99 @@ const onDeviceStopLive = async () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 点击一键返航
|
|
|
-const onClickReturnHome = async () => {
|
|
|
- try {
|
|
|
- await sendDockControlCmd({
|
|
|
- sn: props.osdInfo.gateway_sn,
|
|
|
- cmd: 'return_home' as any,
|
|
|
- }, false)
|
|
|
- } catch (error) {
|
|
|
- console.error(error);
|
|
|
+// 更改镜头类型
|
|
|
+const onChangeCameraType = async (cameraType: Payload['camera_type']) => {
|
|
|
+ payload.camera_type = cameraType;
|
|
|
+ const data = {
|
|
|
+ video_id: deviceLive.videoId,
|
|
|
+ video_type: cameraType,
|
|
|
+ }
|
|
|
+ await changeLiveLens(data);
|
|
|
+}
|
|
|
+
|
|
|
+// 更改重置云台
|
|
|
+const onChangeResetMode = async (resetMode: Payload['reset_mode']) => {
|
|
|
+ const data = {
|
|
|
+ payload_index: deviceLive.cameraValue as string,
|
|
|
+ reset_mode: resetMode as any,
|
|
|
+ }
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ await resetGimbal(sn, data);
|
|
|
+}
|
|
|
+
|
|
|
+// 更改相机模式
|
|
|
+const onChangeCameraMode = async (cameraMode: Payload['camera_mode']) => {
|
|
|
+ const data = {
|
|
|
+ payload_index: deviceLive.cameraValue as string,
|
|
|
+ camera_mode: cameraMode as any,
|
|
|
+ }
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ await switchCameraMode(sn, data);
|
|
|
+}
|
|
|
+
|
|
|
+// 更改变焦倍数
|
|
|
+const onChangeZoomFactor = async (zoomFactor: number) => {
|
|
|
+ const data = {
|
|
|
+ payload_index: deviceLive.cameraValue as string,
|
|
|
+ camera_type: 'zoom' as any,
|
|
|
+ zoom_factor: zoomFactor,
|
|
|
+ }
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ await changeCameraFocalLength(sn, data);
|
|
|
+}
|
|
|
+
|
|
|
+watch(() => props.deviceInfo, (newValue) => {
|
|
|
+ if (!newValue) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ const cameras = newValue.device.cameras;
|
|
|
+ if (cameras && cameras.length > 0) {
|
|
|
+ const cameraInfo = cameras[0];
|
|
|
+ // 拍照状态
|
|
|
+ const photoState = cameraInfo.photo_state;
|
|
|
+ payload.take.pictureStatus = !!photoState;
|
|
|
+ // 录像状态
|
|
|
+ const recordingState = cameraInfo.recording_state;
|
|
|
+ payload.take.videoStatus = !!recordingState;
|
|
|
+ if (!recordingState) {
|
|
|
+ payload.take.time = 0;
|
|
|
+ clearInterval(payload.take.timer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}, { deep: true });
|
|
|
+
|
|
|
+// 开始拍照
|
|
|
+const startTakePhoto = async () => {
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ const payloadIndex = deviceLive.cameraValue as string;
|
|
|
+ await startTakeCameraPhoto(sn, payloadIndex);
|
|
|
+}
|
|
|
+
|
|
|
+// 结束拍照
|
|
|
+const stopTakePhoto = async () => {
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ const payloadIndex = deviceLive.cameraValue as string;
|
|
|
+ await stopTakeCameraPhoto(sn, payloadIndex);
|
|
|
+}
|
|
|
+
|
|
|
+// 开始录像
|
|
|
+const startTakeVideo = async () => {
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ const payloadIndex = deviceLive.cameraValue as string;
|
|
|
+ const res = await startCameraRecording(sn, payloadIndex);
|
|
|
+ if (res) {
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ payload.take.time = payload.take.time + 1;
|
|
|
+ }, 1000);
|
|
|
+ payload.take.timer = timer;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 结束录像
|
|
|
+const stopTakeVideo = async () => {
|
|
|
+ const sn = props.osdInfo.gateway_sn;
|
|
|
+ const payloadIndex = deviceLive.cameraValue as string;
|
|
|
+ await stopCameraRecording(sn, payloadIndex);
|
|
|
}
|
|
|
</script>
|
|
|
|