@ray-js/ipc-player-integration 0.0.29-beta.2 → 0.0.29-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,10 @@ export declare const useMultiCameraCtx: (props: Props) => {
36
36
  * ptz状态
37
37
  */
38
38
  ptzStatus: import("../interface").RetAtom<boolean>;
39
+ /**
40
+ * 多目设备支持的 dp
41
+ */
42
+ dpSupportMap: Record<"ptz_control" | "ipc_multi_locate_coor" | "zoom_control" | "ipc_multi_locate_coors" | "ipc_multi_ptz_control" | "ipc_multi_zoom_control", boolean>;
39
43
  /**
40
44
  * ipcPlayer extendProps
41
45
  */
@@ -44,6 +48,7 @@ export declare const useMultiCameraCtx: (props: Props) => {
44
48
  onSelectVideoIndex: (this: any, event: any) => void;
45
49
  onLayoutStatusChanged: (this: any, event: any) => void;
46
50
  onLocalizerViewLocated: (this: any, event: any) => Promise<void>;
51
+ onSwipeAtVideoIndex: (this: any, event: any) => Promise<void>;
47
52
  };
48
53
  /**
49
54
  * 设置布局样式
@@ -1,7 +1,9 @@
1
1
  import { getDpIdByCode, publishDps } from '@ray-js/ray-ipc-utils';
2
2
  import { useMemoizedFn } from 'ahooks';
3
- import { useMemo } from 'react';
3
+ import { useMemo, useRef } from 'react';
4
4
  import { MultiCameraLayoutStyle, MultiCameraScreenMode } from '../interface';
5
+ import { useDpSupport } from '../hooks';
6
+ import { GUN_BALL, MULTI_GUN_BALL, MULTI_PTZ_CONTROL, MULTI_ZOOM_CONTROL, PTZ_CONTROL, ZOOM_CONTROL } from '../utils/content/dpCode';
5
7
  import { useAtom } from './store';
6
8
  const DEFAULT_VIDEO_SPLIT_PROTOCOL = {
7
9
  total_split_num: 1,
@@ -9,6 +11,7 @@ const DEFAULT_VIDEO_SPLIT_PROTOCOL = {
9
11
  align_info: [],
10
12
  p_v: 3
11
13
  };
14
+ const DP_CODES = [PTZ_CONTROL, GUN_BALL, ZOOM_CONTROL, MULTI_GUN_BALL, MULTI_PTZ_CONTROL, MULTI_ZOOM_CONTROL];
12
15
  /**
13
16
  * 多目摄像头相关状态、方法维护
14
17
  */
@@ -21,6 +24,13 @@ export const useMultiCameraCtx = props => {
21
24
  const isSupport = useMemo(() => {
22
25
  return (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.total_split_num) > 1 && (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.p_v) >= 3 && typeof (IPCPlayerInstance === null || IPCPlayerInstance === void 0 ? void 0 : IPCPlayerInstance.switchLayoutStyle) === 'function';
23
26
  }, [IPCPlayerInstance, videoSplitProtocol]);
27
+ const dpSupportMap = useDpSupport({
28
+ devId,
29
+ dpCodes: DP_CODES
30
+ });
31
+
32
+ // PTZ控制定时器
33
+ const ptzTimerRef = useRef(null);
24
34
  const [layoutStyleAtom, setLayoutStyle] = useAtom(isSupport ? MultiCameraLayoutStyle.tile : MultiCameraLayoutStyle.pip);
25
35
  const [screenModeAtom, setScreenMode] = useAtom(isSupport ? MultiCameraScreenMode.full : MultiCameraScreenMode.short);
26
36
  const [selectedLenInfoAtom, setSelectedLenInfo] = useAtom({
@@ -46,23 +56,111 @@ export const useMultiCameraCtx = props => {
46
56
  setScreenMode(screenMode);
47
57
  });
48
58
  const handleLocalizerViewLocated = useMemoizedFn(async event => {
59
+ var _event$detail;
49
60
  console.info('onLocalizerViewLocated', JSON.stringify(event === null || event === void 0 ? void 0 : event.detail));
50
- const dpData = await getDpIdByCode(devId, 'ipc_multi_locate_coors');
61
+ const locateDpConfig = dpSupportMap.ipc_multi_locate_coors ? {
62
+ code: 'ipc_multi_locate_coors',
63
+ value: JSON.stringify(event.detail)
64
+ } : dpSupportMap.ipc_multi_locate_coor ? {
65
+ code: 'ipc_multi_locate_coor',
66
+ value: String((_event$detail = event.detail) === null || _event$detail === void 0 ? void 0 : _event$detail.coor)
67
+ } // 兼容老 dp
68
+ : null;
69
+ if (!locateDpConfig) return;
70
+ const dpData = await getDpIdByCode(devId, locateDpConfig.code);
51
71
  if (dpData.code === 0) {
52
- const dpId = dpData.data;
53
- const sndDpValue = JSON.stringify(event.detail);
54
72
  publishDps(devId, {
55
- [dpId]: sndDpValue
73
+ [dpData.data]: locateDpConfig.value
56
74
  });
57
75
  }
58
76
  });
77
+ const handleSwipeAtVideoIndex = useMemoizedFn(async event => {
78
+ console.info('onSwipeAtVideoIndex', JSON.stringify(event === null || event === void 0 ? void 0 : event.detail));
79
+ const {
80
+ index,
81
+ direction,
82
+ isStop
83
+ } = (event === null || event === void 0 ? void 0 : event.detail) || {};
84
+
85
+ // 停止当前PTZ的通用方法
86
+ const stopPtz = async () => {
87
+ const stopConfig = dpSupportMap.ipc_multi_ptz_control ? {
88
+ code: 'ipc_multi_ptz_stop',
89
+ value: JSON.stringify({
90
+ index
91
+ })
92
+ } : dpSupportMap.ptz_control ? {
93
+ code: 'ptz_stop',
94
+ value: true
95
+ } : null;
96
+ if (stopConfig) {
97
+ const ptzStopData = await getDpIdByCode(devId, stopConfig.code);
98
+ if (ptzStopData.code === 0) {
99
+ publishDps(devId, {
100
+ [ptzStopData.data]: stopConfig.value
101
+ });
102
+ }
103
+ }
104
+
105
+ // 清除定时器
106
+ if (ptzTimerRef.current) {
107
+ clearInterval(ptzTimerRef.current);
108
+ ptzTimerRef.current = null;
109
+ }
110
+ };
111
+
112
+ // isStop === true 表示结束事件,只需停止PTZ
113
+ if (isStop) {
114
+ await stopPtz();
115
+ return;
116
+ }
117
+
118
+ // !isStop 表示开始事件或方向变化事件
119
+ // 先停止旧方向,再启动新方向
120
+ if (!isStop) {
121
+ // 1. 先停止之前的PTZ控制(如果有)
122
+ await stopPtz();
123
+
124
+ // 2. 构建新方向的PTZ配置
125
+ const ptzConfig = dpSupportMap.ipc_multi_ptz_control ? {
126
+ code: 'ipc_multi_ptz_control',
127
+ value: JSON.stringify({
128
+ index,
129
+ direction: String(direction)
130
+ })
131
+ } : dpSupportMap.ptz_control ? {
132
+ code: 'ptz_control',
133
+ value: String(direction)
134
+ } : null;
135
+ if (!ptzConfig) return;
136
+
137
+ // 3. 启动新方向的PTZ控制
138
+ const dpData = await getDpIdByCode(devId, ptzConfig.code);
139
+ if (dpData.code === 0) {
140
+ const ptzControlId = dpData.data;
141
+
142
+ // 立即发送一次新方向
143
+ publishDps(devId, {
144
+ [ptzControlId]: ptzConfig.value
145
+ });
146
+
147
+ // 每秒持续发送新方向
148
+ ptzTimerRef.current = setInterval(() => {
149
+ publishDps(devId, {
150
+ [ptzControlId]: ptzConfig.value
151
+ });
152
+ }, 1000);
153
+ }
154
+ }
155
+ });
59
156
  const extendProps = useMemo(() => {
60
157
  return {
61
158
  // type: 4 表示多目摄像头
62
159
  type: isSupport ? 4 : undefined,
63
160
  onSelectVideoIndex: handleSelectVideoIndex,
64
161
  onLayoutStatusChanged: handleLayoutStatusChanged,
65
- onLocalizerViewLocated: handleLocalizerViewLocated
162
+ onLocalizerViewLocated: handleLocalizerViewLocated,
163
+ onSwipeAtVideoIndex: handleSwipeAtVideoIndex
66
164
  };
67
165
  }, [videoSplitProtocol]);
68
166
  const _setLayoutStyle = useMemoizedFn(style => {
@@ -145,6 +243,10 @@ export const useMultiCameraCtx = props => {
145
243
  * ptz状态
146
244
  */
147
245
  ptzStatus: ptzStatusAtom,
246
+ /**
247
+ * 多目设备支持的 dp
248
+ */
249
+ dpSupportMap,
148
250
  /**
149
251
  * ipcPlayer extendProps
150
252
  */
@@ -5,3 +5,4 @@ export * from './useDpState';
5
5
  export * from './useMemoizedFn';
6
6
  export * from './usePtz';
7
7
  export * from './useSchemaInfo.tsx';
8
+ export * from './useDpSupport';
@@ -4,4 +4,5 @@ export * from './useTemperature';
4
4
  export * from './useDpState';
5
5
  export * from './useMemoizedFn';
6
6
  export * from './usePtz';
7
- export * from './useSchemaInfo.tsx';
7
+ export * from './useSchemaInfo.tsx';
8
+ export * from './useDpSupport';
@@ -0,0 +1,6 @@
1
+ interface Options {
2
+ devId?: string;
3
+ dpCodes: string[];
4
+ }
5
+ export declare function useDpSupport(options: Options): Record<string, boolean>;
6
+ export {};
@@ -0,0 +1,47 @@
1
+ import "core-js/modules/esnext.iterator.constructor.js";
2
+ import "core-js/modules/esnext.iterator.map.js";
3
+ import "core-js/modules/esnext.iterator.reduce.js";
4
+ import { useEffect, useState } from 'react';
5
+ import { getDeviceInfo } from '@ray-js/ray';
6
+ export function useDpSupport(options) {
7
+ const {
8
+ devId,
9
+ dpCodes
10
+ } = options;
11
+ const [supportedMap, setSupportedMap] = useState(() => {
12
+ var _dpCodes$reduce;
13
+ return (_dpCodes$reduce = dpCodes === null || dpCodes === void 0 ? void 0 : dpCodes.reduce((acc, code) => {
14
+ acc[code] = false;
15
+ return acc;
16
+ }, {})) !== null && _dpCodes$reduce !== void 0 ? _dpCodes$reduce : {};
17
+ });
18
+ useEffect(() => {
19
+ if (!devId || !Array.isArray(dpCodes) || dpCodes.length === 0) {
20
+ var _dpCodes$reduce2;
21
+ setSupportedMap((_dpCodes$reduce2 = dpCodes === null || dpCodes === void 0 ? void 0 : dpCodes.reduce((acc, code) => {
22
+ acc[code] = false;
23
+ return acc;
24
+ }, {})) !== null && _dpCodes$reduce2 !== void 0 ? _dpCodes$reduce2 : {});
25
+ return;
26
+ }
27
+ getDeviceInfo({
28
+ deviceId: devId,
29
+ success: res => {
30
+ const schemaList = Array.isArray(res === null || res === void 0 ? void 0 : res.schema) ? res.schema : [];
31
+ const schemaCodes = new Set(schemaList.map(item => item.code));
32
+ const nextMap = dpCodes.reduce((acc, code) => {
33
+ acc[code] = schemaCodes.has(code);
34
+ return acc;
35
+ }, {});
36
+ setSupportedMap(nextMap);
37
+ },
38
+ fail: () => {
39
+ setSupportedMap(dpCodes.reduce((acc, code) => {
40
+ acc[code] = false;
41
+ return acc;
42
+ }, {}));
43
+ }
44
+ });
45
+ }, [devId, dpCodes]);
46
+ return supportedMap;
47
+ }
@@ -3,3 +3,8 @@ export declare const TEMP_REPORT_F = "temp_report_f";
3
3
  export declare const SENSOR_TEMPERATURE = "sensor_temperature";
4
4
  export declare const SENSOR_HUMIDITY = "sensor_humidity";
5
5
  export declare const PTZ_CONTROL = "ptz_control";
6
+ export declare const GUN_BALL = "ipc_multi_locate_coor";
7
+ export declare const ZOOM_CONTROL = "zoom_control";
8
+ export declare const MULTI_GUN_BALL = "ipc_multi_locate_coors";
9
+ export declare const MULTI_PTZ_CONTROL = "ipc_multi_ptz_control";
10
+ export declare const MULTI_ZOOM_CONTROL = "ipc_multi_zoom_control";
@@ -6,4 +6,14 @@ export const SENSOR_TEMPERATURE = 'sensor_temperature'; // 摄氏度
6
6
 
7
7
  export const SENSOR_HUMIDITY = 'sensor_humidity'; // 湿度
8
8
 
9
- export const PTZ_CONTROL = 'ptz_control'; // ptz
9
+ export const PTZ_CONTROL = 'ptz_control'; // ptz
10
+
11
+ export const GUN_BALL = 'ipc_multi_locate_coor'; // 旧枪球联动-定位器
12
+
13
+ export const ZOOM_CONTROL = 'zoom_control'; // 变焦控制
14
+
15
+ export const MULTI_GUN_BALL = 'ipc_multi_locate_coors'; // 多目枪球联动-定位器
16
+
17
+ export const MULTI_PTZ_CONTROL = 'ipc_multi_ptz_control'; // 多目 PTZ 控制
18
+
19
+ export const MULTI_ZOOM_CONTROL = 'ipc_multi_zoom_control'; // 多目 变焦控制
@@ -60,11 +60,13 @@ export declare const Battery: import("react").FunctionComponent<{
60
60
  nextLayoutStyle: import("../..").RetAtom<import("../..").MultiCameraLayoutStyle>;
61
61
  selectedLenInfo: import("../..").RetAtom<import("../..").MultiCameraLenInfo>;
62
62
  ptzStatus: import("../..").RetAtom<boolean>;
63
+ dpSupportMap: Record<"ptz_control" | "ipc_multi_locate_coor" | "zoom_control" | "ipc_multi_locate_coors" | "ipc_multi_ptz_control" | "ipc_multi_zoom_control", boolean>;
63
64
  extendProps: {
64
65
  type: number | undefined;
65
66
  onSelectVideoIndex: (this: any, event: any) => void;
66
67
  onLayoutStatusChanged: (this: any, event: any) => void;
67
68
  onLocalizerViewLocated: (this: any, event: any) => Promise<void>;
69
+ onSwipeAtVideoIndex: (this: any, event: any) => Promise<void>;
68
70
  };
69
71
  setLayoutStyle: (style: import("../..").MultiCameraLayoutStyle) => void;
70
72
  setScreenMode: (mode: import("../..").MultiCameraScreenMode) => void;
@@ -137,11 +139,13 @@ export declare const BatteryFull: import("react").FunctionComponent<{
137
139
  nextLayoutStyle: import("../..").RetAtom<import("../..").MultiCameraLayoutStyle>;
138
140
  selectedLenInfo: import("../..").RetAtom<import("../..").MultiCameraLenInfo>;
139
141
  ptzStatus: import("../..").RetAtom<boolean>;
142
+ dpSupportMap: Record<"ptz_control" | "ipc_multi_locate_coor" | "zoom_control" | "ipc_multi_locate_coors" | "ipc_multi_ptz_control" | "ipc_multi_zoom_control", boolean>;
140
143
  extendProps: {
141
144
  type: number | undefined;
142
145
  onSelectVideoIndex: (this: any, event: any) => void;
143
146
  onLayoutStatusChanged: (this: any, event: any) => void;
144
147
  onLocalizerViewLocated: (this: any, event: any) => Promise<void>;
148
+ onSwipeAtVideoIndex: (this: any, event: any) => Promise<void>;
145
149
  };
146
150
  setLayoutStyle: (style: import("../..").MultiCameraLayoutStyle) => void;
147
151
  setScreenMode: (mode: import("../..").MultiCameraScreenMode) => void;
@@ -44,7 +44,7 @@
44
44
  --app-native-btn-bg-color: transparent;
45
45
  --ptz-border-color: rgba(255, 255, 255, 0.2);
46
46
  --ptz-arrow-icon-color: #fff;
47
- --ptz-circle-inner-bg-color: rgba(255, 255, 255, 0.65);
47
+ --ptz-circle-inner-bg-color: rgba(255, 255, 255, 1);
48
48
  }
49
49
 
50
50
  .@{prefix}-tile-tip-wrap {
@@ -74,6 +74,9 @@ export const MoveablePtzControlItem = props => {
74
74
  selectedLenInfo: multiCameraCtx.selectedLenInfo,
75
75
  screenMode: multiCameraCtx.screenMode
76
76
  });
77
+ const {
78
+ dpSupportMap
79
+ } = multiCameraCtx;
77
80
  const [style, setStyle] = useState({
78
81
  positionLeft,
79
82
  positionBottom,
@@ -85,6 +88,75 @@ export const MoveablePtzControlItem = props => {
85
88
  pageY: 0
86
89
  });
87
90
  const canMoveRef = useRef(false);
91
+
92
+ // 获取播放器容器尺寸用于边界限制
93
+ const containerInfo = useRef({
94
+ width: 0,
95
+ height: 0,
96
+ top: 0,
97
+ left: 0
98
+ });
99
+ // 动态获取组件实际尺寸
100
+ const componentSizeRef = useRef({
101
+ width: 0,
102
+ height: 0
103
+ });
104
+ // 控制栏高度:竖屏 48px,横屏 72px
105
+ const controlBarHeight = screenMode === MultiCameraScreenMode.landscape ? 72 : 48;
106
+ useEffect(() => {
107
+ // 使用 createSelectorQuery 查询播放器容器和组件的实际尺寸
108
+ const query = ty.createSelectorQuery();
109
+ query.select('.ipc-player-content').boundingClientRect().exec(res => {
110
+ const rect = res === null || res === void 0 ? void 0 : res[0];
111
+ if (rect) {
112
+ containerInfo.current = {
113
+ width: rect.width,
114
+ height: rect.height,
115
+ top: rect.top,
116
+ left: rect.left
117
+ };
118
+ }
119
+ });
120
+
121
+ // 查询 PTZ 控件的实际尺寸
122
+ setTimeout(() => {
123
+ const ptzQuery = ty.createSelectorQuery();
124
+ ptzQuery.select(`.${multiPrefix}-moveable-ptz-control`).boundingClientRect().exec(res => {
125
+ const rect = res === null || res === void 0 ? void 0 : res[0];
126
+ if (rect) {
127
+ componentSizeRef.current = {
128
+ width: rect.width,
129
+ height: rect.height
130
+ };
131
+ }
132
+ });
133
+ }, 100);
134
+ }, [screenMode, selectedLenInfo]);
135
+
136
+ // 边界限制函数
137
+ // 注意:组件使用 bottom 定位,bottom 值越大组件越往上
138
+ const clampPosition = (left, bottom) => {
139
+ const {
140
+ width,
141
+ height
142
+ } = containerInfo.current;
143
+ const componentSize = componentSizeRef.current;
144
+
145
+ // 如果还没获取到组件尺寸,使用默认值
146
+ const compWidth = componentSize.width || 238;
147
+ const compHeight = componentSize.height || 172;
148
+
149
+ // 左右边界:0 到 容器宽度 - 组件宽度
150
+ const clampedLeft = Math.max(0, Math.min(left, width - compWidth));
151
+ // bottom 边界:
152
+ // - 最小值:控制栏高度(底部不能被控制栏遮挡)
153
+ // - 最大值:容器高度 - 组件高度(顶部不能超出容器)
154
+ const clampedBottom = Math.max(controlBarHeight, Math.min(bottom, height - compHeight));
155
+ return {
156
+ positionLeft: clampedLeft,
157
+ positionBottom: clampedBottom
158
+ };
159
+ };
88
160
  const {
89
161
  event
90
162
  } = useContext(UIEventContext);
@@ -112,22 +184,29 @@ export const MoveablePtzControlItem = props => {
112
184
  event: touchEvent
113
185
  } = data;
114
186
  touchEvent.stopPropagation();
115
- const dpData = await getDpIdByCode(devId, 'ipc_multi_ptz_control');
187
+ const dpValue = _get(_find(ptzData.current, {
188
+ type
189
+ }), 'dpValue', null);
190
+ const ptzConfig = dpSupportMap.ipc_multi_ptz_control ? {
191
+ code: 'ipc_multi_ptz_control',
192
+ value: JSON.stringify({
193
+ index: selectedLenInfo.index,
194
+ direction: dpValue
195
+ })
196
+ } : dpSupportMap.ptz_control ? {
197
+ code: 'ptz_control',
198
+ value: dpValue
199
+ } : null;
200
+ if (!ptzConfig) return;
201
+ const dpData = await getDpIdByCode(devId, ptzConfig.code);
116
202
  if (dpData.code === 0) {
117
203
  const ptzControlId = dpData.data;
118
- const direction = _get(_find(ptzData.current, {
119
- type
120
- }), 'dpValue', null);
121
- const sndDpValue = JSON.stringify({
122
- index: selectedLenInfo.index,
123
- direction
124
- });
125
204
  publishDps(devId, {
126
- [ptzControlId]: sndDpValue
205
+ [ptzControlId]: ptzConfig.value
127
206
  });
128
207
  ptzTimeId.current = setInterval(() => {
129
208
  publishDps(devId, {
130
- [ptzControlId]: sndDpValue
209
+ [ptzControlId]: ptzConfig.value
131
210
  });
132
211
  }, 1000);
133
212
  }
@@ -139,22 +218,29 @@ export const MoveablePtzControlItem = props => {
139
218
  event: touchEvent
140
219
  } = data;
141
220
  touchEvent.stopPropagation();
142
- const dpData = await getDpIdByCode(devId, 'ipc_multi_zoom_control');
143
- if (dpData.code === 0) {
144
- const ptzControlId = dpData.data;
145
- const control = _get(_find(ptzData.current, {
146
- type
147
- }), 'dpValue', null);
148
- const sndDpValue = JSON.stringify({
221
+ const dpValue = _get(_find(zoomData.current, {
222
+ type
223
+ }), 'dpValue', null);
224
+ const zoomConfig = dpSupportMap.ipc_multi_zoom_control ? {
225
+ code: 'ipc_multi_zoom_control',
226
+ value: JSON.stringify({
149
227
  index: selectedLenInfo.index,
150
- control
151
- });
228
+ control: dpValue
229
+ })
230
+ } : dpSupportMap.zoom_control ? {
231
+ code: 'zoom_control',
232
+ value: dpValue
233
+ } : null;
234
+ if (!zoomConfig) return;
235
+ const dpData = await getDpIdByCode(devId, zoomConfig.code);
236
+ if (dpData.code === 0) {
237
+ const zoomControlId = dpData.data;
152
238
  publishDps(devId, {
153
- [ptzControlId]: sndDpValue
239
+ [zoomControlId]: zoomConfig.value
154
240
  });
155
241
  ptzTimeId.current = setInterval(() => {
156
242
  publishDps(devId, {
157
- [ptzControlId]: sndDpValue
243
+ [zoomControlId]: zoomConfig.value
158
244
  });
159
245
  }, 1000);
160
246
  }
@@ -177,8 +263,17 @@ export const MoveablePtzControlItem = props => {
177
263
  pageX,
178
264
  pageY
179
265
  } = event.changedTouches[0];
266
+ const deltaX = pageX - pageStartRef.current.pageX;
267
+ const deltaY = pageY - pageStartRef.current.pageY;
268
+ const newLeft = style.positionLeft + deltaX;
269
+ const newBottom = style.positionBottom - deltaY;
270
+
271
+ // 应用边界限制
272
+ const clamped = clampPosition(newLeft, newBottom);
273
+ const clampedDeltaX = clamped.positionLeft - style.positionLeft;
274
+ const clampedDeltaY = style.positionBottom - clamped.positionBottom;
180
275
  (_moveDomRef$current = moveDomRef.current) === null || _moveDomRef$current === void 0 || _moveDomRef$current.setStyle({
181
- transform: `translateY(${pageY - pageStartRef.current.pageY}px) translateX(${pageX - pageStartRef.current.pageX}px)`
276
+ transform: `translateY(${clampedDeltaY}px) translateX(${clampedDeltaX}px)`
182
277
  });
183
278
  },
184
279
  onTouchStart: event => {
@@ -208,10 +303,10 @@ export const MoveablePtzControlItem = props => {
208
303
  const deltaY = pageY - pageStartRef.current.pageY;
209
304
  const newPositionLeft = deltaX + style.positionLeft;
210
305
  const newPositionBottom = style.positionBottom - deltaY;
211
- onDragEnd === null || onDragEnd === void 0 || onDragEnd({
212
- positionLeft: newPositionLeft,
213
- positionBottom: newPositionBottom
214
- });
306
+
307
+ // 应用边界限制
308
+ const clamped = clampPosition(newPositionLeft, newPositionBottom);
309
+ onDragEnd === null || onDragEnd === void 0 || onDragEnd(clamped);
215
310
  ty.nativeDisabled(false);
216
311
  }
217
312
  }, /*#__PURE__*/React.createElement(IpcPtzZoom, {
@@ -223,15 +318,22 @@ export const MoveablePtzControlItem = props => {
223
318
  onTouchPtzStart: onTouchPtzStart,
224
319
  onTouchPtzEnd: async () => {
225
320
  screenMode === MultiCameraScreenMode.landscape && event.emit(startTimeToHideAllComponent);
226
- const ptzStopData = await getDpIdByCode(devId, 'ipc_multi_ptz_stop');
227
- if (ptzStopData.code === 0) {
228
- const ptzStopId = ptzStopData.data;
229
- const sendDpValue = JSON.stringify({
321
+ const stopConfig = dpSupportMap.ipc_multi_ptz_control ? {
322
+ code: 'ipc_multi_ptz_stop',
323
+ value: JSON.stringify({
230
324
  index: selectedLenInfo.index
231
- });
232
- publishDps(devId, {
233
- [ptzStopId]: sendDpValue
234
- });
325
+ })
326
+ } : dpSupportMap.ptz_control ? {
327
+ code: 'ptz_stop',
328
+ value: true
329
+ } : null;
330
+ if (stopConfig) {
331
+ const ptzStopData = await getDpIdByCode(devId, stopConfig.code);
332
+ if (ptzStopData.code === 0) {
333
+ publishDps(devId, {
334
+ [ptzStopData.data]: stopConfig.value
335
+ });
336
+ }
235
337
  }
236
338
  if (ptzTimeId.current) {
237
339
  clearInterval(ptzTimeId.current);
@@ -241,15 +343,22 @@ export const MoveablePtzControlItem = props => {
241
343
  onTouchZoomStart: onTouchZoomStart,
242
344
  onTouchZoomEnd: async () => {
243
345
  screenMode === MultiCameraScreenMode.landscape && event.emit(startTimeToHideAllComponent);
244
- const ptzStopData = await getDpIdByCode(devId, 'ipc_multi_zoom_stop');
245
- if (ptzStopData.code === 0) {
246
- const ptzStopId = ptzStopData.data;
247
- const sendDpValue = JSON.stringify({
346
+ const stopConfig = dpSupportMap.ipc_multi_zoom_control ? {
347
+ code: 'ipc_multi_zoom_stop',
348
+ value: JSON.stringify({
248
349
  index: selectedLenInfo.index
249
- });
250
- publishDps(devId, {
251
- [ptzStopId]: sendDpValue
252
- });
350
+ })
351
+ } : dpSupportMap.zoom_control ? {
352
+ code: 'zoom_stop',
353
+ value: true
354
+ } : null;
355
+ if (stopConfig) {
356
+ const zoomStopData = await getDpIdByCode(devId, stopConfig.code);
357
+ if (zoomStopData.code === 0) {
358
+ publishDps(devId, {
359
+ [zoomStopData.data]: stopConfig.value
360
+ });
361
+ }
253
362
  }
254
363
  if (ptzTimeId.current) {
255
364
  clearInterval(ptzTimeId.current);
@@ -63,11 +63,13 @@ export declare const VoiceIntercom: React.ForwardRefExoticComponent<{
63
63
  nextLayoutStyle: import("../../interface").RetAtom<import("../../interface").MultiCameraLayoutStyle>;
64
64
  selectedLenInfo: import("../../interface").RetAtom<import("../../interface").MultiCameraLenInfo>;
65
65
  ptzStatus: import("../../interface").RetAtom<boolean>;
66
+ dpSupportMap: Record<"ptz_control" | "ipc_multi_locate_coor" | "zoom_control" | "ipc_multi_locate_coors" | "ipc_multi_ptz_control" | "ipc_multi_zoom_control", boolean>;
66
67
  extendProps: {
67
68
  type: number | undefined;
68
69
  onSelectVideoIndex: (this: any, event: any) => void;
69
70
  onLayoutStatusChanged: (this: any, event: any) => void;
70
71
  onLocalizerViewLocated: (this: any, event: any) => Promise<void>;
72
+ onSwipeAtVideoIndex: (this: any, event: any) => Promise<void>;
71
73
  };
72
74
  setLayoutStyle: (style: import("../../interface").MultiCameraLayoutStyle) => void;
73
75
  setScreenMode: (mode: import("../../interface").MultiCameraScreenMode) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.29-beta.2",
3
+ "version": "0.0.29-beta.4",
4
4
  "description": "IPC 融合播放器",
5
5
  "main": "lib/index",
6
6
  "files": [