| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /**
- * PTZ 云台控制 API
- * 通过独立的 PTZ 后端服务调用海康威视 ISAPI 协议
- */
- // ==================== 类型定义 ====================
- export interface PTZConfig {
- host: string
- username: string
- password: string
- channel?: number
- }
- export interface PTZCommand {
- pan: number
- tilt: number
- zoom: number
- }
- export interface PTZResult {
- success: boolean
- error?: string
- data?: unknown
- }
- // ==================== 常量 ====================
- const PTZ_API_BASE = 'http://localhost:3002'
- const DEFAULT_SPEED = 50
- // 方向预设值 (单位向量)
- export const PTZ_DIRECTIONS = {
- UP: { pan: 0, tilt: 1 },
- DOWN: { pan: 0, tilt: -1 },
- LEFT: { pan: -1, tilt: 0 },
- RIGHT: { pan: 1, tilt: 0 },
- UP_LEFT: { pan: -1, tilt: 1 },
- UP_RIGHT: { pan: 1, tilt: 1 },
- DOWN_LEFT: { pan: -1, tilt: -1 },
- DOWN_RIGHT: { pan: 1, tilt: -1 },
- STOP: { pan: 0, tilt: 0 }
- } as const
- // 缩放预设值 (单位向量)
- export const PTZ_ZOOM_DIRECTIONS = {
- IN: { zoom: 1 },
- OUT: { zoom: -1 },
- STOP: { zoom: 0 }
- } as const
- export type PTZDirectionKey = keyof typeof PTZ_DIRECTIONS
- export type PTZZoomKey = keyof typeof PTZ_ZOOM_DIRECTIONS
- // ==================== 核心 API ====================
- /**
- * 发送 PTZ 控制命令 (统一接口)
- */
- async function sendCommand(config: PTZConfig, command: PTZCommand): Promise<PTZResult> {
- try {
- const response = await fetch(`${PTZ_API_BASE}/ptz/control`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- host: config.host,
- username: config.username,
- password: config.password,
- channel: config.channel || 1,
- pan: command.pan,
- tilt: command.tilt,
- zoom: command.zoom
- })
- })
- const data = await response.json()
- return data.code === 200 ? { success: true, data: data.data } : { success: false, error: data.msg || 'Unknown error' }
- } catch (error) {
- return { success: false, error: String(error) }
- }
- }
- /**
- * 获取 PTZ 状态
- */
- export async function getPTZStatus(config: PTZConfig): Promise<PTZResult & { data?: string }> {
- try {
- const response = await fetch(`${PTZ_API_BASE}/ptz/status`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- host: config.host,
- username: config.username,
- password: config.password,
- channel: config.channel || 1
- })
- })
- const data = await response.json()
- return data.code === 200 ? { success: true, data: data.data?.raw } : { success: false, error: data.msg || 'Unknown error' }
- } catch (error) {
- return { success: false, error: String(error) }
- }
- }
- // ==================== 方向控制 ====================
- /**
- * 开始 PTZ 移动
- * @param direction 方向: UP, DOWN, LEFT, RIGHT, UP_LEFT, UP_RIGHT, DOWN_LEFT, DOWN_RIGHT, STOP
- * @param speed 速度 1-100,默认 50
- */
- export function startPTZ(config: PTZConfig, direction: PTZDirectionKey, speed: number = DEFAULT_SPEED): Promise<PTZResult> {
- const dir = PTZ_DIRECTIONS[direction]
- return sendCommand(config, {
- pan: dir.pan * speed,
- tilt: dir.tilt * speed,
- zoom: 0
- })
- }
- /**
- * 停止 PTZ 移动
- */
- export function stopPTZ(config: PTZConfig): Promise<PTZResult> {
- return startPTZ(config, 'STOP')
- }
- // ==================== 缩放控制 ====================
- /**
- * 开始缩放
- * @param direction 缩放方向: IN, OUT, STOP
- * @param speed 速度 1-100,默认 50
- */
- export function startZoom(config: PTZConfig, direction: PTZZoomKey, speed: number = DEFAULT_SPEED): Promise<PTZResult> {
- const zoom = PTZ_ZOOM_DIRECTIONS[direction]
- return sendCommand(config, {
- pan: 0,
- tilt: 0,
- zoom: zoom.zoom * speed
- })
- }
- /**
- * 停止缩放
- */
- export function stopZoom(config: PTZConfig): Promise<PTZResult> {
- return startZoom(config, 'STOP')
- }
- // ==================== 便捷方法 ====================
- export const zoomIn = (config: PTZConfig, speed?: number) => startZoom(config, 'IN', speed)
- export const zoomOut = (config: PTZConfig, speed?: number) => startZoom(config, 'OUT', speed)
- export const zoomStop = stopZoom
|