@ray-js/ray-ipc-player 2.0.20 → 2.0.21-beta-2

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.
package/lib/constant.js CHANGED
@@ -1,25 +1,44 @@
1
1
  export let IpcFailCode = /*#__PURE__*/function (IpcFailCode) {
2
+ // 未知异常
2
3
  IpcFailCode[IpcFailCode["ipc_player_unknown"] = -1000] = "ipc_player_unknown";
4
+ // 建立connect连接失败
3
5
  IpcFailCode[IpcFailCode["ipc_player_connect_fail"] = -1001] = "ipc_player_connect_fail";
6
+ // 开启预览失败
4
7
  IpcFailCode[IpcFailCode["ipc_player_preview_fail"] = -1002] = "ipc_player_preview_fail";
8
+ // 网络状态不可用
5
9
  IpcFailCode[IpcFailCode["ipc_player_network_fail"] = -1010] = "ipc_player_network_fail";
10
+ // 设备被移除
6
11
  IpcFailCode[IpcFailCode["ipc_player_device_removed"] = -1012] = "ipc_player_device_removed";
7
12
  return IpcFailCode;
8
13
  }({});
9
14
  export let TipsCode = /*#__PURE__*/function (TipsCode) {
15
+ // 设备离线
10
16
  TipsCode[TipsCode["ipc_player_no_line"] = -1011] = "ipc_player_no_line";
17
+ // disconnect失败
11
18
  TipsCode[TipsCode["ipc_player_disconnect_fail"] = -1009] = "ipc_player_disconnect_fail";
19
+ // 结束预览失败
12
20
  TipsCode[TipsCode["ipc_player_stop_preview_fail"] = -1003] = "ipc_player_stop_preview_fail";
21
+ // 设置静音失败
13
22
  TipsCode[TipsCode["ipc_player_mute_fail"] = -1004] = "ipc_player_mute_fail";
23
+ // 切换清晰度失败
14
24
  TipsCode[TipsCode["ipc_player_resolution_fail"] = -1005] = "ipc_player_resolution_fail";
25
+ // 截图失败
15
26
  TipsCode[TipsCode["ipc_player_capture_fail"] = -1006] = "ipc_player_capture_fail";
27
+ // 开启对讲失败
16
28
  TipsCode[TipsCode["ipc_player_start_talk_fail"] = -1013] = "ipc_player_start_talk_fail";
29
+ // 结束对讲失败
17
30
  TipsCode[TipsCode["ipc_player_stop_talk_fail"] = -1014] = "ipc_player_stop_talk_fail";
31
+ // 开启录屏失败
18
32
  TipsCode[TipsCode["ipc_player_start_record_fail"] = -1015] = "ipc_player_start_record_fail";
33
+ // 结束录屏失败
19
34
  TipsCode[TipsCode["ipc_player_stop_record_fail"] = -1016] = "ipc_player_stop_record_fail";
35
+ // 获取对讲状态失败
20
36
  TipsCode[TipsCode["ipc_player_is_talk_backing_fail"] = -1017] = "ipc_player_is_talk_backing_fail";
37
+ // 摇杆震动设置失败
21
38
  TipsCode[TipsCode["ipc_player_set_available_rocker_directions_fail"] = -1018] = "ipc_player_set_available_rocker_directions_fail";
39
+ // 开启特写追踪失败
22
40
  TipsCode[TipsCode["ipc_player_set_tracking_status_fail"] = -1020] = "ipc_player_set_tracking_status_fail";
41
+ // 获取视频信息失败
23
42
  TipsCode[TipsCode["ipc_player_get_video_info_fail"] = -1021] = "ipc_player_get_video_info_fail";
24
43
  return TipsCode;
25
44
  }({});
@@ -0,0 +1,7 @@
1
+ interface UseWakeUpDeviceOptions {
2
+ deviceId: string;
3
+ enabled: boolean;
4
+ intervalTime?: number;
5
+ }
6
+ export declare const useWakeUpDevice: ({ deviceId, enabled, intervalTime, }: UseWakeUpDeviceOptions) => void;
7
+ export {};
@@ -0,0 +1,34 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { wakeUpDevice } from '../utils';
3
+ export const useWakeUpDevice = _ref => {
4
+ let {
5
+ deviceId,
6
+ enabled,
7
+ intervalTime = 300
8
+ } = _ref;
9
+ const intervalRef = useRef(null);
10
+ useEffect(() => {
11
+ if (!enabled || !deviceId) {
12
+ if (intervalRef.current) {
13
+ clearInterval(intervalRef.current);
14
+ intervalRef.current = null;
15
+ console.log('唤醒定时器已清除');
16
+ }
17
+ return undefined;
18
+ }
19
+ const wakeUp = () => {
20
+ wakeUpDevice(deviceId);
21
+ };
22
+ // 立即唤醒一次
23
+ wakeUp();
24
+ // 设置定时器
25
+ intervalRef.current = setInterval(wakeUp, intervalTime);
26
+ // 清理函数:停止定时器
27
+ return () => {
28
+ if (intervalRef.current) {
29
+ clearInterval(intervalRef.current);
30
+ intervalRef.current = null;
31
+ }
32
+ };
33
+ }, [enabled, deviceId, intervalTime]);
34
+ };
@@ -2,6 +2,9 @@ import { kit } from '@ray-js/panel-sdk';
2
2
  declare const _default: kit.I18N<{
3
3
  en: {
4
4
  ipc_player_get_video_stream: string;
5
+ ipc_player_private_open_stream: string;
6
+ ipc_player_private_open_low_stream: string;
7
+ ipc_player_private_open_low_stream_fail: string;
5
8
  ipc_player_preview_fail: string;
6
9
  ipc_player_stop_preview_fail: string;
7
10
  ipc_player_resolution_fail: string;
@@ -127,6 +130,9 @@ declare const _default: kit.I18N<{
127
130
  };
128
131
  zh: {
129
132
  ipc_player_get_video_stream: string;
133
+ ipc_player_private_open_stream: string;
134
+ ipc_player_private_open_low_stream: string;
135
+ ipc_player_private_open_low_stream_fail: string;
130
136
  ipc_player_preview_fail: string;
131
137
  ipc_player_stop_preview_fail: string;
132
138
  ipc_player_resolution_fail: string;
@@ -252,6 +258,9 @@ declare const _default: kit.I18N<{
252
258
  };
253
259
  }, {
254
260
  ipc_player_get_video_stream: string;
261
+ ipc_player_private_open_stream: string;
262
+ ipc_player_private_open_low_stream: string;
263
+ ipc_player_private_open_low_stream_fail: string;
255
264
  ipc_player_preview_fail: string;
256
265
  ipc_player_stop_preview_fail: string;
257
266
  ipc_player_resolution_fail: string;
@@ -376,6 +385,9 @@ declare const _default: kit.I18N<{
376
385
  ipc_player_traffic_load_online_zero_tip: string;
377
386
  } | {
378
387
  ipc_player_get_video_stream: string;
388
+ ipc_player_private_open_stream: string;
389
+ ipc_player_private_open_low_stream: string;
390
+ ipc_player_private_open_low_stream_fail: string;
379
391
  ipc_player_preview_fail: string;
380
392
  ipc_player_stop_preview_fail: string;
381
393
  ipc_player_resolution_fail: string;
@@ -1,6 +1,9 @@
1
1
  declare const _default: {
2
2
  en: {
3
3
  ipc_player_get_video_stream: string;
4
+ ipc_player_private_open_stream: string;
5
+ ipc_player_private_open_low_stream: string;
6
+ ipc_player_private_open_low_stream_fail: string;
4
7
  ipc_player_preview_fail: string;
5
8
  ipc_player_stop_preview_fail: string;
6
9
  ipc_player_resolution_fail: string;
@@ -126,6 +129,9 @@ declare const _default: {
126
129
  };
127
130
  zh: {
128
131
  ipc_player_get_video_stream: string;
132
+ ipc_player_private_open_stream: string;
133
+ ipc_player_private_open_low_stream: string;
134
+ ipc_player_private_open_low_stream_fail: string;
129
135
  ipc_player_preview_fail: string;
130
136
  ipc_player_stop_preview_fail: string;
131
137
  ipc_player_resolution_fail: string;
@@ -1,6 +1,9 @@
1
1
  export default {
2
2
  en: {
3
3
  ipc_player_get_video_stream: 'Retrieving video stream...',
4
+ ipc_player_private_open_stream: 'Opening, please wait',
5
+ ipc_player_private_open_low_stream: 'Connecting, please wait',
6
+ ipc_player_private_open_low_stream_fail: 'Connection failed, tap below to retry',
4
7
  ipc_player_preview_fail: 'Failed to retrieve video stream',
5
8
  ipc_player_stop_preview_fail: 'Failed to end preview',
6
9
  ipc_player_resolution_fail: 'Failed to switch the video definition',
@@ -138,6 +141,9 @@ export default {
138
141
  },
139
142
  zh: {
140
143
  ipc_player_get_video_stream: '正在获取视频流',
144
+ ipc_player_private_open_stream: '正在开启中, 请稍等',
145
+ ipc_player_private_open_low_stream: '正在连接开启中, 请稍等',
146
+ ipc_player_private_open_low_stream_fail: '连接开启失败, 点击下方重新开启',
141
147
  ipc_player_preview_fail: '获取视频流失败',
142
148
  ipc_player_stop_preview_fail: '结束预览失败',
143
149
  ipc_player_resolution_fail: '切换清晰度失败',
package/lib/index.js CHANGED
@@ -6,12 +6,13 @@ import React, { useState, useEffect, useRef, useCallback } from 'react';
6
6
  import { useImmer } from 'use-immer';
7
7
  import _isEmpty from 'lodash/isEmpty';
8
8
  import { IpcPlayer, View, CoverView } from '@ray-js/components';
9
- import { useMount, useUnmount } from 'ahooks';
10
- import { setPageOrientation, usePageEvent, getNetworkType, offNetworkStatusChange, onNetworkStatusChange, publishDps, showToast, getSystemInfoSync } from '@ray-js/ray';
9
+ import { useMount, useUnmount, useMemoizedFn } from 'ahooks';
10
+ import { setPageOrientation, usePageEvent, getNetworkType, offNetworkStatusChange, onNetworkStatusChange, publishDps, showToast, getSystemInfoSync, onMqttMessageReceived, registerMQTTProtocolListener, offMqttMessageReceived, unregisterMQTTProtocolListener, registerDeviceListListener, onDpDataChange, onDeviceOnlineStatusUpdate } from '@ray-js/ray';
11
11
  import clsx from 'clsx';
12
12
  import Strings from './i18n';
13
13
  import Styles from './index.module.less';
14
14
  import { IpcFailCode } from './constant';
15
+ import { useWakeUpDevice } from './hooks';
15
16
  import { getIsConnected, getIsOnPreview, openTargetMinByShortLink, getLanguage, getHomeInfo, getDeviceInfo, getDpIdByDpCode, ipcTTTOperatorLog } from './utils';
16
17
  import { getErrCodeDetailDataByCode, codeCoverToInt } from './config/errCodeConfig';
17
18
  import { deviceFreezeReasonStore, miniIdLabs } from './config';
@@ -49,7 +50,8 @@ const Player = props => {
49
50
  renderErrIcon,
50
51
  isShare = false,
51
52
  onPlayerContainerTap,
52
- reConnect = false
53
+ reConnect = false,
54
+ awakeStatus = undefined
53
55
  } = props;
54
56
  const {
55
57
  borderRadius,
@@ -63,6 +65,8 @@ const Player = props => {
63
65
  // 连接状态
64
66
  loadingState: true,
65
67
  // 加载状态
68
+ loadingText: Strings.getLang('ipc_player_get_video_stream'),
69
+ // 正在获取视频流
66
70
  errorState: false,
67
71
  // 异常状态
68
72
  errorMsg: '',
@@ -74,10 +78,26 @@ const Player = props => {
74
78
  });
75
79
  const [screenType, setScreenType] = useState('portrait');
76
80
  const [videoErrCode, setVideoErrCode] = useState('');
77
- // 标记是否为配置149的老方案低功耗设备 待实现
78
- const [isLowPowerDevice, setIsLowPowerDevice] = useState(false);
81
+ // 是否启用下发唤醒指令定时
82
+ const [enableWakeUpInterval, setEnableWakeUpInterval] = useState(false);
83
+ // 标记进入面板后,设备是否有上报休眠的情况,若有上报休眠, 需在拉流错误时,重新连接
84
+ const [wirelessFlag, setWirelessFlag] = useState(false);
85
+ // 低功耗隐私模式
86
+ const [lowPrivateOutTimeFlag, setLowPrivateOutTimeFlag] = useState(false);
87
+ // 处于隐私模式中,且设备处于未唤醒状态, 需要进行唤醒, 在mqtt中做标记
88
+ const [mqttPrivateFlag, setMqttPrivateFlag] = useState(false);
89
+ // 低功耗开启隐私模式, 唤醒指令下发2秒即使
90
+ const privateLowPowerDeviceTimeOutRef = useRef(null);
91
+ const privateWakeOutTimeRef = useRef(null);
92
+ const privateDeviceWakeNeedPublishTimeRef = useRef(null);
93
+ // connectChangeRef
94
+ useRef(null);
95
+ const [isLowPowerDevice] = useState(awakeStatus !== undefined);
96
+
79
97
  // 自定义计时老低功耗方案设备在线状态, 用于短暂时间报上下线的UI展示兼容 待实现
80
- const [lowPowerDeviceOnlineState, setLowPowerDeviceOnlineState] = useState(true);
98
+ const [lowPowerDeviceOnlineState, setLowPowerDeviceOnlineState] = useState(onlineStatus);
99
+ // 用于记录低功耗设备上报离线,延迟5秒展示,避免因设备频繁上下线 导致显示杂乱
100
+ const lowPowerDeviceOnlineStateTimeRef = useRef(null);
81
101
  // 4G设备是否被冻结, 待实现
82
102
  const [device4GIsFreeze, setDevice4GIsFreeze] = useState(false);
83
103
  // 4G设备冻结原因, 待实现
@@ -123,6 +143,43 @@ const Player = props => {
123
143
  setScreenType(type);
124
144
  }
125
145
  });
146
+ useEffect(() => {
147
+ registerDeviceListListener({
148
+ deviceIdList: [devId],
149
+ success: () => {
150
+ console.log('registerDeviceListListener success');
151
+ },
152
+ fail: error => {
153
+ console.log('registerDeviceListListener fail', error);
154
+ }
155
+ });
156
+ // 监听设备在线变化
157
+ onDeviceOnlineStatusUpdate(res => {
158
+ // 针对低功耗设备需要监听
159
+ console.log(res, 'onDeviceOnlineStatusUpdate=======');
160
+ if (res.deviceId === devId) {
161
+ if (res !== null && res !== void 0 && res.online) {
162
+ lowPowerDeviceOnlineStateTimeRef.current && clearTimeout(lowPowerDeviceOnlineStateTimeRef.current);
163
+ setLowPowerDeviceOnlineState(true);
164
+ }
165
+ if (isLowPowerDevice && !(res !== null && res !== void 0 && res.online)) {
166
+ // 如果设备不在线的情况, 针对低功耗设备,做延迟5秒的判断,部分低功耗设备启动时会有频繁上下线的状态
167
+ lowPowerDeviceOnlineStateTimeRef.current = setTimeout(() => {
168
+ setLowPowerDeviceOnlineState(false);
169
+ }, 5000);
170
+ }
171
+ }
172
+ });
173
+ onDpDataChange(handleDpDataChange);
174
+ }, []);
175
+ usePageEvent('onHide', async () => {
176
+ setPlayState(d => {
177
+ d.loadingState = true;
178
+ });
179
+ // 先停流
180
+ stopPreview();
181
+ // await getCurMute();
182
+ });
126
183
  useMount(() => {
127
184
  onNetworkStatusChange(res => {
128
185
  setPhoneNetworkConnect(res.isConnected);
@@ -133,14 +190,96 @@ const Player = props => {
133
190
  console.log(res);
134
191
  });
135
192
  });
136
- usePageEvent('onHide', async () => {
137
- setPlayState(d => {
138
- d.loadingState = true;
193
+ const handleDpDataChange = useMemoizedFn(res => {
194
+ if (res.deviceId === devId) {
195
+ const dpsInfo = res.dps;
196
+ const arr = Object.keys(dpsInfo);
197
+ if (arr.length === 1) {
198
+ const dpId = +arr[0];
199
+ const dpValue = dpsInfo[arr[0]];
200
+ console.log(privateState, 'privateState');
201
+ // 这里的 149 为固定 dpId, 无需进行根据 code 获取
202
+ if (dpId === 149 && !dpValue && !privateState) {
203
+ // 进入到面板中,低功耗产品上报休眠, 进行标记
204
+ setWirelessFlag(true);
205
+ }
206
+ }
207
+ }
208
+ });
209
+ const handleMqttMessage = useMemoizedFn(event => {
210
+ var _event$messageData;
211
+ if ((event === null || event === void 0 ? void 0 : event.protocol) === 1 && event !== null && event !== void 0 && (_event$messageData = event.messageData) !== null && _event$messageData !== void 0 && _event$messageData.online) {
212
+ // 监听到设备唤醒, 当前为隐私模式时 延迟1s再进行下发,并且标记下发隐私模式时, 看日志有时用到唤醒DP会滞后
213
+ console.log('isLowPowerDevice', isLowPowerDevice);
214
+ console.log('privateState', privateState);
215
+ console.log('mqttPrivateFlag', mqttPrivateFlag);
216
+ if (isLowPowerDevice && privateState && mqttPrivateFlag) {
217
+ privateDeviceWakeNeedPublishTimeRef.current = setTimeout(async () => {
218
+ const sendDpId = await getDpIdByDpCode(devId, 'basic_private');
219
+ // 还原状态
220
+ setMqttPrivateFlag(false);
221
+ if (sendDpId === -1) {
222
+ showToast(Strings.getLang('ipc_player_basic_private_not_exist'));
223
+ } else {
224
+ publishDps({
225
+ deviceId: devId,
226
+ dps: {
227
+ [sendDpId]: false
228
+ },
229
+ mode: 1,
230
+ pipelines: [0, 1, 2, 3, 4, 5, 6],
231
+ options: {},
232
+ success: () => {
233
+ console.log('下发隐私模式成功');
234
+ }
235
+ });
236
+ }
237
+ }, 1000);
238
+ // 清理15秒超时定时器 以及还原超时状态
239
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
240
+ setLowPrivateOutTimeFlag(false);
241
+ }
242
+ }
243
+ });
244
+
245
+ /**
246
+ * 监听mqtt
247
+ */
248
+ useEffect(() => {
249
+ registerMQTTProtocolListener({
250
+ protocol: 1,
251
+ success: () => console.log('registerMQTTProtocolListener success'),
252
+ fail: err => console.log('registerMQTTProtocolListener fail', err)
139
253
  });
140
- // 先停流
141
- stopPreview();
142
- // await getCurMute();
254
+ onMqttMessageReceived(handleMqttMessage);
255
+ return () => {
256
+ offMqttMessageReceived(handleMqttMessage);
257
+ unregisterMQTTProtocolListener({
258
+ protocol: 1,
259
+ success: () => console.log('unRegisterMQTTProtocolListener success'),
260
+ fail: err => console.log('unRegisterMQTTProtocolListener fail', err)
261
+ });
262
+ // 清理延迟下发定时器
263
+ privateDeviceWakeNeedPublishTimeRef.current && clearTimeout(privateDeviceWakeNeedPublishTimeRef.current);
264
+ lowPowerDeviceOnlineStateTimeRef.current && clearTimeout(lowPowerDeviceOnlineStateTimeRef.current);
265
+ };
266
+ }, []);
267
+
268
+ /**
269
+ * 唤醒设备TTT能力
270
+ */
271
+ useWakeUpDevice({
272
+ deviceId: devId,
273
+ enabled: enableWakeUpInterval,
274
+ intervalTime: 300
143
275
  });
276
+ useEffect(() => {
277
+ if (wirelessFlag) {
278
+ // 进入面板后,若监听到设备上报休眠后, 需进行重新连接
279
+ setWirelessFlag(false);
280
+ _reConnect();
281
+ }
282
+ }, [wirelessFlag]);
144
283
  useEffect(() => {
145
284
  onlineStatus && createIpcCtx();
146
285
  return () => {
@@ -206,6 +345,7 @@ const Player = props => {
206
345
  const _reConnect = () => {
207
346
  setPlayState(d => {
208
347
  d.connectState = true;
348
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
209
349
  d.errorMsg = '';
210
350
  d.errorState = false;
211
351
  d.loadingState = true;
@@ -221,6 +361,14 @@ const Player = props => {
221
361
  * 关闭隐私模式,重新拉流
222
362
  */
223
363
  const handleReWakeCamera = async () => {
364
+ setPlayState(d => {
365
+ d.connectState = true;
366
+ d.errorMsg = '';
367
+ d.loadingText = Strings.getLang('ipc_player_private_open_stream');
368
+ d.errorState = false;
369
+ d.loadingState = true;
370
+ });
371
+ setVideoErrCode('');
224
372
  const sendDpId = await getDpIdByDpCode(devId, 'basic_private');
225
373
  if (sendDpId === -1) {
226
374
  showToast(Strings.getLang('ipc_player_basic_private_not_exist'));
@@ -239,10 +387,72 @@ const Player = props => {
239
387
  });
240
388
  }
241
389
  };
390
+
391
+ /**
392
+ *
393
+ * 低功耗设备关闭隐私模式,先判断设备是否唤醒,唤醒后才可下发隐私模式DP
394
+ */
395
+
396
+ const handleReWakeCameraLowPowerDevice = useMemoizedFn(() => {
397
+ setVideoErrCode('');
398
+ setLowPrivateOutTimeFlag(false);
399
+ if (awakeStatus) {
400
+ setPlayState(d => {
401
+ d.connectState = true;
402
+ d.errorMsg = '';
403
+ d.loadingText = Strings.getLang('ipc_player_private_open_stream');
404
+ d.errorState = false;
405
+ d.loadingState = true;
406
+ });
407
+ // 如果值为true, 表示设备为唤醒状态,直接下发隐私模式DP
408
+ handleReWakeCamera();
409
+ } else {
410
+ setPlayState(d => {
411
+ d.connectState = true;
412
+ d.errorMsg = '';
413
+ d.loadingText = Strings.getLang('ipc_player_private_open_low_stream');
414
+ d.errorState = false;
415
+ d.loadingState = true;
416
+ });
417
+ // 如果值为false, 表示设备为睡眠状态,需要唤醒设备
418
+ setMqttPrivateFlag(true);
419
+ setEnableWakeUpInterval(true);
420
+ // 2秒后停止下发唤醒, 防止频繁唤醒, 此时若Mqtt监听到1协议,也会停止下发唤醒
421
+ privateLowPowerDeviceTimeOutRef.current = setTimeout(() => {
422
+ setEnableWakeUpInterval(false);
423
+ // 清除定时器
424
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateLowPowerDeviceTimeOutRef.current);
425
+ }, 2000);
426
+
427
+ // 15 秒后若设备还是未唤醒,未监听到Mqtt消息以及唤醒Dp上报, 则提示报错
428
+ privateWakeOutTimeRef.current = setTimeout(() => {
429
+ // 清除定时器
430
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
431
+ setPlayState(d => {
432
+ d.connectState = false;
433
+ d.errorMsg = Strings.getLang('ipc_player_private_open_low_stream_fail');
434
+ d.errorState = true;
435
+ d.loadingState = false;
436
+ });
437
+ setMqttPrivateFlag(false);
438
+ setLowPrivateOutTimeFlag(true);
439
+ }, 15000);
440
+ }
441
+ });
242
442
  const retry = useCallback(() => {
243
443
  // console.log('retry:', muteRef.current);
244
444
  console.log('重新拉流启动');
445
+ // 任何重试拉流时, 将播放器状态还原为loading状态
446
+ setVideoErrCode('');
447
+ setPlayState(d => {
448
+ d.loadingState = true;
449
+ d.errorState = false;
450
+ d.errorMsg = '';
451
+ });
245
452
  phoneNetworkConnect && onlineStatus && privateState && !isLowPowerDevice && handleReWakeCamera();
453
+
454
+ // 低功耗设备隐私模式需单独处理,先进行下发唤醒, 唤醒后再进行下发DP
455
+ phoneNetworkConnect && onlineStatus && privateState && isLowPowerDevice && handleReWakeCameraLowPowerDevice();
246
456
  phoneNetworkConnect && onlineStatus && !privateState && _retry();
247
457
  }, [isLowPowerDevice, phoneNetworkConnect && playState.connectState, privateState, onlineStatus]);
248
458
 
@@ -256,14 +466,25 @@ const Player = props => {
256
466
  };
257
467
 
258
468
  // 建立连接
259
- const createConnect = async params => {
469
+ const createConnect = useMemoizedFn(async params => {
260
470
  var _ipcCtx$current;
261
471
  // console.log('建立连接前:', devId, Date.now());
472
+ // 若走到连接状态,需清除低功耗15秒超时定时
473
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
474
+ setLowPrivateOutTimeFlag(false);
475
+ // 表示为 149 低功耗设备, 唤醒设备
476
+ if (isLowPowerDevice) {
477
+ // 下发唤醒
478
+ setEnableWakeUpInterval(true);
479
+ }
262
480
  (_ipcCtx$current = ipcCtx.current) === null || _ipcCtx$current === void 0 || _ipcCtx$current.connect({
263
481
  success: () => {
264
482
  ipcTTTOperatorLog("VID: create_p2p_connect_success");
483
+ // 清除唤醒定时器
484
+ setEnableWakeUpInterval(false);
265
485
  setPlayState(d => {
266
486
  d.connectState = true;
487
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
267
488
  d.errorState = false;
268
489
  d.errorMsg = '';
269
490
  });
@@ -272,24 +493,29 @@ const Player = props => {
272
493
  startPreview(params);
273
494
  },
274
495
  fail: () => {
496
+ // 清除唤醒定时器
497
+ setEnableWakeUpInterval(false);
275
498
  ipcTTTOperatorLog("VID: create_p2p_connect_failure");
276
- setPlayState(d => {
277
- d.connectState = false;
278
- d.errorState = true;
279
- d.errorMsg = Strings.getLang('ipc_player_connect_fail');
280
- d.loadingState = false;
281
- });
282
- onChangeStreamStatus && onChangeStreamStatus(-1001);
499
+ // 针对进入面板上报149状态的为true的设备直接忽略
500
+ if (!wirelessFlag) {
501
+ setPlayState(d => {
502
+ d.connectState = false;
503
+ d.errorState = true;
504
+ d.errorMsg = Strings.getLang('ipc_player_connect_fail');
505
+ d.loadingState = false;
506
+ });
507
+ onChangeStreamStatus && onChangeStreamStatus(-1001);
508
+ }
283
509
  }
284
510
  });
285
- };
511
+ });
286
512
 
287
513
  // 视图层准备就绪,开始建立连接
288
514
 
289
515
  /*
290
516
  * 开启预览
291
517
  */
292
- const startPreview = params => {
518
+ const startPreview = useMemoizedFn(params => {
293
519
  var _ipcCtx$current2;
294
520
  // console.log('开启预览前');
295
521
  (_ipcCtx$current2 = ipcCtx.current) === null || _ipcCtx$current2 === void 0 || _ipcCtx$current2.startPreview({
@@ -321,15 +547,18 @@ const Player = props => {
321
547
  onChangeStreamStatus && onChangeStreamStatus(1002);
322
548
  return;
323
549
  }
324
- setPlayState(d => {
325
- d.errorState = true;
326
- d.loadingState = false;
327
- d.errorMsg = Strings.getLang('ipc_player_preview_fail');
328
- });
329
- onChangeStreamStatus && onChangeStreamStatus(-1002);
550
+ // 针对进入到面板,接收到上报为设备休眠的情况直接忽略
551
+ if (!wirelessFlag) {
552
+ setPlayState(d => {
553
+ d.errorState = true;
554
+ d.loadingState = false;
555
+ d.errorMsg = Strings.getLang('ipc_player_preview_fail');
556
+ });
557
+ onChangeStreamStatus && onChangeStreamStatus(-1002);
558
+ }
330
559
  }
331
560
  });
332
- };
561
+ });
333
562
 
334
563
  /**
335
564
  * 暂停预览
@@ -393,6 +622,45 @@ const Player = props => {
393
622
  }, [playState.errorState]);
394
623
 
395
624
  // 连接状态发生变化
625
+ const connectChange = useMemoizedFn(e => {
626
+ var _e$detail;
627
+ ipcTTTOperatorLog("VID: player_event_connect_change: ".concat(JSON.stringify(e)));
628
+ console.log('连接状态发生变化', e);
629
+ const code = e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.state;
630
+ onChangeStreamStatus && onChangeStreamStatus(code === 0 ? 1001 : -1001);
631
+ if (code === 0) {
632
+ setPlayState(d => {
633
+ d.connectState = true;
634
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
635
+ });
636
+ } else if ((code === -3 || code === -105) && retryCount.current < 1) {
637
+ // 连接超时或鉴权失败重试一次
638
+ retryCount.current++;
639
+ retry();
640
+ } else {
641
+ if (privateState) {
642
+ return;
643
+ }
644
+ setPlayState(d => {
645
+ d.connectState = false;
646
+ d.loadingState = false;
647
+ d.errorState = true;
648
+ d.errorMsg = "".concat(Strings.getLang(IpcFailCode[-1001]), "(").concat(code, ")");
649
+ });
650
+ // 安卓隐私模式切换时,会触发此回调,错误码为-108, 此时拿不到最新更新过来的隐私模式状态,延迟1秒对其进行判断
651
+ // connectChangeTimeRef.current = setTimeout(() => {
652
+ // // if (privateState) {
653
+ // // return false;
654
+ // // }
655
+ // setPlayState(d => {
656
+ // d.connectState = false;
657
+ // d.loadingState = false;
658
+ // d.errorState = true;
659
+ // d.errorMsg = `${Strings.getLang(IpcFailCode[-1001])}(${code})`;
660
+ // });
661
+ // }, 1000);
662
+ }
663
+ });
396
664
 
397
665
  // 断开连接
398
666
  const disconnect = () => {
@@ -437,6 +705,30 @@ const Player = props => {
437
705
  * 退出横屏
438
706
  */
439
707
 
708
+ const handleCameraPreviewFailure = useMemoizedFn(data => {
709
+ console.log(data, 'data======');
710
+ ipcTTTOperatorLog("cameraPreviewFailure_event_trigger_".concat(JSON.stringify(data)));
711
+ if (data.type === 'cameraPreviewFailure' && !privateState) {
712
+ // 隐私模式时不展示错误
713
+ const {
714
+ deviceId,
715
+ errCode,
716
+ errorCode
717
+ } = data === null || data === void 0 ? void 0 : data.detail;
718
+ const codeValue = errCode || errorCode;
719
+ if (deviceId) {
720
+ if (deviceId === devId) {
721
+ setVideoErrCode(codeValue);
722
+ props.onCameraPreviewFailure && onCameraPreviewFailure(codeValue);
723
+ }
724
+ } else {
725
+ // 兼容匹配安卓 6.8.0 修复错误码不带 deviceId 和 errorCode 修正 为errCode的问题
726
+ setVideoErrCode(codeValue);
727
+ props.onCameraPreviewFailure && onCameraPreviewFailure(codeValue);
728
+ }
729
+ }
730
+ });
731
+
440
732
  /**
441
733
  * 获取错误展示内容
442
734
  */
@@ -450,9 +742,15 @@ const Player = props => {
450
742
  if (!isLowPowerDevice && onlineStatus && privateState) {
451
743
  return Strings.getLang('ipc_player_device_sleep');
452
744
  }
453
- if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState) {
745
+
746
+ // 低功耗隐私模式正常唤醒
747
+ if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState && !lowPrivateOutTimeFlag) {
454
748
  return Strings.getLang('ipc_player_device_sleep');
455
749
  }
750
+ // 低功耗隐私模式正常唤醒,下发指令失败
751
+ if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState && !lowPrivateOutTimeFlag) {
752
+ return Strings.getLang('ipc_player_private_open_low_stream_fail');
753
+ }
456
754
  if (!isLowPowerDevice && device4GIsFreeze && onlineStatus && !privateState) {
457
755
  return deviceFreezeReasonStore[deviceFreezeReason];
458
756
  }
@@ -471,13 +769,14 @@ const Player = props => {
471
769
  return Strings.getLang('ipc_player_no_line');
472
770
  }
473
771
  if (videoErrCode !== '') {
772
+ console.log(Strings["ipc_player_error_".concat(codeCoverToInt(videoErrCode))], '多语言');
474
773
  if (Strings["ipc_player_error_".concat(codeCoverToInt(videoErrCode))]) {
475
774
  return "".concat(Strings.getLang("ipc_player_error_".concat(codeCoverToInt(videoErrCode))), "(").concat(videoErrCode, ")");
476
775
  }
477
776
  return "".concat(Strings.getLang("ipc_player_error_common"), "(").concat(videoErrCode, ")");
478
777
  }
479
778
  return playState.errorMsg;
480
- }, [phoneNetworkConnect, playState, videoErrCode, privateState, onlineStatus, isLowPowerDevice, lowPowerDeviceOnlineState, device4GIsFreeze, deviceFreezeReason]);
779
+ }, [phoneNetworkConnect, playState, videoErrCode, privateState, onlineStatus, isLowPowerDevice, lowPowerDeviceOnlineState, device4GIsFreeze, deviceFreezeReason, lowPrivateOutTimeFlag]);
481
780
 
482
781
  /**
483
782
  * 根据自定义类型获取错误码展示内容
@@ -494,12 +793,14 @@ const Player = props => {
494
793
  return errContent.suggestedText !== '';
495
794
  // 建议文案
496
795
  case 'suggestedText':
497
- if (contentEmpty) {
796
+ if (contentEmpty || privateState) {
498
797
  return '';
499
798
  }
500
799
  return errContent.suggestedText;
501
800
  // 是否展示点我重试
502
801
  case 'retry':
802
+ console.log(privateState, 'privateState========');
803
+ console.log(privateState, 'privateState========');
503
804
  if (!phoneNetworkConnect) {
504
805
  return false;
505
806
  }
@@ -559,7 +860,7 @@ const Player = props => {
559
860
  if (!phoneNetworkConnect) {
560
861
  return true;
561
862
  }
562
- if (privateState && isShare) {
863
+ if (privateState) {
563
864
  return false;
564
865
  }
565
866
  if (contentEmpty) {
@@ -604,19 +905,7 @@ const Player = props => {
604
905
  objectFit: objectFit,
605
906
  onVideoTap: handleVideoTap,
606
907
  onZoomChange: onZoomChange,
607
- onCameraPreviewFailure: data => {
608
- ipcTTTOperatorLog("cameraPreviewFailure_event_trigger_".concat(JSON.stringify(data)));
609
- if (data.type === 'cameraPreviewFailure') {
610
- const {
611
- deviceId,
612
- errCode
613
- } = data === null || data === void 0 ? void 0 : data.detail;
614
- if (deviceId === devId) {
615
- setVideoErrCode(errCode);
616
- props.onCameraPreviewFailure && onCameraPreviewFailure(errCode);
617
- }
618
- }
619
- },
908
+ onCameraPreviewFailure: handleCameraPreviewFailure,
620
909
  onCameraNotifyWeakNetwork: onCameraNotifyWeakNetwork,
621
910
  onInitDone: () => {
622
911
  console.log('视图层准备就绪~');
@@ -627,29 +916,7 @@ const Player = props => {
627
916
  });
628
917
  },
629
918
  onError: onError,
630
- onConnectChange: e => {
631
- var _e$detail;
632
- ipcTTTOperatorLog("VID: player_event_connect_change: ".concat(JSON.stringify(e)));
633
- console.log('连接状态发生变化', e);
634
- const code = e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.state;
635
- onChangeStreamStatus && onChangeStreamStatus(code === 0 ? 1001 : -1001);
636
- if (code === 0) {
637
- setPlayState(d => {
638
- d.connectState = true;
639
- });
640
- } else if ((code === -3 || code === -105) && retryCount.current < 1) {
641
- // 连接超时或鉴权失败重试一次
642
- retryCount.current++;
643
- retry();
644
- } else {
645
- setPlayState(d => {
646
- d.connectState = false;
647
- d.loadingState = false;
648
- d.errorState = true;
649
- d.errorMsg = Strings.getLang(IpcFailCode[-1001]);
650
- });
651
- }
652
- },
919
+ onConnectChange: connectChange,
653
920
  deviceId: devId,
654
921
  autoPauseIfNavigate: false,
655
922
  autoPauseIfOpenNative: false,
@@ -676,7 +943,7 @@ const Player = props => {
676
943
  className: Styles.load_icon
677
944
  }), /*#__PURE__*/React.createElement(View, {
678
945
  className: Styles.load_des
679
- }, loadText || Strings.getLang('ipc_player_get_video_stream'))), /*#__PURE__*/React.createElement(CoverView, {
946
+ }, loadText || playState.loadingText || Strings.getLang('ipc_player_get_video_stream'))), /*#__PURE__*/React.createElement(CoverView, {
680
947
  style: {
681
948
  borderRadius: "".concat(borderRadius)
682
949
  },
@@ -126,4 +126,10 @@ export type IProps = {
126
126
  * @default {}
127
127
  */
128
128
  reConnect?: boolean;
129
+ /**
130
+ * @description.en needReconnect
131
+ * @description.zh 是否需要唤醒
132
+ * @default {}
133
+ */
134
+ awakeStatus?: boolean | undefined;
129
135
  };
package/lib/utils.d.ts CHANGED
@@ -40,3 +40,7 @@ export declare const getDpIdByDpCode: (devId: string, code: string) => Promise<n
40
40
  * TTT能力写入App日志
41
41
  */
42
42
  export declare const ipcTTTOperatorLog: (ipcLogString: string) => void;
43
+ /**
44
+ * TTT 能力唤醒设备
45
+ */
46
+ export declare const wakeUpDevice: (deviceId: string) => void;
package/lib/utils.js CHANGED
@@ -152,4 +152,20 @@ export const ipcTTTOperatorLog = ipcLogString => {
152
152
  } catch (err) {
153
153
  console.log('ipcTTTOperatorLog error', err);
154
154
  }
155
+ };
156
+ /**
157
+ * TTT 能力唤醒设备
158
+ */
159
+ export const wakeUpDevice = deviceId => {
160
+ ipcTTTOperatorLog('start publish wakeUpDevice');
161
+ ty.device.wakeUpDevice({
162
+ deviceId,
163
+ dps: {},
164
+ success: () => {
165
+ ipcTTTOperatorLog('publish wakeUpDevice success');
166
+ },
167
+ fail: () => {
168
+ ipcTTTOperatorLog('publish wakeUpDevice fail');
169
+ }
170
+ });
155
171
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ray-ipc-player",
3
- "version": "2.0.20",
3
+ "version": "2.0.21-beta-2",
4
4
  "description": "ray小程序播放器",
5
5
  "keywords": [
6
6
  "tuya-miniapp",
@@ -44,8 +44,8 @@
44
44
  "devDependencies": {
45
45
  "@commitlint/cli": "^7.2.1",
46
46
  "@commitlint/config-conventional": "^9.0.1",
47
- "@ray-js/cli": "^1.4.9",
48
- "@ray-js/ray": "^1.4.9",
47
+ "@ray-js/cli": "^1.7.14",
48
+ "@ray-js/ray": "^1.7.14",
49
49
  "@testing-library/react-hooks": "^8.0.1",
50
50
  "@types/jest": "^29.5.14",
51
51
  "core-js": "^3.19.1",