<!--
|
* @Author: husq 931347610@qq.com
|
* @Date: 2023-09-13 18:21:08
|
* @LastEditors: husq 931347610@qq.com
|
* @LastEditTime: 2023-09-14 11:40:03
|
* @FilePath: \Cloud-API-Demo-Web\src\pages\page-web\projects\components\DockConfig.vue
|
* @Description:
|
*
|
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
|
-->
|
<template>
|
<div class="config_dock">
|
<div class="w100 option flex-display">
|
<div class="option-left-icon flex-display">
|
<RobotOutlined :style="{ fontSize: '48px' }" />
|
<div style="margin-top: 10px;">Dock</div>
|
</div>
|
<div class="option-right">
|
<div class="wrapper">
|
<div class="wrapper-item flex-display">
|
<span class="item-left">设备空闲中</span>
|
<span class="item-right dock-status">当前正常</span>
|
</div>
|
|
<div class="wrapper-item flex-display">
|
<div class="item-left">
|
<CloudOutlined />
|
<span>正常</span>
|
</div>
|
<div class="item-right flex-display flex-align-center">
|
<span class="mr20">
|
<ThunderboltOutlined />
|
34°C
|
</span>
|
<span class="mr20">
|
<FundProjectionScreenOutlined />
|
436kb/s
|
</span>
|
<span class="mr20">
|
<UploadOutlined />
|
0
|
</span>
|
</div>
|
</div>
|
</div>
|
<div class="option-btn flex-display flex-justify-between">
|
<div class="btn">
|
<a-button type="primary" @click="control" :class="{ unchecked: !videoControl }"
|
style="width: 100%;">
|
<template #icon>
|
<VideoCameraOutlined />
|
</template>
|
监控
|
</a-button>
|
</div>
|
<div class="btn">
|
<a-button type="primary" @click="optionControl = !optionControl"
|
:class="{ unchecked: !optionControl }" style="width: 100%;">
|
<template #icon>
|
<ToolOutlined />
|
</template>
|
操作
|
</a-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="video" v-if="videoControl">
|
<!-- <div class="video-option">
|
<a-tooltip title="关闭补光灯"></a-tooltip>
|
</div> -->
|
<video auto src="https://cdn.jsdelivr.net/gh/xdlumia/files/video-play/IronMan.mp4"
|
style="width: 100%;height: 200px;" id="video-webrtc" ref="videowebrtc" controls class="mt20"></video>
|
</div>
|
<div class="w100 option flex-display aerial">
|
<div class="option-left-icon flex-display">
|
<RobotOutlined :style="{ fontSize: '48px' }" />
|
<div style="margin-top: 10px;">Dock</div>
|
</div>
|
<div class="option-right">
|
<div class="wrapper">
|
<div class="wrapper-item flex-display">
|
<span class="item-left">舱内关机</span>
|
<span class="item-right dock-status">N/A</span>
|
</div>
|
|
<div class="wrapper-item flex-display">
|
<span class="w100 text-center f12" style="color: #4e4e4e;">当前设备已关机,无法进行直播</span>
|
<!-- <div class="item-left">
|
<CloudOutlined />
|
<span>正常</span>
|
</div>
|
<div class="item-right flex-display flex-align-center">
|
<span class="mr20">
|
<ThunderboltOutlined />
|
34°C
|
</span>
|
</div> -->
|
</div>
|
</div>
|
<div class="option-btn flex-display flex-justify-between">
|
<div class="btn" style="width: 100%;">
|
<a-button type="primary" @click="flyControl = !flyControl" :class="{ unchecked: !flyControl }"
|
style="width: 100%;">
|
<template #icon>
|
<BoxPlotOutlined />
|
</template>
|
飞行控制
|
</a-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="takeoff flex-display flex-align-center">
|
<div class="takeoff-left mr15 flex-display flex-align-center flex-direction-column">
|
<RobotOutlined :style="{ fontSize: '28px' }" />
|
<div style="margin-top: 10px;">一键起飞</div>
|
</div>
|
<div class="divider"></div>
|
<div class="takeoff-middle"></div>
|
<div class="takeoff-right flex-display flex-justify-center flex-align-center flex-direction-column">
|
<div class="mb5 input-box flex-display flex-align-center">
|
<span class="f10 label mr15">安全离场高(ALT)</span>
|
<a-input size="small" class="input-style" suffix="m" v-model:value="option.safe_height" />
|
</div>
|
<div class="mb5 input-box flex-display flex-align-center">
|
<span class="f10 label mr15">飞行作业高(AGL)</span>
|
<a-input size="small" class="input-style" suffix="m" v-model:value="option.fly_height" />
|
</div>
|
<div class="mb5 input-box flex-display flex-align-center">
|
<span class="f10 label mr15">返航高(ALT)</span>
|
<a-input size="small" class="input-style" suffix="m" v-model:value="option.return_height" />
|
</div>
|
<div class="mb5 select-box flex-display flex-align-center">
|
<span class="f10 label mr15">失联动作</span>
|
<a-select :dropdownMatchSelectWidth="false" class="select-style" :bordered="false" size="small"
|
ref="select" v-model:value="option.lose_connection" style="width: 60px" @change="handleChange">
|
<a-select-option value="1">悬停</a-select-option>
|
<a-select-option value="2">返航</a-select-option>
|
<a-select-option value="3">继续执行</a-select-option>
|
</a-select>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { VideoCameraOutlined, RobotOutlined, ToolOutlined, CloudOutlined, ThunderboltOutlined, FundProjectionScreenOutlined, UploadOutlined, BoxPlotOutlined } from '@ant-design/icons-vue'
|
import { getLiveCapacity, setLivestreamQuality, startLivestream, stopLivestream } from '/@/api/manage'
|
import { message } from 'ant-design-vue'
|
import jswebrtc from '/@/vendors/jswebrtc.min.js'
|
import { CURRENT_CONFIG as config } from '/@/api/http/config'
|
const nonSwitchable = 'normal'
|
// 视频ref
|
const videowebrtc = ref(null)
|
// 是否显示视频
|
const videoControl = ref(false)
|
// 是否显示操作 页面暂未加
|
const optionControl = ref(false)
|
// 一键起飞操作
|
const flyControl = ref(false)
|
// 操作设置
|
const option = ref({
|
safe_height: 60,
|
fly_height: 60,
|
return_height: 60,
|
lose_connection: '1',
|
})
|
const handleChange = (e: string) => {
|
console.log(e, 'eee')
|
}
|
// 画质设置
|
interface SelectOption {
|
value: any,
|
label: string,
|
more?: any
|
}
|
const clarityList: SelectOption[] = [
|
{
|
value: 0,
|
label: 'Adaptive'
|
},
|
{
|
value: 1,
|
label: 'Smooth'
|
},
|
{
|
value: 2,
|
label: 'Standard'
|
},
|
{
|
value: 3,
|
label: 'HD'
|
},
|
{
|
value: 4,
|
label: 'Super Clear'
|
}
|
]
|
// 视频配置
|
const videoOption = ref({
|
url_type: 3,
|
url: '',
|
video_id: '',
|
video_quality: 3,
|
})
|
const control = () => {
|
videoControl.value = !videoControl.value
|
if (videoControl.value) {
|
onStart()
|
} else {
|
onPause()
|
}
|
}
|
// 开启视频直播
|
const onStart = async () => {
|
videoOption.value.video_id = `${'设备id'}/${'默认设备第一个相机id'}/${nonSwitchable}-0`
|
const liveURL = `serverIP=${config.gbServerIp}&serverPort=${config.gbServerPort}&serverID=${config.gbServerId}&agentID=${config.gbAgentId}&agentPassword=${config.gbPassword}&localPort=${config.gbAgentPort}&channel=${config.gbAgentChannel}`
|
const res = await startLivestream({
|
url: liveURL,
|
video_id: videoOption.value.video_id,
|
url_type: videoOption.value.url_type,
|
video_quality: videoOption.value.video_quality,
|
})
|
if (res.code !== 0) return
|
const url = res.data.url
|
const videoElement = videowebrtc.value
|
message.loading({
|
content: 'Loding...',
|
duration: 4,
|
onClose () {
|
const player = new jswebrtc.Player(url, {
|
video: videoElement,
|
autoplay: true,
|
onPlay: (obj: any) => {
|
console.log('start play livestream')
|
}
|
})
|
}
|
})
|
}
|
// 暂停直播
|
const onPause = async () => {
|
stopLivestream({
|
video_id: videoOption.value.video_id
|
}).then(res => {
|
if (res.code === 0) {
|
message.success(res.message)
|
console.log('stop play livestream')
|
}
|
})
|
}
|
</script>
|
|
<style scoped lang="scss">
|
.config_dock {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
|
:deep(.ant-input-affix-wrapper > input.ant-input) {
|
background: #101010;
|
color: #fff;
|
text-align: center;
|
margin-right: 5px;
|
width: 30px;
|
}
|
|
:deep(.ant-input-affix-wrapper .ant-input-suffix) {
|
color: #fff;
|
}
|
|
.unchecked {
|
color: #fff;
|
background-color: #3c3c3c;
|
border: none;
|
}
|
|
.option {
|
width: 100%;
|
height: 120px;
|
align-items: center;
|
|
.option-left-icon {
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
background-color: #3d3d3d;
|
padding: 10px;
|
}
|
|
.option-right {
|
flex: 1;
|
padding: 5px;
|
|
.wrapper {
|
width: 100%;
|
|
.wrapper-item {
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
|
.item-left {
|
width: 100px;
|
}
|
|
.item-right {
|
flex: 1;
|
}
|
|
.dock-status {
|
background-color: #5d5f61;
|
padding: 0 5px;
|
color: #fff;
|
}
|
}
|
}
|
|
.option-btn {
|
width: 100%;
|
|
.btn {
|
width: 48%;
|
}
|
}
|
}
|
}
|
|
.video {
|
width: 100%;
|
height: 80%;
|
position: relative;
|
|
.video-option {
|
display: flex;
|
align-items: center;
|
justify-content: flex-end;
|
}
|
}
|
|
.takeoff {
|
padding: 5px;
|
height: 100px;
|
width: 100%;
|
margin-bottom: 10px;
|
|
.takeoff-left {
|
background-color: #3d3d3d;
|
padding: 10px;
|
width: 90px;
|
height: 90px;
|
justify-content: center;
|
}
|
|
.input-style {
|
width: 60px;
|
padding: 0;
|
background-color: #101010;
|
border: none;
|
}
|
|
.select-style {
|
background-color: #3c3c3c;
|
padding: 0;
|
color: #fff;
|
font-size: 10px;
|
}
|
|
.label {
|
min-width: 100px;
|
text-align: right;
|
}
|
|
.divider {
|
height: 100%;
|
width: 1.12px;
|
background-color: hsla(0, 0%, 100%, .1);
|
}
|
}
|
}
|
</style>
|