parent
562223fec4
commit
43a49e95fb
|
@ -67,4 +67,7 @@ export default {
|
|||
|
||||
// 播放云端回放
|
||||
playbackStart: (recordId: string) => server.get(`/media/record/${recordId}.mp4`),
|
||||
|
||||
// 设备预置位相关接口
|
||||
opFunction: (deviceId: string, functionId: string, data?: any) => server.post(`/device/invoked/${deviceId}/function/${functionId}`, data)
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
justify-content: center;
|
||||
width: 45%;
|
||||
height: 45%;
|
||||
font-size: 30px;
|
||||
// font-size: 30px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%) rotateZ(-45deg);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="direction-audio">
|
||||
<!-- <AIcon type="AudioOutlined" /> -->
|
||||
<slot name="center"><!-- <AIcon type="AudioOutlined" /> --></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zoom">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import menus, { AccountCenterBindPath, InitHomePath, InitLicense, LoginPath, OauthPath } from './menu'
|
||||
import menus, { AccountCenterBindPath, InitHomePath, InitLicense, LoginPath, OauthPath, VideoSharePath } from './menu'
|
||||
import { cleanToken, getToken } from '@/utils/comm'
|
||||
import { useUserInfo } from '@/store/userInfo'
|
||||
import { useSystem } from '@/store/system'
|
||||
|
@ -15,7 +15,7 @@ const router = createRouter({
|
|||
})
|
||||
|
||||
const filterPath = [ InitHomePath ]
|
||||
const noTokenPath = [ AccountCenterBindPath, OauthPath, InitLicense ]
|
||||
const noTokenPath = [ AccountCenterBindPath, OauthPath, InitLicense, VideoSharePath ]
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
// TODO 切换路由取消请求
|
||||
|
|
|
@ -5,6 +5,7 @@ export const InitLicense = '/init-license'
|
|||
export const NotificationSubscriptionCode = 'message-subscribe'
|
||||
export const NotificationRecordCode = 'account/NotificationRecord'
|
||||
export const OauthPath = '/oauth'
|
||||
export const VideoSharePath = '/media/device/Share'
|
||||
|
||||
export const AccountMenu = {
|
||||
path: '/account',
|
||||
|
@ -86,5 +87,9 @@ export default [
|
|||
},
|
||||
component: () => import('@/views/oauth/WeChat.vue')
|
||||
},
|
||||
{
|
||||
path: VideoSharePath,
|
||||
component: () => import('@/views/media/Device/Channel/Share/index.vue')
|
||||
},
|
||||
AccountMenu
|
||||
]
|
|
@ -0,0 +1,200 @@
|
|||
<template>
|
||||
<j-table
|
||||
size="small"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="false"
|
||||
:scroll="{ y: 200 }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'actions'">
|
||||
<j-button
|
||||
type="link"
|
||||
style="padding: 0"
|
||||
v-if="!record.flag"
|
||||
:disabled="loading"
|
||||
@click="onSetting(record)"
|
||||
>设置</j-button
|
||||
>
|
||||
<template v-else>
|
||||
<j-space>
|
||||
<j-button
|
||||
danger
|
||||
type="link"
|
||||
:disabled="loading"
|
||||
style="padding: 0"
|
||||
@click="onDelete(record)"
|
||||
>删除</j-button
|
||||
>
|
||||
<j-button
|
||||
type="link"
|
||||
:disabled="loading"
|
||||
style="padding: 0"
|
||||
@click="onInvoke(record)"
|
||||
>调用</j-button
|
||||
>
|
||||
</j-space>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'name'">
|
||||
<j-input
|
||||
:disabled="record.flag"
|
||||
v-model:value="record[column.dataIndex]"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record[column.dataIndex] }}
|
||||
</template>
|
||||
</template>
|
||||
</j-table>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import channelApi from '@/api/media/channel';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { isNumber, unionBy } from 'lodash-es';
|
||||
import { PropType } from 'vue';
|
||||
|
||||
type Item = { id: string | number; name: string; flag?: boolean };
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object as PropType<Partial<Record<string, any>>>,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
width: 60,
|
||||
},
|
||||
{
|
||||
title: '预置点位',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'actions',
|
||||
width: 90,
|
||||
},
|
||||
];
|
||||
|
||||
const init = new Array(50).fill(0).map((_, index) => {
|
||||
return {
|
||||
id: String(index + 1),
|
||||
name: `预置点${index + 1}`,
|
||||
flag: false,
|
||||
};
|
||||
});
|
||||
|
||||
const dataSource = ref<Item[]>(init);
|
||||
const loading = ref(false);
|
||||
|
||||
const handleSearch = async (id: string, arr: Item[]) => {
|
||||
const resp = await channelApi.opFunction(id, 'QueryPreset');
|
||||
if (resp.status === 200) {
|
||||
dataSource.value = unionBy([ ...arr, ...init], 'id').map((item) => {
|
||||
const _item = (resp.result?.[0] || []).find(
|
||||
(i: any) => i.id === item.id,
|
||||
);
|
||||
if (_item) {
|
||||
return {
|
||||
..._item,
|
||||
flag: true,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const saveInfo = async (preset: Item[]) => {
|
||||
const resp = await channelApi.update(props.data.id, {
|
||||
id: props.data.id,
|
||||
address: props.data.address,
|
||||
channelId: props.data.channelId,
|
||||
description: props.data.description,
|
||||
deviceId: props.data.deviceId,
|
||||
name: props.data.name,
|
||||
manufacturer: props.data.manufacturer,
|
||||
ptzType: props.data.ptzType?.value || 0,
|
||||
others: {
|
||||
...props.data?.others,
|
||||
preset
|
||||
},
|
||||
});
|
||||
if (resp.status === 200) {
|
||||
console.log(resp);
|
||||
}
|
||||
};
|
||||
|
||||
const onFunction = (id: string, functionId: string, params: any) => {
|
||||
loading.value = true;
|
||||
channelApi
|
||||
.opFunction(id, functionId, params)
|
||||
.then(async (resp) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功!');
|
||||
const preset = dataSource.value.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
};
|
||||
});
|
||||
if (params?.operation === 'SET') {
|
||||
// 保存名称
|
||||
await saveInfo(preset);
|
||||
}
|
||||
if (props.data?.deviceId) {
|
||||
await handleSearch(props.data?.deviceId, preset);
|
||||
}
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onSetting = (obj: Item) => {
|
||||
if (!obj.id) return;
|
||||
const params = {
|
||||
operation: 'SET',
|
||||
presetIndex: isNumber(obj.id) ? Number(obj.id) : obj.id,
|
||||
channel: props.data?.channelId,
|
||||
};
|
||||
onFunction(props.data?.deviceId, 'Preset', params);
|
||||
};
|
||||
|
||||
const onInvoke = (obj: Item) => {
|
||||
if (!obj.id) return;
|
||||
const params = {
|
||||
operation: 'CALL',
|
||||
presetIndex: isNumber(obj.id) ? Number(obj.id) : obj.id,
|
||||
channel: props.data?.channelId,
|
||||
};
|
||||
onFunction(props.data?.deviceId, 'Preset', params);
|
||||
};
|
||||
|
||||
const onDelete = (obj: Item) => {
|
||||
if (!obj.id) return;
|
||||
const params = {
|
||||
operation: 'DEL',
|
||||
presetIndex: isNumber(obj.id) ? Number(obj.id) : obj.id,
|
||||
channel: props.data?.channelId,
|
||||
};
|
||||
onFunction(props.data?.deviceId, 'Preset', params);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data.deviceId,
|
||||
() => {
|
||||
if (props.data?.deviceId) {
|
||||
handleSearch(props.data?.deviceId, props.data?.others?.preset);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<j-modal visible @cancel="emit('close')" :closable="false">
|
||||
<div class="content">
|
||||
<div style="margin-bottom: 5px;">
|
||||
复制下方链接,分享{{ data.name }}视频界面
|
||||
</div>
|
||||
<j-input-group compact>
|
||||
<j-input
|
||||
v-model:value="url"
|
||||
ref="urlRef"
|
||||
style="width: calc(100% - 50px)"
|
||||
/>
|
||||
<j-tooltip title="复制">
|
||||
<j-button @click="onCopy">
|
||||
<template #icon><AIcon type="CopyOutlined" /></template>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</j-input-group>
|
||||
</div>
|
||||
<template #footer>
|
||||
<j-button type="primary" @click="emit('close')">确定</j-button>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getToken } from '@/utils/comm';
|
||||
import { TOKEN_KEY } from '@/utils/variable';
|
||||
import { PropType } from 'vue';
|
||||
|
||||
const emit = defineEmits(['close', 'save']);
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object as PropType<Partial<Record<string, any>>>,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const token = getToken();
|
||||
const route = useRoute();
|
||||
const url = ref('');
|
||||
const urlRef = ref<HTMLInputElement>()
|
||||
|
||||
watchEffect(() => {
|
||||
url.value = `${window.location.origin}#/media/device/Share?deviceId=${props.data.deviceId}&channelId=${props.data.channelId}&type=${route.query.type}&${TOKEN_KEY}=${token}`
|
||||
})
|
||||
|
||||
const onCopy = () => {
|
||||
if(urlRef.value) {
|
||||
urlRef.value.select()
|
||||
document.execCommand('copy')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 60px 10px 40px 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,22 +1,21 @@
|
|||
.media-live {
|
||||
display: flex;
|
||||
|
||||
.live-player-tools {
|
||||
flex-basis: 230px;
|
||||
// .live-player-tools {
|
||||
// flex-basis: 300px;
|
||||
|
||||
.direction-item {
|
||||
font-size: 30px !important;
|
||||
}
|
||||
// .direction-item {
|
||||
// font-size: 30px !important;
|
||||
// }
|
||||
|
||||
.zoom-item {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
// .zoom-item {
|
||||
// font-size: 20px !important;
|
||||
// }
|
||||
// }
|
||||
|
||||
.media-live-video {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
width: 0;
|
||||
flex: 1;
|
||||
|
||||
.media-tool {
|
||||
position: absolute;
|
||||
|
@ -50,9 +49,20 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media-live-actions {
|
||||
width: 300px;
|
||||
margin-left: 10px;
|
||||
|
||||
.actions-tool {
|
||||
padding: 0 40px 5px 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media-live-tool {
|
||||
display: flex;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -3,49 +3,82 @@
|
|||
<j-modal
|
||||
v-model:visible="_vis"
|
||||
title="播放"
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
width="800px"
|
||||
:width="_type ? 1200 : 900"
|
||||
:maskClosable="false"
|
||||
@ok="_vis = false"
|
||||
@cancel="_vis = false"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<j-button :disabled="type === 'share'" type="text"><AIcon type="CloseOutlined" /></j-button>
|
||||
</template>
|
||||
<div class="media-live-tool">
|
||||
<j-radio-group
|
||||
v-model:value="mediaType"
|
||||
button-style="solid"
|
||||
@change="mediaStart"
|
||||
>
|
||||
<j-radio-button value="mp4">MP4</j-radio-button>
|
||||
<j-radio-button value="flv">FLV</j-radio-button>
|
||||
<j-radio-button value="m3u8">HLS</j-radio-button>
|
||||
</j-radio-group>
|
||||
<div class="media-live-share" v-if="type !== 'share'">
|
||||
<j-button type="link" @click="onShare"
|
||||
><AIcon type="ShareAltOutlined" />分享视频</j-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-live">
|
||||
<div class="media-live-video">
|
||||
<div :class="mediaToolClass" @mouseleave='mouseleave' @mouseenter='showTool = true' >
|
||||
<div class="tool-item" >
|
||||
<template v-if='isRecord === 0'>
|
||||
<j-dropdown trigger='click' @visibleChange='visibleChange' @click='showToolLock = true'>
|
||||
<div>
|
||||
开始录像
|
||||
</div>
|
||||
<template #overlay>
|
||||
<j-menu @click="recordStart">
|
||||
<j-menu-item key='true' v-if='route.query.type !== "fixed-media"'>
|
||||
<span style='padding-right: 12px;'>本地存储</span>
|
||||
<j-tooltip title='存储在设备本地'>
|
||||
<a-icon type='QuestionCircleOutlined' />
|
||||
</j-tooltip>
|
||||
</j-menu-item>
|
||||
<j-menu-item key='false'>
|
||||
<span style='padding-right: 12px;'>云端存储</span>
|
||||
<j-tooltip title='存储在服务器中'>
|
||||
<a-icon type='QuestionCircleOutlined' />
|
||||
</j-tooltip>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
<div
|
||||
:class="mediaToolClass"
|
||||
@mouseleave="mouseleave"
|
||||
@mouseenter="showTool = true"
|
||||
>
|
||||
<div class="tool-item" v-if="type !== 'share'">
|
||||
<template v-if="isRecord === 0">
|
||||
<j-dropdown
|
||||
trigger="click"
|
||||
@visibleChange="visibleChange"
|
||||
@click="showToolLock = true"
|
||||
>
|
||||
<div>开始录像</div>
|
||||
<template #overlay>
|
||||
<j-menu @click="recordStart">
|
||||
<j-menu-item
|
||||
key="true"
|
||||
v-if="_type"
|
||||
>
|
||||
<span style="padding-right: 12px"
|
||||
>本地存储</span
|
||||
>
|
||||
<j-tooltip title="存储在设备本地">
|
||||
<a-icon
|
||||
type="QuestionCircleOutlined"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</j-menu-item>
|
||||
<j-menu-item key="false">
|
||||
<span style="padding-right: 12px"
|
||||
>云端存储</span
|
||||
>
|
||||
<j-tooltip title="存储在服务器中">
|
||||
<a-icon
|
||||
type="QuestionCircleOutlined"
|
||||
/>
|
||||
</j-tooltip>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</template>
|
||||
<div v-else-if='isRecord === 1'>
|
||||
请求录像中
|
||||
<div v-else-if="isRecord === 1">请求录像中</div>
|
||||
<div
|
||||
v-else-if="isRecord === 2"
|
||||
@click.stop="recordStop"
|
||||
>
|
||||
停止录像
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if='isRecord === 2' @click.stop="recordStop">
|
||||
停止录像
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="tool-item" @click.stop="handleRefresh">
|
||||
刷新
|
||||
|
@ -67,23 +100,45 @@
|
|||
autoplay
|
||||
/>
|
||||
</div>
|
||||
<MediaTool
|
||||
@onMouseDown="handleMouseDown"
|
||||
@onMouseUp="handleMouseUp"
|
||||
/>
|
||||
</div>
|
||||
<div class="media-live-tool">
|
||||
<j-radio-group
|
||||
v-model:value="mediaType"
|
||||
button-style="solid"
|
||||
@change="mediaStart"
|
||||
>
|
||||
<j-radio-button value="mp4">MP4</j-radio-button>
|
||||
<j-radio-button value="flv">FLV</j-radio-button>
|
||||
<j-radio-button value="m3u8">HLS</j-radio-button>
|
||||
</j-radio-group>
|
||||
<div class="media-live-actions" v-if="_type">
|
||||
<div class="actions-tool">
|
||||
<MediaTool
|
||||
@onMouseDown="handleMouseDown"
|
||||
@onMouseUp="handleMouseUp"
|
||||
>
|
||||
<template #center>
|
||||
<div class="center">
|
||||
<div>转速控制</div>
|
||||
<j-dropdown>
|
||||
<span
|
||||
>{{ _speed }}<AIcon type="DownOutlined"
|
||||
/></span>
|
||||
<template #overlay>
|
||||
<j-menu @click="onMenuChange">
|
||||
<j-menu-item
|
||||
:key="item.value"
|
||||
v-for="item in speedList"
|
||||
>
|
||||
{{ item.label }}
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</j-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</MediaTool>
|
||||
</div>
|
||||
<Preset :data="data" />
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<j-space>
|
||||
<j-button :disabled="type === 'share'" @click="_vis = false">取消</j-button>
|
||||
<j-button :disabled="type === 'share'" @click="_vis = false" type="primary">确定</j-button>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-modal>
|
||||
<Share v-if="visible" :data="data" @close="visible = false" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -91,6 +146,8 @@ import { PropType } from 'vue';
|
|||
import LivePlayer from '@/components/Player/index.vue';
|
||||
import MediaTool from '@/components/Player/mediaTool.vue';
|
||||
import channelApi from '@/api/media/channel';
|
||||
import Share from './Share.vue';
|
||||
import Preset from './Preset.vue';
|
||||
|
||||
type Emits = {
|
||||
(e: 'update:visible', data: boolean): void;
|
||||
|
@ -103,6 +160,10 @@ const props = defineProps({
|
|||
type: Object as PropType<Partial<Record<string, any>>>,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<'share' | 'normal'>,
|
||||
default: 'normal',
|
||||
},
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
|
@ -118,29 +179,50 @@ const player = ref();
|
|||
const url = ref('');
|
||||
// 视频类型
|
||||
const mediaType = ref<'mp4' | 'flv' | 'hls'>('mp4');
|
||||
const showTool = ref(false)
|
||||
const showToolLock = ref(false)
|
||||
const showTool = ref(false);
|
||||
const showToolLock = ref(false);
|
||||
|
||||
const visible = ref(false);
|
||||
|
||||
const _type = computed(() => {
|
||||
return route.query.type !== 'fixed-media'
|
||||
})
|
||||
|
||||
const speedList = [
|
||||
{ label: '高', value: 180 },
|
||||
{ label: '中', value: 90 },
|
||||
{ label: '低', value: 45 },
|
||||
];
|
||||
const speed = ref(90);
|
||||
|
||||
const _speed = computed(() => {
|
||||
return speedList.find((item) => item.value === speed.value)?.label;
|
||||
});
|
||||
|
||||
const onMenuChange = (val: any) => {
|
||||
speed.value = val.key;
|
||||
};
|
||||
|
||||
const mouseleave = () => {
|
||||
if (!showToolLock.value) {
|
||||
showTool.value = false
|
||||
}
|
||||
}
|
||||
if (!showToolLock.value) {
|
||||
showTool.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const visibleChange = (v: boolean) => {
|
||||
showTool.value = v
|
||||
}
|
||||
showTool.value = v;
|
||||
};
|
||||
|
||||
const getPopupContainer = (trigger: HTMLElement) => {
|
||||
return trigger?.parentNode || document.body
|
||||
}
|
||||
return trigger?.parentNode || document.body;
|
||||
};
|
||||
|
||||
const mediaToolClass = computed(() => {
|
||||
return {
|
||||
'media-tool': true,
|
||||
'media-tool-show': showTool.value
|
||||
}
|
||||
})
|
||||
return {
|
||||
'media-tool': true,
|
||||
'media-tool-show': showTool.value,
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 媒体开始播放
|
||||
|
@ -150,7 +232,7 @@ const mediaStart = () => {
|
|||
props.data.deviceId,
|
||||
props.data.channelId,
|
||||
mediaType.value,
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// 录像状态
|
||||
|
@ -169,36 +251,33 @@ const getIsRecord = async () => {
|
|||
/**
|
||||
* 开始录像
|
||||
*/
|
||||
const recordStart = async ({ key }: { key: string}) => {
|
||||
showToolLock.value = false
|
||||
showTool.value = false
|
||||
isRecord.value = 1;
|
||||
const local = key === 'true'
|
||||
const res = await channelApi.recordStart(
|
||||
props.data.deviceId,
|
||||
props.data.channelId,
|
||||
{ local },
|
||||
).catch(() => ({ success: false }))
|
||||
if (res.success) {
|
||||
isRecord.value = 2;
|
||||
} else {
|
||||
isRecord.value = 0;
|
||||
}
|
||||
}
|
||||
const recordStart = async ({ key }: { key: string }) => {
|
||||
showToolLock.value = false;
|
||||
showTool.value = false;
|
||||
isRecord.value = 1;
|
||||
const local = key === 'true';
|
||||
const res = await channelApi
|
||||
.recordStart(props.data.deviceId, props.data.channelId, { local })
|
||||
.catch(() => ({ success: false }));
|
||||
if (res.success) {
|
||||
isRecord.value = 2;
|
||||
} else {
|
||||
isRecord.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 停止录像
|
||||
*/
|
||||
const recordStop = async () => {
|
||||
const res = await channelApi.recordStop(
|
||||
props.data.deviceId,
|
||||
props.data.channelId
|
||||
);
|
||||
if (res.success) {
|
||||
isRecord.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const res = await channelApi.recordStop(
|
||||
props.data.deviceId,
|
||||
props.data.channelId,
|
||||
);
|
||||
if (res.success) {
|
||||
isRecord.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新
|
||||
|
@ -223,12 +302,19 @@ const handleReset = async () => {
|
|||
* @param type 控制类型
|
||||
*/
|
||||
const handleMouseDown = (type: string) => {
|
||||
channelApi.ptzTool(props.data.deviceId, props.data.channelId, type);
|
||||
channelApi.ptzTool(props.data.deviceId, props.data.channelId, type, speed.value);
|
||||
};
|
||||
const handleMouseUp = () => {
|
||||
channelApi.ptzStop(props.data.deviceId, props.data.channelId);
|
||||
};
|
||||
|
||||
/**
|
||||
* 分享视频
|
||||
*/
|
||||
const onShare = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => _vis.value,
|
||||
(val: boolean) => {
|
||||
|
@ -240,14 +326,23 @@ watch(
|
|||
url.value = '';
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@import './index.less';
|
||||
:deep(.live-player-stretch-btn){
|
||||
display: none;
|
||||
:deep(.live-player-stretch-btn) {
|
||||
display: none;
|
||||
}
|
||||
:deep(.vjs-icon-spinner){
|
||||
display: none;
|
||||
:deep(.vjs-icon-spinner) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<Live :visible="true" type="share" :data="playData" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { LocalStore } from '@/utils/comm';
|
||||
import { TOKEN_KEY } from '@/utils/variable';
|
||||
import Live from '../Live/index.vue';
|
||||
|
||||
const playData = ref({
|
||||
deviceId: '',
|
||||
channelId: '',
|
||||
type: ''
|
||||
});
|
||||
|
||||
// 获取url信息
|
||||
const route = useRoute();
|
||||
|
||||
watchEffect(() => {
|
||||
const obj: any = unref(route.query) || {};
|
||||
playData.value = {
|
||||
deviceId: obj?.deviceId || '',
|
||||
channelId: obj?.channelId || '',
|
||||
type: obj?.type
|
||||
};
|
||||
if(obj?.[TOKEN_KEY]){
|
||||
LocalStore.set(TOKEN_KEY, obj?.[TOKEN_KEY]);
|
||||
}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue