ptz.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /**
  2. * PTZ 云台控制 API
  3. * 通过独立的 PTZ 后端服务调用海康威视 ISAPI 协议
  4. */
  5. // ==================== 类型定义 ====================
  6. export interface PTZConfig {
  7. host: string
  8. username: string
  9. password: string
  10. channel?: number
  11. }
  12. export interface PTZCommand {
  13. pan: number
  14. tilt: number
  15. zoom: number
  16. }
  17. export interface PTZResult {
  18. success: boolean
  19. error?: string
  20. data?: unknown
  21. }
  22. // ==================== 常量 ====================
  23. const PTZ_API_BASE = 'http://localhost:3002'
  24. const DEFAULT_SPEED = 50
  25. // 方向预设值 (单位向量)
  26. export const PTZ_DIRECTIONS = {
  27. UP: { pan: 0, tilt: 1 },
  28. DOWN: { pan: 0, tilt: -1 },
  29. LEFT: { pan: -1, tilt: 0 },
  30. RIGHT: { pan: 1, tilt: 0 },
  31. UP_LEFT: { pan: -1, tilt: 1 },
  32. UP_RIGHT: { pan: 1, tilt: 1 },
  33. DOWN_LEFT: { pan: -1, tilt: -1 },
  34. DOWN_RIGHT: { pan: 1, tilt: -1 },
  35. STOP: { pan: 0, tilt: 0 }
  36. } as const
  37. // 缩放预设值 (单位向量)
  38. export const PTZ_ZOOM_DIRECTIONS = {
  39. IN: { zoom: 1 },
  40. OUT: { zoom: -1 },
  41. STOP: { zoom: 0 }
  42. } as const
  43. export type PTZDirectionKey = keyof typeof PTZ_DIRECTIONS
  44. export type PTZZoomKey = keyof typeof PTZ_ZOOM_DIRECTIONS
  45. // ==================== 核心 API ====================
  46. /**
  47. * 发送 PTZ 控制命令 (统一接口)
  48. */
  49. async function sendCommand(config: PTZConfig, command: PTZCommand): Promise<PTZResult> {
  50. try {
  51. const response = await fetch(`${PTZ_API_BASE}/ptz/control`, {
  52. method: 'POST',
  53. headers: { 'Content-Type': 'application/json' },
  54. body: JSON.stringify({
  55. host: config.host,
  56. username: config.username,
  57. password: config.password,
  58. channel: config.channel || 1,
  59. pan: command.pan,
  60. tilt: command.tilt,
  61. zoom: command.zoom
  62. })
  63. })
  64. const data = await response.json()
  65. return data.code === 200 ? { success: true, data: data.data } : { success: false, error: data.msg || 'Unknown error' }
  66. } catch (error) {
  67. return { success: false, error: String(error) }
  68. }
  69. }
  70. /**
  71. * 获取 PTZ 状态
  72. */
  73. export async function getPTZStatus(config: PTZConfig): Promise<PTZResult & { data?: string }> {
  74. try {
  75. const response = await fetch(`${PTZ_API_BASE}/ptz/status`, {
  76. method: 'POST',
  77. headers: { 'Content-Type': 'application/json' },
  78. body: JSON.stringify({
  79. host: config.host,
  80. username: config.username,
  81. password: config.password,
  82. channel: config.channel || 1
  83. })
  84. })
  85. const data = await response.json()
  86. return data.code === 200 ? { success: true, data: data.data?.raw } : { success: false, error: data.msg || 'Unknown error' }
  87. } catch (error) {
  88. return { success: false, error: String(error) }
  89. }
  90. }
  91. // ==================== 方向控制 ====================
  92. /**
  93. * 开始 PTZ 移动
  94. * @param direction 方向: UP, DOWN, LEFT, RIGHT, UP_LEFT, UP_RIGHT, DOWN_LEFT, DOWN_RIGHT, STOP
  95. * @param speed 速度 1-100,默认 50
  96. */
  97. export function startPTZ(config: PTZConfig, direction: PTZDirectionKey, speed: number = DEFAULT_SPEED): Promise<PTZResult> {
  98. const dir = PTZ_DIRECTIONS[direction]
  99. return sendCommand(config, {
  100. pan: dir.pan * speed,
  101. tilt: dir.tilt * speed,
  102. zoom: 0
  103. })
  104. }
  105. /**
  106. * 停止 PTZ 移动
  107. */
  108. export function stopPTZ(config: PTZConfig): Promise<PTZResult> {
  109. return startPTZ(config, 'STOP')
  110. }
  111. // ==================== 缩放控制 ====================
  112. /**
  113. * 开始缩放
  114. * @param direction 缩放方向: IN, OUT, STOP
  115. * @param speed 速度 1-100,默认 50
  116. */
  117. export function startZoom(config: PTZConfig, direction: PTZZoomKey, speed: number = DEFAULT_SPEED): Promise<PTZResult> {
  118. const zoom = PTZ_ZOOM_DIRECTIONS[direction]
  119. return sendCommand(config, {
  120. pan: 0,
  121. tilt: 0,
  122. zoom: zoom.zoom * speed
  123. })
  124. }
  125. /**
  126. * 停止缩放
  127. */
  128. export function stopZoom(config: PTZConfig): Promise<PTZResult> {
  129. return startZoom(config, 'STOP')
  130. }
  131. // ==================== 便捷方法 ====================
  132. export const zoomIn = (config: PTZConfig, speed?: number) => startZoom(config, 'IN', speed)
  133. export const zoomOut = (config: PTZConfig, speed?: number) => startZoom(config, 'OUT', speed)
  134. export const zoomStop = stopZoom