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

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.
Files changed (82) hide show
  1. package/lib/ctx/ctx.composition.js +43 -1
  2. package/lib/ctx/ctx.js +5 -0
  3. package/lib/ctx/multiCameraCtx.d.ts +40 -5
  4. package/lib/ctx/multiCameraCtx.js +166 -20
  5. package/lib/features/initPlayerWidgets/index.d.ts +7 -1
  6. package/lib/features/initPlayerWidgets/index.js +14 -11
  7. package/lib/hooks/index.d.ts +2 -0
  8. package/lib/hooks/index.js +3 -1
  9. package/lib/hooks/useDpSupport/index.d.ts +6 -0
  10. package/lib/hooks/useDpSupport/index.js +47 -0
  11. package/lib/hooks/useSignal4G/index.d.ts +2 -0
  12. package/lib/hooks/useSignal4G/index.js +35 -0
  13. package/lib/index.d.ts +2 -1
  14. package/lib/index.js +2 -1
  15. package/lib/interface.d.ts +43 -2
  16. package/lib/ports.output.d.ts +4 -0
  17. package/lib/ports.output.js +3 -1
  18. package/lib/res/index.d.ts +1 -0
  19. package/lib/res/index.js +21 -1
  20. package/lib/res/svg/signalFour0.svg +1 -0
  21. package/lib/res/svg/signalFour1.svg +1 -0
  22. package/lib/res/svg/signalFour2.svg +1 -0
  23. package/lib/res/svg/signalFour3.svg +1 -0
  24. package/lib/res/svg/signalFour4.svg +1 -0
  25. package/lib/res/svg/signalThree0.svg +1 -0
  26. package/lib/res/svg/signalThree1.svg +1 -0
  27. package/lib/res/svg/signalThree2.svg +1 -0
  28. package/lib/res/svg/signalThree3.svg +1 -0
  29. package/lib/svg-module.d.ts +4 -0
  30. package/lib/ui/constant.d.ts +20 -0
  31. package/lib/ui/constant.js +21 -0
  32. package/lib/ui/index.d.ts +2 -0
  33. package/lib/ui/index.js +3 -1
  34. package/lib/ui/ui.d.ts +2 -0
  35. package/lib/ui/ui.js +130 -38
  36. package/lib/ui/ui.less +33 -4
  37. package/lib/ui/widgetClick.d.ts +2 -0
  38. package/lib/ui/widgetClick.js +2 -0
  39. package/lib/utils/content/dpCode.d.ts +5 -0
  40. package/lib/utils/content/dpCode.js +11 -1
  41. package/lib/utils/index.d.ts +2 -0
  42. package/lib/utils/index.js +12 -1
  43. package/lib/utils/videoSplitHelper.d.ts +18 -0
  44. package/lib/utils/videoSplitHelper.js +48 -0
  45. package/lib/widgets/fullScreen/fullScreen.js +6 -4
  46. package/lib/widgets/fullScreen/fullTravelRouteControl.js +4 -1
  47. package/lib/widgets/fullScreen/fullVoiceIntercom.js +5 -2
  48. package/lib/widgets/fullScreen/verticalScreen.js +1 -1
  49. package/lib/widgets/fullSmallIntercom/fullSmallIntercom.js +4 -1
  50. package/lib/widgets/index.d.ts +2 -0
  51. package/lib/widgets/index.js +3 -1
  52. package/lib/widgets/moveInteractiveControl/controlButton.js +4 -1
  53. package/lib/widgets/moveInteractiveControl/moveInteractiveControl.js +7 -1
  54. package/lib/widgets/multiCamera/index.less +28 -5
  55. package/lib/widgets/multiCamera/moveablePtzControl.js +229 -47
  56. package/lib/widgets/multiCamera/tileActions.js +2 -2
  57. package/lib/widgets/muted/muted.js +12 -11
  58. package/lib/widgets/ptz/ptz.js +4 -1
  59. package/lib/widgets/ptzControlTip/ptzControlTip.js +4 -1
  60. package/lib/widgets/recordVideo/recordVideo.js +6 -1
  61. package/lib/widgets/resolution/fullResolutionControl.js +10 -2
  62. package/lib/widgets/resolution/resolution.js +4 -1
  63. package/lib/widgets/screenshot/screenshot.js +6 -1
  64. package/lib/widgets/signal4G/index.d.ts +1 -0
  65. package/lib/widgets/signal4G/index.js +1 -0
  66. package/lib/widgets/signal4G/signal4G.d.ts +8 -0
  67. package/lib/widgets/signal4G/signal4G.js +28 -0
  68. package/lib/widgets/signal4G/signal4G.less +15 -0
  69. package/lib/widgets/toggleVerticalFull/index.d.ts +1 -0
  70. package/lib/widgets/toggleVerticalFull/index.js +1 -0
  71. package/lib/widgets/toggleVerticalFull/toggleVerticalFull.d.ts +8 -0
  72. package/lib/widgets/toggleVerticalFull/toggleVerticalFull.js +32 -0
  73. package/lib/widgets/toggleVerticalFull/toggleVerticalFull.less +4 -0
  74. package/lib/widgets/verticalSmallIntercom/verticalSmallIntercom.js +4 -1
  75. package/lib/widgets/voiceIntercom/voiceIntercom.js +18 -21
  76. package/lib/widgets/voiceIntercom/voiceIntercom.less +85 -0
  77. package/package.json +6 -7
  78. package/lib/ctx/ctx.composition.d.ts +0 -10
  79. package/lib/features/initPlayerWidgets/multiCamera.d.ts +0 -8
  80. package/lib/features/initPlayerWidgets/multiCamera.js +0 -78
  81. package/lib/widgets/battery/battery.composition.d.ts +0 -155
  82. package/lib/widgets/voiceIntercom/voiceIntercom.d.ts +0 -93
