|
@@ -506,7 +506,7 @@
|
|
|
<div
|
|
<div
|
|
|
v-for="preset in ptzPresetList"
|
|
v-for="preset in ptzPresetList"
|
|
|
:key="preset.id"
|
|
:key="preset.id"
|
|
|
- :class="['preset-item', { active: activePresetId === preset.id }]"
|
|
|
|
|
|
|
+ :class="['preset-item', { active: activePresetId === preset.id.toString() }]"
|
|
|
>
|
|
>
|
|
|
<span class="preset-index">{{ preset.id }}</span>
|
|
<span class="preset-index">{{ preset.id }}</span>
|
|
|
<span class="preset-name">{{ preset.name || `Preset ${preset.id}` }}</span>
|
|
<span class="preset-name">{{ preset.name || `Preset ${preset.id}` }}</span>
|
|
@@ -639,16 +639,13 @@ import { startStreamTask, stopStreamTask, getStreamPlayback } from '@/api/stream
|
|
|
import VideoPlayer from '@/components/VideoPlayer.vue'
|
|
import VideoPlayer from '@/components/VideoPlayer.vue'
|
|
|
import CodeEditor from '@/components/CodeEditor.vue'
|
|
import CodeEditor from '@/components/CodeEditor.vue'
|
|
|
import {
|
|
import {
|
|
|
- getPresets,
|
|
|
|
|
- gotoPreset,
|
|
|
|
|
type PresetInfo,
|
|
type PresetInfo,
|
|
|
presetList,
|
|
presetList,
|
|
|
presetGoto,
|
|
presetGoto,
|
|
|
presetSet,
|
|
presetSet,
|
|
|
presetRemove,
|
|
presetRemove,
|
|
|
getPTZCapabilities,
|
|
getPTZCapabilities,
|
|
|
- ptzStart,
|
|
|
|
|
- ptzStop
|
|
|
|
|
|
|
+ ptzControl
|
|
|
} from '@/api/camera'
|
|
} from '@/api/camera'
|
|
|
import type { LiveStreamDTO, LiveStreamStatus, LssNodeDTO, CameraInfoDTO, StreamChannelDTO, PTZAction } from '@/types'
|
|
import type { LiveStreamDTO, LiveStreamStatus, LssNodeDTO, CameraInfoDTO, StreamChannelDTO, PTZAction } from '@/types'
|
|
|
|
|
|
|
@@ -694,9 +691,7 @@ const ptzSpeed = ref(50)
|
|
|
const zoomValue = ref(0)
|
|
const zoomValue = ref(0)
|
|
|
|
|
|
|
|
// 预置位
|
|
// 预置位
|
|
|
-const presetListData = ref<PresetInfo[]>([])
|
|
|
|
|
const presetsLoading = ref(false)
|
|
const presetsLoading = ref(false)
|
|
|
-const activePresetToken = ref<string | null>(null)
|
|
|
|
|
|
|
|
|
|
// PTZ 预置位 (camera API)
|
|
// PTZ 预置位 (camera API)
|
|
|
interface PTZPresetInfo {
|
|
interface PTZPresetInfo {
|
|
@@ -707,7 +702,7 @@ interface PTZCapabilities {
|
|
|
maxPresetNum?: number
|
|
maxPresetNum?: number
|
|
|
[key: string]: unknown
|
|
[key: string]: unknown
|
|
|
}
|
|
}
|
|
|
-const ptzPresetList = ref<PTZPresetInfo[]>([])
|
|
|
|
|
|
|
+const ptzPresetList = ref<PresetInfo[]>([])
|
|
|
const activePresetId = ref<string | null>(null)
|
|
const activePresetId = ref<string | null>(null)
|
|
|
const cameraCapabilities = ref<PTZCapabilities | null>(null)
|
|
const cameraCapabilities = ref<PTZCapabilities | null>(null)
|
|
|
const capabilitiesLoading = ref(false)
|
|
const capabilitiesLoading = ref(false)
|
|
@@ -1349,8 +1344,8 @@ async function handlePTZ(direction: string) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- const action = directionToAction[direction] || 'stop'
|
|
|
|
|
- const res = await ptzStart(cameraId, action, ptzSpeed.value)
|
|
|
|
|
|
|
+ const command = directionToAction[direction] || 'stop'
|
|
|
|
|
+ const res = await ptzControl({ cameraId, command, speed: ptzSpeed.value })
|
|
|
if (!res.success) {
|
|
if (!res.success) {
|
|
|
console.error('PTZ 控制失败', res.errMsg)
|
|
console.error('PTZ 控制失败', res.errMsg)
|
|
|
}
|
|
}
|
|
@@ -1364,7 +1359,7 @@ async function handlePTZStop() {
|
|
|
if (!cameraId) return
|
|
if (!cameraId) return
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- await ptzStop(cameraId)
|
|
|
|
|
|
|
+ await ptzControl({ cameraId, command: 'stop' })
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('PTZ 停止失败', error)
|
|
console.error('PTZ 停止失败', error)
|
|
|
}
|
|
}
|
|
@@ -1381,19 +1376,19 @@ async function handleZoomChange(val: number) {
|
|
|
if (!cameraId) return
|
|
if (!cameraId) return
|
|
|
|
|
|
|
|
if (val === 0) {
|
|
if (val === 0) {
|
|
|
- await ptzStop(cameraId)
|
|
|
|
|
|
|
+ await ptzControl({ cameraId, command: 'stop' })
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const action: PTZAction = val > 0 ? 'zoom_in' : 'zoom_out'
|
|
|
|
|
- await ptzStart(cameraId, action, Math.abs(val))
|
|
|
|
|
|
|
+ const command = val > 0 ? 'zoom_in' : 'zoom_out'
|
|
|
|
|
+ await ptzControl({ cameraId, command, speed: Math.abs(val) })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function handleZoomRelease() {
|
|
async function handleZoomRelease() {
|
|
|
zoomValue.value = 0
|
|
zoomValue.value = 0
|
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
|
if (!cameraId) return
|
|
if (!cameraId) return
|
|
|
- await ptzStop(cameraId)
|
|
|
|
|
|
|
+ await ptzControl({ cameraId, command: 'stop' })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 缩放按钮控制
|
|
// 缩放按钮控制
|
|
@@ -1404,7 +1399,7 @@ async function handleZoomIn() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- const res = await ptzStart(cameraId, 'zoom_in', ptzSpeed.value)
|
|
|
|
|
|
|
+ const res = await ptzControl({ cameraId, command: 'zoom_in', speed: ptzSpeed.value })
|
|
|
if (!res.success) {
|
|
if (!res.success) {
|
|
|
console.error('Zoom in 失败', res.errMsg)
|
|
console.error('Zoom in 失败', res.errMsg)
|
|
|
}
|
|
}
|
|
@@ -1420,7 +1415,7 @@ async function handleZoomOut() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- const res = await ptzStart(cameraId, 'zoom_out', ptzSpeed.value)
|
|
|
|
|
|
|
+ const res = await ptzControl({ cameraId, command: 'zoom_out', speed: ptzSpeed.value })
|
|
|
if (!res.success) {
|
|
if (!res.success) {
|
|
|
console.error('Zoom out 失败', res.errMsg)
|
|
console.error('Zoom out 失败', res.errMsg)
|
|
|
}
|
|
}
|
|
@@ -1429,50 +1424,6 @@ async function handleZoomOut() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 加载预置位列表
|
|
|
|
|
-async function loadPresets() {
|
|
|
|
|
- if (!currentMediaStream.value?.cameraId) {
|
|
|
|
|
- ElMessage.warning(t('未配置摄像头'))
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- presetsLoading.value = true
|
|
|
|
|
- try {
|
|
|
|
|
- const res = await getPresets(currentMediaStream.value.cameraId)
|
|
|
|
|
- if (res.success && res.data) {
|
|
|
|
|
- presetList.value = res.data
|
|
|
|
|
- } else {
|
|
|
|
|
- presetList.value = []
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('加载预置位失败', error)
|
|
|
|
|
- presetList.value = []
|
|
|
|
|
- } finally {
|
|
|
|
|
- presetsLoading.value = false
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 跳转到预置位
|
|
|
|
|
-async function handleGotoPreset(preset: PresetInfo) {
|
|
|
|
|
- if (!currentMediaStream.value?.cameraId) {
|
|
|
|
|
- ElMessage.warning(t('未配置摄像头'))
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- activePresetToken.value = preset.token
|
|
|
|
|
- const res = await gotoPreset(currentMediaStream.value.cameraId, preset.token)
|
|
|
|
|
- if (res.success) {
|
|
|
|
|
- ElMessage.success(`${t('已跳转到预置位')}: ${preset.name || preset.token}`)
|
|
|
|
|
- } else {
|
|
|
|
|
- ElMessage.error(res.errMessage || t('跳转失败'))
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('跳转预置位失败', error)
|
|
|
|
|
- ElMessage.error(t('跳转失败'))
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
// ==================== PTZ 直连 API ====================
|
|
// ==================== PTZ 直连 API ====================
|
|
|
|
|
|
|
|
// 检查摄像头连接配置
|
|
// 检查摄像头连接配置
|
|
@@ -1490,9 +1441,9 @@ async function loadPTZPresets() {
|
|
|
|
|
|
|
|
presetsLoading.value = true
|
|
presetsLoading.value = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await presetList(cameraId)
|
|
|
|
|
- if (res.success && res.data) {
|
|
|
|
|
- ptzPresetList.value = res.data as PTZPresetInfo[]
|
|
|
|
|
|
|
+ const res = await presetList({ cameraId })
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ ptzPresetList.value = res.data as PresetInfo[]
|
|
|
} else {
|
|
} else {
|
|
|
ptzPresetList.value = []
|
|
ptzPresetList.value = []
|
|
|
if (!res.success) {
|
|
if (!res.success) {
|
|
@@ -1508,7 +1459,7 @@ async function loadPTZPresets() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 跳转到 PTZ 预置位 (通过 camera API)
|
|
// 跳转到 PTZ 预置位 (通过 camera API)
|
|
|
-async function handleGotoPTZPreset(preset: PTZPresetInfo) {
|
|
|
|
|
|
|
+async function handleGotoPTZPreset(preset: PresetInfo) {
|
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
|
if (!cameraId) {
|
|
if (!cameraId) {
|
|
|
ElMessage.warning(t('请先配置摄像头连接'))
|
|
ElMessage.warning(t('请先配置摄像头连接'))
|
|
@@ -1517,8 +1468,8 @@ async function handleGotoPTZPreset(preset: PTZPresetInfo) {
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
activePresetId.value = preset.id
|
|
activePresetId.value = preset.id
|
|
|
- const res = await presetGoto(cameraId, parseInt(preset.id))
|
|
|
|
|
- if (res.success) {
|
|
|
|
|
|
|
+ const res = await presetGoto({ cameraId, presetId: parseInt(preset.id) })
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
ElMessage.success(`${t('已跳转到预置位')}: ${preset.name || preset.id}`)
|
|
ElMessage.success(`${t('已跳转到预置位')}: ${preset.name || preset.id}`)
|
|
|
} else {
|
|
} else {
|
|
|
ElMessage.error(res.errMsg || t('跳转失败'))
|
|
ElMessage.error(res.errMsg || t('跳转失败'))
|
|
@@ -1548,7 +1499,7 @@ async function handleDeletePreset(preset: PTZPresetInfo) {
|
|
|
type: 'warning'
|
|
type: 'warning'
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- const res = await presetRemove(cameraId, parseInt(preset.id))
|
|
|
|
|
|
|
+ const res = await presetRemove({ cameraId, presetId: parseInt(preset.id) })
|
|
|
if (res.success) {
|
|
if (res.success) {
|
|
|
ElMessage.success(t('删除成功'))
|
|
ElMessage.success(t('删除成功'))
|
|
|
// 刷新预置位列表
|
|
// 刷新预置位列表
|
|
@@ -1573,7 +1524,7 @@ async function loadCameraCapabilities() {
|
|
|
|
|
|
|
|
capabilitiesLoading.value = true
|
|
capabilitiesLoading.value = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await getPTZCapabilities(cameraId)
|
|
|
|
|
|
|
+ const res = await getPTZCapabilities({ cameraId })
|
|
|
if (res.success && res.data) {
|
|
if (res.success && res.data) {
|
|
|
cameraCapabilities.value = res.data as PTZCapabilities
|
|
cameraCapabilities.value = res.data as PTZCapabilities
|
|
|
} else {
|
|
} else {
|
|
@@ -1693,7 +1644,7 @@ function selectPoint(point: TimelinePoint) {
|
|
|
// 如果已有预置位,跳转到该位置
|
|
// 如果已有预置位,跳转到该位置
|
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
const cameraId = currentMediaStream.value?.cameraId
|
|
|
if (point.presetId && cameraId) {
|
|
if (point.presetId && cameraId) {
|
|
|
- presetGoto(cameraId, point.presetId).then((res) => {
|
|
|
|
|
|
|
+ presetGoto({ cameraId, presetId: point.presetId }).then((res) => {
|
|
|
if (res.success) {
|
|
if (res.success) {
|
|
|
ElMessage.success(`${t('已跳转到')}: ${point.presetName || `Point ${point.id}`}`)
|
|
ElMessage.success(`${t('已跳转到')}: ${point.presetName || `Point ${point.id}`}`)
|
|
|
}
|
|
}
|
|
@@ -1718,7 +1669,7 @@ async function saveCurrentPoint() {
|
|
|
|
|
|
|
|
savingPreset.value = true
|
|
savingPreset.value = true
|
|
|
try {
|
|
try {
|
|
|
- const res = await presetSet(cameraId, presetIdNum, presetName)
|
|
|
|
|
|
|
+ const res = await presetSet({ cameraId, presetId: presetIdNum, presetName })
|
|
|
if (res.success) {
|
|
if (res.success) {
|
|
|
point.presetId = presetIdNum
|
|
point.presetId = presetIdNum
|
|
|
point.presetName = presetName
|
|
point.presetName = presetName
|
|
@@ -1820,7 +1771,7 @@ async function playTimeline() {
|
|
|
|
|
|
|
|
// 跳转到该预置位
|
|
// 跳转到该预置位
|
|
|
if (point.presetId) {
|
|
if (point.presetId) {
|
|
|
- await presetGoto(cameraId, point.presetId)
|
|
|
|
|
|
|
+ await presetGoto({ cameraId, presetId: point.presetId })
|
|
|
selectedPoint.value = point
|
|
selectedPoint.value = point
|
|
|
}
|
|
}
|
|
|
|
|
|