@ray-js/ray-ipc-player 2.0.20-beta-17 → 2.0.21-beta-1

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,57 @@ 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(res => {
174
+ if (res.deviceId === devId) {
175
+ const dpsInfo = res.dps;
176
+ const arr = Object.keys(dpsInfo);
177
+ if (arr.length === 1) {
178
+ const dpId = +arr[0];
179
+ const dpValue = dpsInfo[arr[0]];
180
+ // 这里的 149 为固定 dpId, 无需进行根据 code 获取
181
+ if (dpId === 149 && !dpValue) {
182
+ // 进入到面板中,低功耗产品上报休眠, 进行标记
183
+ setWirelessFlag(true);
184
+ }
185
+ }
186
+ }
187
+ });
188
+ }, []);
189
+ usePageEvent('onHide', async () => {
190
+ setPlayState(d => {
191
+ d.loadingState = true;
192
+ });
193
+ // 先停流
194
+ stopPreview();
195
+ // await getCurMute();
196
+ });
126
197
  useMount(() => {
127
198
  onNetworkStatusChange(res => {
128
199
  setPhoneNetworkConnect(res.isConnected);
@@ -133,14 +204,80 @@ const Player = props => {
133
204
  console.log(res);
134
205
  });
135
206
  });
136
- usePageEvent('onHide', async () => {
137
- setPlayState(d => {
138
- d.loadingState = true;
207
+ const handleMqttMessage = useMemoizedFn(event => {
208
+ var _event$messageData;
209
+ 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) {
210
+ // 监听到设备唤醒, 当前为隐私模式时 延迟1s再进行下发,并且标记下发隐私模式时, 看日志有时用到唤醒DP会滞后
211
+ console.log('isLowPowerDevice', isLowPowerDevice);
212
+ console.log('privateState', privateState);
213
+ console.log('mqttPrivateFlag', mqttPrivateFlag);
214
+ if (isLowPowerDevice && privateState && mqttPrivateFlag) {
215
+ privateDeviceWakeNeedPublishTimeRef.current = setTimeout(async () => {
216
+ const sendDpId = await getDpIdByDpCode(devId, 'basic_private');
217
+ // 还原状态
218
+ setMqttPrivateFlag(false);
219
+ if (sendDpId === -1) {
220
+ showToast(Strings.getLang('ipc_player_basic_private_not_exist'));
221
+ } else {
222
+ publishDps({
223
+ deviceId: devId,
224
+ dps: {
225
+ [sendDpId]: false
226
+ },
227
+ mode: 1,
228
+ pipelines: [0, 1, 2, 3, 4, 5, 6],
229
+ options: {},
230
+ success: () => {
231
+ console.log('下发隐私模式成功');
232
+ }
233
+ });
234
+ }
235
+ }, 1000);
236
+ // 清理15秒超时定时器 以及还原超时状态
237
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
238
+ setLowPrivateOutTimeFlag(false);
239
+ }
240
+ }
241
+ });
242
+
243
+ /**
244
+ * 监听mqtt
245
+ */
246
+ useEffect(() => {
247
+ registerMQTTProtocolListener({
248
+ protocol: 1,
249
+ success: () => console.log('registerMQTTProtocolListener success'),
250
+ fail: err => console.log('registerMQTTProtocolListener fail', err)
139
251
  });
140
- // 先停流
141
- stopPreview();
142
- // await getCurMute();
252
+ onMqttMessageReceived(handleMqttMessage);
253
+ return () => {
254
+ offMqttMessageReceived(handleMqttMessage);
255
+ unregisterMQTTProtocolListener({
256
+ protocol: 1,
257
+ success: () => console.log('unRegisterMQTTProtocolListener success'),
258
+ fail: err => console.log('unRegisterMQTTProtocolListener fail', err)
259
+ });
260
+ // 清理延迟下发定时器
261
+ privateDeviceWakeNeedPublishTimeRef.current && clearTimeout(privateDeviceWakeNeedPublishTimeRef.current);
262
+ lowPowerDeviceOnlineStateTimeRef.current && clearTimeout(lowPowerDeviceOnlineStateTimeRef.current);
263
+ };
264
+ }, []);
265
+
266
+ /**
267
+ * 唤醒设备TTT能力
268
+ */
269
+ useWakeUpDevice({
270
+ deviceId: devId,
271
+ enabled: enableWakeUpInterval,
272
+ intervalTime: 300
143
273
  });
274
+ useEffect(() => {
275
+ if (wirelessFlag) {
276
+ // 进入面板后,若监听到设备上报休眠后, 需进行重新连接
277
+ setWirelessFlag(false);
278
+ _reConnect();
279
+ }
280
+ }, [wirelessFlag]);
144
281
  useEffect(() => {
145
282
  onlineStatus && createIpcCtx();
146
283
  return () => {
@@ -206,6 +343,7 @@ const Player = props => {
206
343
  const _reConnect = () => {
207
344
  setPlayState(d => {
208
345
  d.connectState = true;
346
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
209
347
  d.errorMsg = '';
210
348
  d.errorState = false;
211
349
  d.loadingState = true;
@@ -221,6 +359,14 @@ const Player = props => {
221
359
  * 关闭隐私模式,重新拉流
222
360
  */
223
361
  const handleReWakeCamera = async () => {
362
+ setPlayState(d => {
363
+ d.connectState = true;
364
+ d.errorMsg = '';
365
+ d.loadingText = Strings.getLang('ipc_player_private_open_stream');
366
+ d.errorState = false;
367
+ d.loadingState = true;
368
+ });
369
+ setVideoErrCode('');
224
370
  const sendDpId = await getDpIdByDpCode(devId, 'basic_private');
225
371
  if (sendDpId === -1) {
226
372
  showToast(Strings.getLang('ipc_player_basic_private_not_exist'));
@@ -239,10 +385,72 @@ const Player = props => {
239
385
  });
240
386
  }
241
387
  };
388
+
389
+ /**
390
+ *
391
+ * 低功耗设备关闭隐私模式,先判断设备是否唤醒,唤醒后才可下发隐私模式DP
392
+ */
393
+
394
+ const handleReWakeCameraLowPowerDevice = useMemoizedFn(() => {
395
+ setVideoErrCode('');
396
+ setLowPrivateOutTimeFlag(false);
397
+ if (awakeStatus) {
398
+ setPlayState(d => {
399
+ d.connectState = true;
400
+ d.errorMsg = '';
401
+ d.loadingText = Strings.getLang('ipc_player_private_open_stream');
402
+ d.errorState = false;
403
+ d.loadingState = true;
404
+ });
405
+ // 如果值为true, 表示设备为唤醒状态,直接下发隐私模式DP
406
+ handleReWakeCamera();
407
+ } else {
408
+ setPlayState(d => {
409
+ d.connectState = true;
410
+ d.errorMsg = '';
411
+ d.loadingText = Strings.getLang('ipc_player_private_open_low_stream');
412
+ d.errorState = false;
413
+ d.loadingState = true;
414
+ });
415
+ // 如果值为false, 表示设备为睡眠状态,需要唤醒设备
416
+ setMqttPrivateFlag(true);
417
+ setEnableWakeUpInterval(true);
418
+ // 2秒后停止下发唤醒, 防止频繁唤醒, 此时若Mqtt监听到1协议,也会停止下发唤醒
419
+ privateLowPowerDeviceTimeOutRef.current = setTimeout(() => {
420
+ setEnableWakeUpInterval(false);
421
+ // 清除定时器
422
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateLowPowerDeviceTimeOutRef.current);
423
+ }, 2000);
424
+
425
+ // 15 秒后若设备还是未唤醒,未监听到Mqtt消息以及唤醒Dp上报, 则提示报错
426
+ privateWakeOutTimeRef.current = setTimeout(() => {
427
+ // 清除定时器
428
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
429
+ setPlayState(d => {
430
+ d.connectState = false;
431
+ d.errorMsg = Strings.getLang('ipc_player_private_open_low_stream_fail');
432
+ d.errorState = true;
433
+ d.loadingState = false;
434
+ });
435
+ setMqttPrivateFlag(false);
436
+ setLowPrivateOutTimeFlag(true);
437
+ }, 15000);
438
+ }
439
+ });
242
440
  const retry = useCallback(() => {
243
441
  // console.log('retry:', muteRef.current);
244
442
  console.log('重新拉流启动');
443
+ // 任何重试拉流时, 将播放器状态还原为loading状态
444
+ setVideoErrCode('');
445
+ setPlayState(d => {
446
+ d.loadingState = true;
447
+ d.errorState = false;
448
+ d.errorMsg = '';
449
+ });
245
450
  phoneNetworkConnect && onlineStatus && privateState && !isLowPowerDevice && handleReWakeCamera();
451
+
452
+ // 低功耗设备隐私模式需单独处理,先进行下发唤醒, 唤醒后再进行下发DP
453
+ phoneNetworkConnect && onlineStatus && privateState && isLowPowerDevice && handleReWakeCameraLowPowerDevice();
246
454
  phoneNetworkConnect && onlineStatus && !privateState && _retry();
247
455
  }, [isLowPowerDevice, phoneNetworkConnect && playState.connectState, privateState, onlineStatus]);
248
456
 
@@ -256,14 +464,25 @@ const Player = props => {
256
464
  };
257
465
 
258
466
  // 建立连接
259
- const createConnect = async params => {
467
+ const createConnect = useMemoizedFn(async params => {
260
468
  var _ipcCtx$current;
261
469
  // console.log('建立连接前:', devId, Date.now());
470
+ // 若走到连接状态,需清除低功耗15秒超时定时
471
+ privateLowPowerDeviceTimeOutRef.current && clearTimeout(privateWakeOutTimeRef.current);
472
+ setLowPrivateOutTimeFlag(false);
473
+ // 表示为 149 低功耗设备, 唤醒设备
474
+ if (isLowPowerDevice) {
475
+ // 下发唤醒
476
+ setEnableWakeUpInterval(true);
477
+ }
262
478
  (_ipcCtx$current = ipcCtx.current) === null || _ipcCtx$current === void 0 || _ipcCtx$current.connect({
263
479
  success: () => {
264
480
  ipcTTTOperatorLog("VID: create_p2p_connect_success");
481
+ // 清除唤醒定时器
482
+ setEnableWakeUpInterval(false);
265
483
  setPlayState(d => {
266
484
  d.connectState = true;
485
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
267
486
  d.errorState = false;
268
487
  d.errorMsg = '';
269
488
  });
@@ -272,24 +491,29 @@ const Player = props => {
272
491
  startPreview(params);
273
492
  },
274
493
  fail: () => {
494
+ // 清除唤醒定时器
495
+ setEnableWakeUpInterval(false);
275
496
  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);
497
+ // 针对进入面板上报149状态的为true的设备直接忽略
498
+ if (!wirelessFlag) {
499
+ setPlayState(d => {
500
+ d.connectState = false;
501
+ d.errorState = true;
502
+ d.errorMsg = Strings.getLang('ipc_player_connect_fail');
503
+ d.loadingState = false;
504
+ });
505
+ onChangeStreamStatus && onChangeStreamStatus(-1001);
506
+ }
283
507
  }
284
508
  });
285
- };
509
+ });
286
510
 
287
511
  // 视图层准备就绪,开始建立连接
288
512
 
289
513
  /*
290
514
  * 开启预览
291
515
  */
292
- const startPreview = params => {
516
+ const startPreview = useMemoizedFn(params => {
293
517
  var _ipcCtx$current2;
294
518
  // console.log('开启预览前');
295
519
  (_ipcCtx$current2 = ipcCtx.current) === null || _ipcCtx$current2 === void 0 || _ipcCtx$current2.startPreview({
@@ -321,15 +545,18 @@ const Player = props => {
321
545
  onChangeStreamStatus && onChangeStreamStatus(1002);
322
546
  return;
323
547
  }
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);
548
+ // 针对进入到面板,接收到上报为设备休眠的情况直接忽略
549
+ if (!wirelessFlag) {
550
+ setPlayState(d => {
551
+ d.errorState = true;
552
+ d.loadingState = false;
553
+ d.errorMsg = Strings.getLang('ipc_player_preview_fail');
554
+ });
555
+ onChangeStreamStatus && onChangeStreamStatus(-1002);
556
+ }
330
557
  }
331
558
  });
332
- };
559
+ });
333
560
 
334
561
  /**
335
562
  * 暂停预览
@@ -393,6 +620,45 @@ const Player = props => {
393
620
  }, [playState.errorState]);
394
621
 
395
622
  // 连接状态发生变化
623
+ const connectChange = useMemoizedFn(e => {
624
+ var _e$detail;
625
+ ipcTTTOperatorLog("VID: player_event_connect_change: ".concat(JSON.stringify(e)));
626
+ console.log('连接状态发生变化', e);
627
+ const code = e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.state;
628
+ onChangeStreamStatus && onChangeStreamStatus(code === 0 ? 1001 : -1001);
629
+ if (code === 0) {
630
+ setPlayState(d => {
631
+ d.connectState = true;
632
+ d.loadingText = Strings.getLang('ipc_player_get_video_stream');
633
+ });
634
+ } else if ((code === -3 || code === -105) && retryCount.current < 1) {
635
+ // 连接超时或鉴权失败重试一次
636
+ retryCount.current++;
637
+ retry();
638
+ } else {
639
+ if (privateState) {
640
+ return;
641
+ }
642
+ setPlayState(d => {
643
+ d.connectState = false;
644
+ d.loadingState = false;
645
+ d.errorState = true;
646
+ d.errorMsg = "".concat(Strings.getLang(IpcFailCode[-1001]), "(").concat(code, ")");
647
+ });
648
+ // 安卓隐私模式切换时,会触发此回调,错误码为-108, 此时拿不到最新更新过来的隐私模式状态,延迟1秒对其进行判断
649
+ // connectChangeTimeRef.current = setTimeout(() => {
650
+ // // if (privateState) {
651
+ // // return false;
652
+ // // }
653
+ // setPlayState(d => {
654
+ // d.connectState = false;
655
+ // d.loadingState = false;
656
+ // d.errorState = true;
657
+ // d.errorMsg = `${Strings.getLang(IpcFailCode[-1001])}(${code})`;
658
+ // });
659
+ // }, 1000);
660
+ }
661
+ });
396
662
 
397
663
  // 断开连接
398
664
  const disconnect = () => {
@@ -437,6 +703,30 @@ const Player = props => {
437
703
  * 退出横屏
438
704
  */
439
705
 
706
+ const handleCameraPreviewFailure = useMemoizedFn(data => {
707
+ console.log(data, 'data======');
708
+ ipcTTTOperatorLog("cameraPreviewFailure_event_trigger_".concat(JSON.stringify(data)));
709
+ if (data.type === 'cameraPreviewFailure' && !privateState) {
710
+ // 隐私模式时不展示错误
711
+ const {
712
+ deviceId,
713
+ errCode,
714
+ errorCode
715
+ } = data === null || data === void 0 ? void 0 : data.detail;
716
+ const codeValue = errCode || errorCode;
717
+ if (deviceId) {
718
+ if (deviceId === devId) {
719
+ setVideoErrCode(codeValue);
720
+ props.onCameraPreviewFailure && onCameraPreviewFailure(codeValue);
721
+ }
722
+ } else {
723
+ // 兼容匹配安卓 6.8.0 修复错误码不带 deviceId 和 errorCode 修正 为errCode的问题
724
+ setVideoErrCode(codeValue);
725
+ props.onCameraPreviewFailure && onCameraPreviewFailure(codeValue);
726
+ }
727
+ }
728
+ });
729
+
440
730
  /**
441
731
  * 获取错误展示内容
442
732
  */
@@ -450,9 +740,15 @@ const Player = props => {
450
740
  if (!isLowPowerDevice && onlineStatus && privateState) {
451
741
  return Strings.getLang('ipc_player_device_sleep');
452
742
  }
453
- if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState) {
743
+
744
+ // 低功耗隐私模式正常唤醒
745
+ if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState && !lowPrivateOutTimeFlag) {
454
746
  return Strings.getLang('ipc_player_device_sleep');
455
747
  }
748
+ // 低功耗隐私模式正常唤醒,下发指令失败
749
+ if (isLowPowerDevice && lowPowerDeviceOnlineState && privateState && !lowPrivateOutTimeFlag) {
750
+ return Strings.getLang('ipc_player_private_open_low_stream_fail');
751
+ }
456
752
  if (!isLowPowerDevice && device4GIsFreeze && onlineStatus && !privateState) {
457
753
  return deviceFreezeReasonStore[deviceFreezeReason];
458
754
  }
@@ -471,13 +767,14 @@ const Player = props => {
471
767
  return Strings.getLang('ipc_player_no_line');
472
768
  }
473
769
  if (videoErrCode !== '') {
770
+ console.log(Strings["ipc_player_error_".concat(codeCoverToInt(videoErrCode))], '多语言');
474
771
  if (Strings["ipc_player_error_".concat(codeCoverToInt(videoErrCode))]) {
475
772
  return "".concat(Strings.getLang("ipc_player_error_".concat(codeCoverToInt(videoErrCode))), "(").concat(videoErrCode, ")");
476
773
  }
477
774
  return "".concat(Strings.getLang("ipc_player_error_common"), "(").concat(videoErrCode, ")");
478
775
  }
479
776
  return playState.errorMsg;
480
- }, [phoneNetworkConnect, playState, videoErrCode, privateState, onlineStatus, isLowPowerDevice, lowPowerDeviceOnlineState, device4GIsFreeze, deviceFreezeReason]);
777
+ }, [phoneNetworkConnect, playState, videoErrCode, privateState, onlineStatus, isLowPowerDevice, lowPowerDeviceOnlineState, device4GIsFreeze, deviceFreezeReason, lowPrivateOutTimeFlag]);
481
778
 
482
779
  /**
483
780
  * 根据自定义类型获取错误码展示内容
@@ -494,12 +791,14 @@ const Player = props => {
494
791
  return errContent.suggestedText !== '';
495
792
  // 建议文案
496
793
  case 'suggestedText':
497
- if (contentEmpty) {
794
+ if (contentEmpty || privateState) {
498
795
  return '';
499
796
  }
500
797
  return errContent.suggestedText;
501
798
  // 是否展示点我重试
502
799
  case 'retry':
800
+ console.log(privateState, 'privateState========');
801
+ console.log(privateState, 'privateState========');
503
802
  if (!phoneNetworkConnect) {
504
803
  return false;
505
804
  }
@@ -559,7 +858,7 @@ const Player = props => {
559
858
  if (!phoneNetworkConnect) {
560
859
  return true;
561
860
  }
562
- if (privateState && isShare) {
861
+ if (privateState) {
563
862
  return false;
564
863
  }
565
864
  if (contentEmpty) {
@@ -604,19 +903,7 @@ const Player = props => {
604
903
  objectFit: objectFit,
605
904
  onVideoTap: handleVideoTap,
606
905
  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
- },
906
+ onCameraPreviewFailure: handleCameraPreviewFailure,
620
907
  onCameraNotifyWeakNetwork: onCameraNotifyWeakNetwork,
621
908
  onInitDone: () => {
622
909
  console.log('视图层准备就绪~');
@@ -627,29 +914,7 @@ const Player = props => {
627
914
  });
628
915
  },
629
916
  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
- },
917
+ onConnectChange: connectChange,
653
918
  deviceId: devId,
654
919
  autoPauseIfNavigate: false,
655
920
  autoPauseIfOpenNative: false,
@@ -676,7 +941,7 @@ const Player = props => {
676
941
  className: Styles.load_icon
677
942
  }), /*#__PURE__*/React.createElement(View, {
678
943
  className: Styles.load_des
679
- }, loadText || Strings.getLang('ipc_player_get_video_stream'))), /*#__PURE__*/React.createElement(CoverView, {
944
+ }, loadText || playState.loadingText || Strings.getLang('ipc_player_get_video_stream'))), /*#__PURE__*/React.createElement(CoverView, {
680
945
  style: {
681
946
  borderRadius: "".concat(borderRadius)
682
947
  },
@@ -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-beta-17",
3
+ "version": "2.0.21-beta-1",
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",