@@ -4,8 +4,10 @@ const _excluded = ["title", "duration"];
4
4
  import { getCameraConfigInfo } from '@ray-js/ray-ipc-utils';
5
5
  import { IntercomMode, MuteMode, ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
6
6
  import { createUseCtx } from './ctx';
7
- import { FullSmallIntercom, VerticalSmallIntercom, BatteryFull, Battery, Screenshot, TempHumidity, RecordVideo, FullScreen, VideoBitKBP, Muted, Resolution, Ptz } from '../widgets';
7
+ import { FullSmallIntercom, VerticalSmallIntercom, BatteryFull, Battery, Screenshot, TempHumidity, Signal4G, RecordVideo, FullScreen, VideoBitKBP, Muted, Resolution, Ptz, MultiPtz, TileTip, PtzMoveableTip, LandscapeTip, TileActions, MoveablePtzControl, SwitchLayout, ToggleVerticalFull } from '../widgets';
8
8
  import { authorizeStatus } from '../utils/authorize';
9
+ import { landscapeTipId, moveablePtzControlId, multiPtzId, ptzMoveableTipId, tileActionsId, tileTipId } from '../ui/constant';
10
+ import { multiPrefix } from '../widgets/multiCamera/constants';
9
11
  const createPlayContext = ty.createIpcPlayerContext;
10
12
  // const createPlayContext = () => null;
11
13
 
@@ -16,6 +18,9 @@ export const defaultTopLeftContent = [{
16
18
  export const defaultTopRightContent = [{
17
19
  id: 'BatteryFull',
18
20
  content: BatteryFull
21
+ }, {
22
+ id: 'Signal4G',
23
+ content: Signal4G
19
24
  }, {
20
25
  id: 'TempHumidity',
21
26
  content: TempHumidity
@@ -42,15 +47,52 @@ export const defaultBottomLeftContent = [{
42
47
  }, {
43
48
  id: 'Ptz',
44
49
  content: Ptz
50
+ }, {
51
+ id: multiPtzId,
52
+ content: MultiPtz,
53
+ hidden: true
45
54
  }, {
46
55
  id: 'Resolution',
47
56
  content: Resolution
48
57
  }];
49
58
  export const defaultBottomRightContent = [{
59
+ id: 'SwitchLayout',
60
+ content: SwitchLayout,
61
+ hidden: true
62
+ }, {
63
+ id: 'ToggleVerticalFull',
64
+ content: ToggleVerticalFull,
65
+ hidden: true
66
+ }, {
50
67
  id: 'FullScreen',
51
68
  content: FullScreen
52
69
  }];
53
70
  const absoluteContent = [];
71
+ export const multiCameraAbsoluteContent = [{
72
+ id: tileTipId,
73
+ content: TileTip,
74
+ absoluteContentClassName: `${multiPrefix}-tile-tip-wrap`,
75
+ hidden: true
76
+ }, {
77
+ id: ptzMoveableTipId,
78
+ content: PtzMoveableTip,
79
+ absoluteContentClassName: `${multiPrefix}-tile-tip-wrap`,
80
+ hidden: true
81
+ }, {
82
+ id: landscapeTipId,
83
+ content: LandscapeTip,
84
+ absoluteContentClassName: `${multiPrefix}-tile-tip-wrap`,
85
+ hidden: true
86
+ }, {
87
+ id: tileActionsId,
88
+ absoluteContentClassName: `${multiPrefix}-actions-wrap`,
89
+ content: TileActions
90
+ }, {
91
+ id: moveablePtzControlId,
92
+ content: MoveablePtzControl,
93
+ absoluteNoCoverView: true,
94
+ hidden: true
95
+ }];
54
96
  const toast = _ref => {
55
97
  let {
56
98
  title,
package/lib/ctx/ctx.js CHANGED
@@ -43,6 +43,9 @@ export const createUseCtx = _ref => {
43
43
  // 全屏、竖屏
44
44
  const [screenType, setScreenType] = useAtom('vertical');
45
45
 
46
+ // 是否处于竖屏填充布局
47
+ const [isVerticalFullLayout, setIsVerticalFullLayout] = useAtom(false);
48
+
46
49
  // 录像中
47
50
  const [recording] = useAtom(false);
48
51
 
@@ -244,6 +247,8 @@ export const createUseCtx = _ref => {
244
247
  verticalMic,
245
248
  saveToAlbum,
246
249
  screenType,
250
+ isVerticalFullLayout,
251
+ setIsVerticalFullLayout,
247
252
  recording,
248
253
  recordingDisabled,
249
254
  ptzControlTipDisabled,
@@ -1,4 +1,16 @@
1
+ /// <reference types="react" />
1
2
  import { MultiCameraLayoutStyle, MultiCameraLenInfo, MultiCameraScreenMode, VideoSplitProtocol } from '../interface';
3
+ interface MultiCameraViewLenName {
4
+ index: number;
5
+ name: string;
6
+ }
7
+ interface MultiCameraViewDataSource {
8
+ selectedVideoBorderColor?: string;
9
+ localizerLineColor?: string;
10
+ localizeCrosshairColor?: string;
11
+ localizerTip?: string;
12
+ lenNames?: MultiCameraViewLenName[];
13
+ }
2
14
  interface Props {
3
15
  devId: string;
4
16
  IPCPlayerInstance: IpcContext;
@@ -32,27 +44,46 @@ export declare const useMultiCameraCtx: (props: Props) => {
32
44
  * 选中镜头信息
33
45
  */
34
46
  selectedLenInfo: import("../interface").RetAtom<MultiCameraLenInfo>;
47
+ /**
48
+ * 本轮点击周期内是否触发了镜头选中事件
49
+ */
50
+ selectVideoFiredRef: import("react").MutableRefObject<boolean>;
51
+ /**
52
+ * 最新选中镜头信息(同步引用,避免依赖渲染时机)
53
+ */
54
+ selectedLenInfoRef: import("react").MutableRefObject<MultiCameraLenInfo>;
35
55
  /**
36
56
  * ptz状态
37
57
  */
38
58
  ptzStatus: import("../interface").RetAtom<boolean>;
59
+ /**
60
+ * 多目设备支持的 dp
61
+ */
62
+ dpSupportMap: Record<"ptz_control" | "ipc_multi_locate_coor" | "zoom_control" | "ipc_multi_locate_coors" | "ipc_multi_ptz_control" | "ipc_multi_zoom_control", boolean>;
39
63
  /**
40
64
  * ipcPlayer extendProps
41
65
  */
42
66
  extendProps: {
43
- type: number | undefined;
67
+ type: number;
44
68
  onSelectVideoIndex: (this: any, event: any) => void;
45
69
  onLayoutStatusChanged: (this: any, event: any) => void;
46
70
  onLocalizerViewLocated: (this: any, event: any) => Promise<void>;
71
+ onSwipeAtVideoIndex: (this: any, event: any) => Promise<void>;
72
+ } | {
73
+ type?: undefined;
74
+ onSelectVideoIndex?: undefined;
75
+ onLayoutStatusChanged?: undefined;
76
+ onLocalizerViewLocated?: undefined;
77
+ onSwipeAtVideoIndex?: undefined;
47
78
  };
48
79
  /**
49
80
  * 设置布局样式
50
81
  */
51
- setLayoutStyle: (style: MultiCameraLayoutStyle) => void;
82
+ setLayoutStyle: (this: unknown, style: MultiCameraLayoutStyle) => void;
52
83
  /**
53
84
  * 设置屏幕模式
54
85
  */
55
- setScreenMode: (mode: MultiCameraScreenMode) => void;
86
+ setScreenMode: (this: unknown, mode: MultiCameraScreenMode) => void;
56
87
  /**
57
88
  * 设置ptz状态
58
89
  */
@@ -60,7 +91,7 @@ export declare const useMultiCameraCtx: (props: Props) => {
60
91
  /**
61
92
  * 显示/隐藏镜头名称
62
93
  */
63
- showLenNames: (value: boolean) => void;
94
+ showLenNames: (this: unknown, value: boolean) => void;
64
95
  /**
65
96
  * 设置下一个布局样式
66
97
  */
@@ -68,6 +99,10 @@ export declare const useMultiCameraCtx: (props: Props) => {
68
99
  /**
69
100
  * 获取下一个布局样式
70
101
  */
71
- getNextLayoutStyle: () => Promise<MultiCameraLayoutStyle>;
102
+ getNextLayoutStyle: (this: unknown) => Promise<MultiCameraLayoutStyle>;
103
+ /**
104
+ * 设置多目镜头视图数据
105
+ */
106
+ setViewData: (this: unknown, dataSource: MultiCameraViewDataSource) => void;
72
107
  };
73
108
  export {};
@@ -1,14 +1,30 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
1
2
  import { getDpIdByCode, publishDps } from '@ray-js/ray-ipc-utils';
2
3
  import { useMemoizedFn } from 'ahooks';
3
- import { useMemo } from 'react';
4
+ import { useMemo, useRef } from 'react';
4
5
  import { MultiCameraLayoutStyle, MultiCameraScreenMode } from '../interface';
6
+ import { useDpSupport } from '../hooks';
7
+ import { GUN_BALL, MULTI_GUN_BALL, MULTI_PTZ_CONTROL, MULTI_ZOOM_CONTROL, PTZ_CONTROL, ZOOM_CONTROL } from '../utils/content/dpCode';
8
+ import { getLensSupportDirections, isSwipeDirectionSupported } from '../utils';
5
9
  import { useAtom } from './store';
6
10
  const DEFAULT_VIDEO_SPLIT_PROTOCOL = {
7
11
  total_split_num: 1,
8
12
  split_info: [],
9
- align_info: [],
13
+ align_info: {
14
+ align_group: [],
15
+ linked_group: [],
16
+ localizer_group: []
17
+ },
10
18
  p_v: 3
11
19
  };
20
+ const DP_CODES = [PTZ_CONTROL, GUN_BALL, ZOOM_CONTROL, MULTI_GUN_BALL, MULTI_PTZ_CONTROL, MULTI_ZOOM_CONTROL];
21
+ const DEFAULT_SELECTED_LEN_INFO = {
22
+ index: 1,
23
+ videoName: '',
24
+ supportPTZ: false,
25
+ supportLocalizer: false,
26
+ supportZoom: false
27
+ };
12
28
  /**
13
29
  * 多目摄像头相关状态、方法维护
14
30
  */
@@ -21,19 +37,24 @@ export const useMultiCameraCtx = props => {
21
37
  const isSupport = useMemo(() => {
22
38
  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
39
  }, [IPCPlayerInstance, videoSplitProtocol]);
40
+ const dpSupportMap = useDpSupport({
41
+ devId,
42
+ dpCodes: DP_CODES
43
+ });
44
+
45
+ // PTZ控制定时器
46
+ const ptzTimerRef = useRef(null);
24
47
  const [layoutStyleAtom, setLayoutStyle] = useAtom(isSupport ? MultiCameraLayoutStyle.tile : MultiCameraLayoutStyle.pip);
25
48
  const [screenModeAtom, setScreenMode] = useAtom(isSupport ? MultiCameraScreenMode.full : MultiCameraScreenMode.short);
26
- const [selectedLenInfoAtom, setSelectedLenInfo] = useAtom({
27
- index: 1,
28
- videoName: '',
29
- supportPTZ: false,
30
- supportLocalizer: false,
31
- supportZoom: false
32
- });
49
+ const [selectedLenInfoAtom, setSelectedLenInfo] = useAtom(DEFAULT_SELECTED_LEN_INFO);
33
50
  const [nextLayoutStyleAtom, setNextLayoutStyle] = useAtom(MultiCameraLayoutStyle.invalid);
34
51
  const [ptzStatusAtom, setPtzStatus] = useAtom(false);
52
+ const selectVideoFiredRef = useRef(false);
53
+ const selectedLenInfoRef = useRef(DEFAULT_SELECTED_LEN_INFO);
35
54
  const handleSelectVideoIndex = useMemoizedFn(event => {
36
55
  console.info('onSelectVideoIndex', JSON.stringify(event === null || event === void 0 ? void 0 : event.detail));
56
+ selectVideoFiredRef.current = true;
57
+ selectedLenInfoRef.current = event.detail;
37
58
  setSelectedLenInfo(event.detail);
38
59
  });
39
60
  const handleLayoutStatusChanged = useMemoizedFn(event => {
@@ -46,25 +67,123 @@ export const useMultiCameraCtx = props => {
46
67
  setScreenMode(screenMode);
47
68
  });
48
69
  const handleLocalizerViewLocated = useMemoizedFn(async event => {
70
+ var _event$detail;
49
71
  console.info('onLocalizerViewLocated', JSON.stringify(event === null || event === void 0 ? void 0 : event.detail));
50
- const dpData = await getDpIdByCode(devId, 'ipc_multi_locate_coors');
72
+ const locateDpConfig = dpSupportMap.ipc_multi_locate_coors ? {
73
+ code: 'ipc_multi_locate_coors',
74
+ value: JSON.stringify(event.detail)
75
+ } : dpSupportMap.ipc_multi_locate_coor ? {
76
+ code: 'ipc_multi_locate_coor',
77
+ value: String((_event$detail = event.detail) === null || _event$detail === void 0 ? void 0 : _event$detail.coor)
78
+ } // 兼容老 dp
79
+ : null;
80
+ if (!locateDpConfig) return;
81
+ const dpData = await getDpIdByCode(devId, locateDpConfig.code);
51
82
  if (dpData.code === 0) {
52
- const dpId = dpData.data;
53
- const sndDpValue = JSON.stringify(event.detail);
54
83
  publishDps(devId, {
55
- [dpId]: sndDpValue
84
+ [dpData.data]: locateDpConfig.value
56
85
  });
57
86
  }
58
87
  });
88
+ const handleSwipeAtVideoIndex = useMemoizedFn(async event => {
89
+ console.info('onSwipeAtVideoIndex', JSON.stringify(event === null || event === void 0 ? void 0 : event.detail));
90
+ const {
91
+ index,
92
+ direction,
93
+ isStop
94
+ } = (event === null || event === void 0 ? void 0 : event.detail) || {};
95
+
96
+ // 停止当前PTZ的通用方法
97
+ const stopPtz = async () => {
98
+ const stopConfig = dpSupportMap.ipc_multi_ptz_control ? {
99
+ code: 'ipc_multi_ptz_stop',
100
+ value: JSON.stringify({
101
+ index
102
+ })
103
+ } : dpSupportMap.ptz_control ? {
104
+ code: 'ptz_stop',
105
+ value: true
106
+ } : null;
107
+ if (stopConfig) {
108
+ const ptzStopData = await getDpIdByCode(devId, stopConfig.code);
109
+ if (ptzStopData.code === 0) {
110
+ publishDps(devId, {
111
+ [ptzStopData.data]: stopConfig.value
112
+ });
113
+ }
114
+ }
115
+
116
+ // 清除定时器
117
+ if (ptzTimerRef.current) {
118
+ clearInterval(ptzTimerRef.current);
119
+ ptzTimerRef.current = null;
120
+ }
121
+ };
122
+
123
+ // isStop === true 表示结束事件,只需停止PTZ
124
+ if (isStop) {
125
+ await stopPtz();
126
+ return;
127
+ }
128
+
129
+ // !isStop 表示开始事件或方向变化事件
130
+ // 先停止旧方向,再启动新方向
131
+ if (!isStop) {
132
+ // 1. 先停止之前的PTZ控制(如果有)
133
+ await stopPtz();
134
+ const directionValue = Number(direction);
135
+ if (!isSwipeDirectionSupported(videoSplitProtocol, index, directionValue)) {
136
+ const supportDirections = getLensSupportDirections(videoSplitProtocol, index);
137
+ console.info('onSwipeAtVideoIndex direction not supported', {
138
+ index,
139
+ direction,
140
+ supportDirections
141
+ });
142
+ return;
143
+ }
144
+
145
+ // 2. 构建新方向的PTZ配置
146
+ const ptzConfig = dpSupportMap.ipc_multi_ptz_control ? {
147
+ code: 'ipc_multi_ptz_control',
148
+ value: JSON.stringify({
149
+ index,
150
+ direction: String(directionValue)
151
+ })
152
+ } : dpSupportMap.ptz_control ? {
153
+ code: 'ptz_control',
154
+ value: String(directionValue)
155
+ } : null;
156
+ if (!ptzConfig) return;
157
+
158
+ // 3. 启动新方向的PTZ控制
159
+ const dpData = await getDpIdByCode(devId, ptzConfig.code);
160
+ if (dpData.code === 0) {
161
+ const ptzControlId = dpData.data;
162
+
163
+ // 立即发送一次新方向
164
+ publishDps(devId, {
165
+ [ptzControlId]: ptzConfig.value
166
+ });
167
+
168
+ // 每秒持续发送新方向
169
+ ptzTimerRef.current = setInterval(() => {
170
+ publishDps(devId, {
171
+ [ptzControlId]: ptzConfig.value
172
+ });
173
+ }, 1000);
174
+ }
175
+ }
176
+ });
59
177
  const extendProps = useMemo(() => {
60
- return {
61
- // type: 4 表示多目摄像头
62
- type: isSupport ? 4 : undefined,
178
+ return isSupport ? {
179
+ type: 4,
180
+ // 表示多目摄像头
63
181
  onSelectVideoIndex: handleSelectVideoIndex,
64
182
  onLayoutStatusChanged: handleLayoutStatusChanged,
65
- onLocalizerViewLocated: handleLocalizerViewLocated
66
- };
67
- }, [videoSplitProtocol]);
183
+ onLocalizerViewLocated: handleLocalizerViewLocated,
184
+ onSwipeAtVideoIndex: handleSwipeAtVideoIndex
185
+ } : {};
186
+ }, [isSupport]);
68
187
  const _setLayoutStyle = useMemoizedFn(style => {
69
188
  var _IPCPlayerInstance$sw;
70
189
  IPCPlayerInstance === null || IPCPlayerInstance === void 0 || (_IPCPlayerInstance$sw = IPCPlayerInstance.switchLayoutStyle) === null || _IPCPlayerInstance$sw === void 0 || _IPCPlayerInstance$sw.call(IPCPlayerInstance, {
@@ -116,6 +235,17 @@ export const useMultiCameraCtx = props => {
116
235
  }
117
236
  });
118
237
  });
238
+ const setViewData = useMemoizedFn(dataSource => {
239
+ var _IPCPlayerInstance$se;
240
+ IPCPlayerInstance === null || IPCPlayerInstance === void 0 || (_IPCPlayerInstance$se = IPCPlayerInstance.setMultiCameraViewDataSource) === null || _IPCPlayerInstance$se === void 0 || _IPCPlayerInstance$se.call(IPCPlayerInstance, _objectSpread(_objectSpread({}, dataSource), {}, {
241
+ success: () => {
242
+ console.info('setMultiCameraViewDataSource success', JSON.stringify(dataSource));
243
+ },
244
+ fail: err => {
245
+ console.error('setMultiCameraViewDataSource fail', err);
246
+ }
247
+ }));
248
+ });
119
249
  return {
120
250
  /**
121
251
  * 是否支持多目
@@ -141,10 +271,22 @@ export const useMultiCameraCtx = props => {
141
271
  * 选中镜头信息
142
272
  */
143
273
  selectedLenInfo: selectedLenInfoAtom,
274
+ /**
275
+ * 本轮点击周期内是否触发了镜头选中事件
276
+ */
277
+ selectVideoFiredRef,
278
+ /**
279
+ * 最新选中镜头信息(同步引用,避免依赖渲染时机)
280
+ */
281
+ selectedLenInfoRef,
144
282
  /**
145
283
  * ptz状态
146
284
  */
147
285
  ptzStatus: ptzStatusAtom,
286
+ /**
287
+ * 多目设备支持的 dp
288
+ */
289
+ dpSupportMap,
148
290
  /**
149
291
  * ipcPlayer extendProps
150
292
  */
@@ -172,6 +314,10 @@ export const useMultiCameraCtx = props => {
172
314
  /**
173
315
  * 获取下一个布局样式
174
316
  */
175
- getNextLayoutStyle
317
+ getNextLayoutStyle,
318
+ /**
319
+ * 设置多目镜头视图数据
320
+ */
321
+ setViewData
176
322
  };
177
323
  };
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { UseCtx, WidgetId } from '../../interface';
2
+ import { ComponentConfig, UseCtx, WidgetId } from '../../interface';
3
3
  import { FullScreen } from '../../widgets';
4
4
  type Ctx = ReturnType<UseCtx>;
5
5
  export type InitPlayerWidgetsOptions = {
@@ -9,7 +9,13 @@ export type InitPlayerWidgetsOptions = {
9
9
  hideRecordVideoMenu?: boolean;
10
10
  hideResolutionMenu?: boolean;
11
11
  hideKbsMenu?: boolean;
12
+ showToggleVerticalFull?: boolean;
12
13
  directionControlProps?: Partial<React.ComponentProps<typeof FullScreen>['directionControlProps']>;
14
+ topLeftContent?: ComponentConfig[];
15
+ topRightContent?: ComponentConfig[];
16
+ bottomLeftContent?: ComponentConfig[];
17
+ bottomRightContent?: ComponentConfig[];
18
+ absoluteContent?: ComponentConfig[];
13
19
  };
14
20
  export declare function initPlayerWidgets(ctx: Ctx, options: InitPlayerWidgetsOptions): Promise<boolean>;
15
21
  export declare function updatePlayerWidgetProps(ctx: Ctx, area: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'absolute', widgetId: WidgetId, newProps: Record<string, any>): Promise<void>;
@@ -1,19 +1,13 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _cloneDeep from 'lodash/cloneDeep';
3
- import { defaultTopLeftContent, defaultTopRightContent, defaultBottomLeftContent, defaultBottomRightContent } from '../../ctx';
3
+ import { defaultTopLeftContent, defaultTopRightContent, defaultBottomLeftContent, defaultBottomRightContent, multiCameraAbsoluteContent } from '../../ctx';
4
4
  import { hasDpCode } from '../../utils/device';
5
5
  import { MoveInteractiveControlButton } from '../../widgets/moveInteractiveControl';
6
- import { initMultiCameraPlayerWidgets } from './multiCamera';
7
6
  // 根据当前 dp 信息决定设置哪些 plugin
8
7
  export async function initPlayerWidgets(ctx, options) {
9
- // 初始化多目设备控件
10
- if (ctx.multiCameraCtx.isSupport) {
11
- initMultiCameraPlayerWidgets(ctx, options);
12
- return true;
13
- }
14
- ctx.addContent('topLeft', defaultTopLeftContent);
15
- const newDefaultBottomLeftContent = _cloneDeep(defaultBottomLeftContent);
16
- const newDefaultTopRightContent = _cloneDeep(defaultTopRightContent);
8
+ ctx.addContent('topLeft', options.topLeftContent || defaultTopLeftContent);
9
+ const newDefaultBottomLeftContent = _cloneDeep(options.bottomLeftContent || defaultBottomLeftContent);
10
+ const newDefaultTopRightContent = _cloneDeep(options.topRightContent || defaultTopRightContent);
17
11
  const videoKbsIndex = newDefaultTopRightContent.findIndex(item => item.id === 'VideoBitKBP');
18
12
  if (videoKbsIndex !== -1) {
19
13
  newDefaultTopRightContent[videoKbsIndex].initProps = {
@@ -44,7 +38,7 @@ export async function initPlayerWidgets(ctx, options) {
44
38
  };
45
39
  }
46
40
  ctx.addContent('bottomLeft', newDefaultBottomLeftContent);
47
- const newDefaultBottomRightContent = _cloneDeep(defaultBottomRightContent);
41
+ const newDefaultBottomRightContent = _cloneDeep(options.bottomRightContent || defaultBottomRightContent);
48
42
  const fullScreenIndex = newDefaultBottomRightContent.findIndex(item => item.id === 'FullScreen');
49
43
  if (fullScreenIndex !== -1) {
50
44
  // @ts-ignore
@@ -64,6 +58,15 @@ export async function initPlayerWidgets(ctx, options) {
64
58
  }, -1);
65
59
  }
66
60
  });
61
+
62
+ // 初始化多目设备控件
63
+ if (ctx.multiCameraCtx.isSupport) {
64
+ ctx.hideContent('bottomLeft', 'Ptz'); // 隐藏单路云台
65
+ ctx.showContent('bottomRight', 'SwitchLayout'); // 多目默认展示切换竖屏组件
66
+ ctx.addContent('absolute', multiCameraAbsoluteContent);
67
+ } else if (options.showToggleVerticalFull) {
68
+ ctx.showContent('bottomRight', 'ToggleVerticalFull');
69
+ }
67
70
  return true;
68
71
  }
69
72
  export async function updatePlayerWidgetProps(ctx, area, widgetId, newProps) {
@@ -1,7 +1,9 @@
1
1
  export * from './useBattery';
2
2
  export * from './useHumidity';
3
3
  export * from './useTemperature';
4
+ export * from './useSignal4G';
4
5
  export * from './useDpState';
5
6
  export * from './useMemoizedFn';
6
7
  export * from './usePtz';
7
8
  export * from './useSchemaInfo.tsx';
9
+ export * from './useDpSupport';
@@ -1,7 +1,9 @@
1
1
  export * from './useBattery';
2
2
  export * from './useHumidity';
3
3
  export * from './useTemperature';
4
+ export * from './useSignal4G';
4
5
  export * from './useDpState';
5
6
  export * from './useMemoizedFn';
6
7
  export * from './usePtz';
7
- export * from './useSchemaInfo.tsx';
8
+ export * from './useSchemaInfo.tsx';
9
+ 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
+ }
@@ -0,0 +1,2 @@
1
+ import type { UseSignal4G } from '../../ports.output';
2
+ export declare const useSignal4G: UseSignal4G;
@@ -0,0 +1,35 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { useDpState } from '../useDpState';
3
+ const CELLULAR_SIGNAL_DP_CODE = 'ipc_cellular_signal';
4
+ export const useSignal4G = devId => {
5
+ const [dpState, dpSchema] = useDpState({
6
+ devId,
7
+ dpCodes: [CELLULAR_SIGNAL_DP_CODE]
8
+ });
9
+
10
+ /**
11
+ * 获取信号图片key
12
+ */
13
+
14
+ const getSignalKey = useCallback(dpValue => {
15
+ var _dpSchema$CELLULAR_SI;
16
+ const range = (_dpSchema$CELLULAR_SI = dpSchema[CELLULAR_SIGNAL_DP_CODE]) === null || _dpSchema$CELLULAR_SI === void 0 || (_dpSchema$CELLULAR_SI = _dpSchema$CELLULAR_SI.property) === null || _dpSchema$CELLULAR_SI === void 0 ? void 0 : _dpSchema$CELLULAR_SI.range;
17
+ if (range.length <= 4) {
18
+ return `signalThree${dpValue}`;
19
+ }
20
+ return `signalFour${dpValue}`;
21
+ }, [dpSchema]);
22
+ const signalInfo = useMemo(() => {
23
+ if (dpState[CELLULAR_SIGNAL_DP_CODE] !== undefined) {
24
+ return {
25
+ dpValue: dpState[CELLULAR_SIGNAL_DP_CODE],
26
+ signalKey: getSignalKey(dpState[CELLULAR_SIGNAL_DP_CODE])
27
+ };
28
+ }
29
+ return {
30
+ dpValue: '',
31
+ signalKey: ''
32
+ };
33
+ }, [dpState]);
34
+ return signalInfo;
35
+ };
package/lib/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from './ctx';
3
3
  export * from './interface';
4
4
  import * as Widgets from './widgets';
5
5
  import * as Features from './features';
6
- export { Widgets, Features };
6
+ import * as Utils from './utils';
7
+ export { Widgets, Features, Utils };
package/lib/index.js CHANGED
@@ -3,4 +3,5 @@ export * from './ctx';
3
3
  export * from './interface';
4
4
  import * as Widgets from './widgets';
5
5
  import * as Features from './features';
6
- export { Widgets, Features };
6
+ import * as Utils from './utils';
7
+ export { Widgets, Features, Utils };