@ray-js/ipc-player-integration 0.0.53-beta.1 → 0.0.53-beta.11
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/ctx/ctx.autoClarity.test.d.ts +1 -0
- package/lib/ctx/ctx.autoClarity.test.js +150 -0
- package/lib/ctx/ctx.js +75 -6
- package/lib/i18n/index.d.ts +16 -0
- package/lib/i18n/strings.d.ts +8 -0
- package/lib/i18n/strings.js +8 -0
- package/lib/interface.d.ts +3 -6
- package/lib/ui/constant.d.ts +0 -6
- package/lib/ui/constant.js +0 -7
- package/lib/ui/ui.js +47 -4
- package/lib/utils/captureResult.d.ts +6 -1
- package/lib/utils/captureResult.js +15 -13
- package/lib/utils/captureResult.test.js +42 -15
- package/lib/utils/ttt.autoClarity.test.d.ts +1 -0
- package/lib/utils/ttt.autoClarity.test.js +75 -0
- package/lib/utils/ttt.d.ts +16 -2
- package/lib/utils/ttt.js +78 -25
- package/lib/widgets/captureResult/captureResult.js +6 -10
- package/lib/widgets/captureResult/captureResult.less +59 -14
- package/lib/widgets/captureResult/captureResult.test.d.ts +1 -0
- package/lib/widgets/captureResult/captureResult.test.js +80 -0
- package/lib/widgets/recordVideo/recordVideo.js +5 -1
- package/lib/widgets/resolution/resolution.js +2 -29
- package/lib/widgets/screenshot/screenshot.js +5 -1
- package/lib/widgets/videoBitKBP/videoBitKBP.js +40 -38
- package/lib/widgets/videoBitKBP/videoBitKBP.less +17 -11
- package/lib/widgets/videoBitKBP/videoBitKBP.test.d.ts +1 -0
- package/lib/widgets/videoBitKBP/videoBitKBP.test.js +156 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import { act, renderHook } from '@testing-library/react-hooks';
|
|
3
|
+
import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
|
|
4
|
+
import { createUseCtx } from './ctx';
|
|
5
|
+
import { useStore } from './store';
|
|
6
|
+
import { PlayState } from '../interface';
|
|
7
|
+
import { getCachedAutoClarity, setCachedAutoClarity, subscribeClarityChanged } from '../utils/ttt';
|
|
8
|
+
jest.mock('@ray-js/ray', () => ({}));
|
|
9
|
+
jest.mock('@ray-js/ray-ipc-utils/lib/interface', () => ({
|
|
10
|
+
ClarityType: {
|
|
11
|
+
SS: 'SS',
|
|
12
|
+
SD: 'SD',
|
|
13
|
+
HD: 'HD',
|
|
14
|
+
UD: 'UD',
|
|
15
|
+
SSP: 'SSP',
|
|
16
|
+
AUTO: 'AUTO',
|
|
17
|
+
AUDIO: 'AUDIO'
|
|
18
|
+
},
|
|
19
|
+
IntercomMode: {
|
|
20
|
+
OneWay: 'OneWay',
|
|
21
|
+
TwoWay: 'TwoWay'
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
jest.mock('../i18n', () => ({
|
|
25
|
+
__esModule: true,
|
|
26
|
+
default: {
|
|
27
|
+
getLang: key => key
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
jest.mock('./multiCameraCtx', () => ({
|
|
31
|
+
isMultiCameraTileSupported: () => false,
|
|
32
|
+
useMultiCameraCtx: () => ({})
|
|
33
|
+
}));
|
|
34
|
+
jest.mock('../utils/ttt', () => ({
|
|
35
|
+
getCachedAutoClarity: jest.fn(),
|
|
36
|
+
isClarityChangedSupported: () => true,
|
|
37
|
+
setCachedAutoClarity: jest.fn(),
|
|
38
|
+
subscribeClarityChanged: jest.fn(() => () => undefined)
|
|
39
|
+
}));
|
|
40
|
+
const cameraState = resolution => ({
|
|
41
|
+
resolution,
|
|
42
|
+
resolutionList: [ClarityType.HD, ClarityType.SD],
|
|
43
|
+
mute: true,
|
|
44
|
+
intercomMode: 'TwoWay',
|
|
45
|
+
isIntercomSupported: false,
|
|
46
|
+
maxZoomSettings: 6
|
|
47
|
+
});
|
|
48
|
+
describe('cached auto clarity restoration', () => {
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
jest.clearAllMocks();
|
|
51
|
+
});
|
|
52
|
+
const mountContext = resolution => {
|
|
53
|
+
const setClarity = jest.fn();
|
|
54
|
+
const getMemoryState = jest.fn().mockResolvedValue(cameraState(resolution));
|
|
55
|
+
const useCtx = createUseCtx({
|
|
56
|
+
createPlayContext: () => ({
|
|
57
|
+
setClarity
|
|
58
|
+
}),
|
|
59
|
+
getMemoryState,
|
|
60
|
+
setResolutionMemoryState: jest.fn(),
|
|
61
|
+
setMuteMemoryState: jest.fn(),
|
|
62
|
+
authorizeStatus: jest.fn(),
|
|
63
|
+
toast: jest.fn()
|
|
64
|
+
});
|
|
65
|
+
const hook = renderHook(() => {
|
|
66
|
+
const ctx = useCtx({
|
|
67
|
+
devId: 'camera-1'
|
|
68
|
+
});
|
|
69
|
+
const state = useStore({
|
|
70
|
+
resolution: ctx.resolution,
|
|
71
|
+
autoClarity: ctx.autoClarity
|
|
72
|
+
});
|
|
73
|
+
return _objectSpread(_objectSpread({}, ctx), {}, {
|
|
74
|
+
state
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
return _objectSpread(_objectSpread({}, hook), {}, {
|
|
78
|
+
setClarity
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
it('shows last listener value on reopening AUTO and refreshes it after preview', async () => {
|
|
82
|
+
getCachedAutoClarity.mockReturnValue(ClarityType.HD);
|
|
83
|
+
const {
|
|
84
|
+
result,
|
|
85
|
+
setClarity,
|
|
86
|
+
unmount
|
|
87
|
+
} = mountContext(ClarityType.AUTO);
|
|
88
|
+
await act(async () => Promise.resolve());
|
|
89
|
+
expect(result.current.state).toEqual({
|
|
90
|
+
resolution: ClarityType.AUTO,
|
|
91
|
+
autoClarity: ClarityType.HD
|
|
92
|
+
});
|
|
93
|
+
act(() => result.current.setPlayState(PlayState.PLAYING));
|
|
94
|
+
await act(async () => Promise.resolve());
|
|
95
|
+
expect(setClarity).toHaveBeenCalledTimes(1);
|
|
96
|
+
expect(setClarity).toHaveBeenCalledWith(expect.objectContaining({
|
|
97
|
+
clarity: 'auto'
|
|
98
|
+
}));
|
|
99
|
+
const onReport = subscribeClarityChanged.mock.calls[0][1];
|
|
100
|
+
act(() => onReport({
|
|
101
|
+
deviceId: 'camera-1',
|
|
102
|
+
clarity: ClarityType.SD
|
|
103
|
+
}));
|
|
104
|
+
expect(result.current.state.autoClarity).toBe(ClarityType.SD);
|
|
105
|
+
expect(setCachedAutoClarity).toHaveBeenCalledWith('camera-1', ClarityType.SD);
|
|
106
|
+
unmount();
|
|
107
|
+
});
|
|
108
|
+
it('does not restore cached actual clarity in manual mode', async () => {
|
|
109
|
+
getCachedAutoClarity.mockReturnValue(ClarityType.HD);
|
|
110
|
+
const {
|
|
111
|
+
result,
|
|
112
|
+
unmount
|
|
113
|
+
} = mountContext(ClarityType.SD);
|
|
114
|
+
await act(async () => Promise.resolve());
|
|
115
|
+
expect(result.current.state).toEqual({
|
|
116
|
+
resolution: ClarityType.SD,
|
|
117
|
+
autoClarity: null
|
|
118
|
+
});
|
|
119
|
+
expect(getCachedAutoClarity).not.toHaveBeenCalled();
|
|
120
|
+
const onReport = subscribeClarityChanged.mock.calls[0][1];
|
|
121
|
+
act(() => onReport({
|
|
122
|
+
deviceId: 'camera-1',
|
|
123
|
+
clarity: ClarityType.HD
|
|
124
|
+
}));
|
|
125
|
+
expect(result.current.state.autoClarity).toBeNull();
|
|
126
|
+
expect(setCachedAutoClarity).not.toHaveBeenCalled();
|
|
127
|
+
unmount();
|
|
128
|
+
});
|
|
129
|
+
it('requests a fresh report when reopening AUTO without an actual clarity cache', async () => {
|
|
130
|
+
getCachedAutoClarity.mockReturnValue(null);
|
|
131
|
+
const {
|
|
132
|
+
result,
|
|
133
|
+
setClarity,
|
|
134
|
+
unmount
|
|
135
|
+
} = mountContext(ClarityType.AUTO);
|
|
136
|
+
await act(async () => Promise.resolve());
|
|
137
|
+
expect(result.current.state.autoClarity).toBeNull();
|
|
138
|
+
act(() => result.current.setPlayState(PlayState.PLAYING));
|
|
139
|
+
expect(setClarity).toHaveBeenCalledWith(expect.objectContaining({
|
|
140
|
+
clarity: 'auto'
|
|
141
|
+
}));
|
|
142
|
+
const onReport = subscribeClarityChanged.mock.calls[0][1];
|
|
143
|
+
act(() => onReport({
|
|
144
|
+
deviceId: 'camera-1',
|
|
145
|
+
clarity: ClarityType.HD
|
|
146
|
+
}));
|
|
147
|
+
expect(result.current.state.autoClarity).toBe(ClarityType.HD);
|
|
148
|
+
unmount();
|
|
149
|
+
});
|
|
150
|
+
});
|
package/lib/ctx/ctx.js
CHANGED
|
@@ -12,6 +12,7 @@ import { changeIgnoreHideStopPreview } from '../ui/constant';
|
|
|
12
12
|
import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
|
|
13
13
|
import { getEventInstance } from './event';
|
|
14
14
|
import { isMultiCameraTileSupported, useMultiCameraCtx } from './multiCameraCtx';
|
|
15
|
+
import { getCachedAutoClarity, isClarityChangedSupported, setCachedAutoClarity, subscribeClarityChanged } from '../utils/ttt';
|
|
15
16
|
const SAVE_TO_ALBUM = 1;
|
|
16
17
|
export const createUseCtx = _ref => {
|
|
17
18
|
let {
|
|
@@ -74,6 +75,8 @@ export const createUseCtx = _ref => {
|
|
|
74
75
|
const [resolution] = useAtom('HD');
|
|
75
76
|
// resolution 清晰度列表
|
|
76
77
|
const [resolutionList, setResolutionList] = useAtom([]);
|
|
78
|
+
// 自动模式下宿主上报的实际清晰度,供横竖屏码率区域共用
|
|
79
|
+
const [autoClarity] = useAtom(null);
|
|
77
80
|
|
|
78
81
|
// 单向对讲还是双向对讲
|
|
79
82
|
const [intercomMode, setIntercomMode] = useAtom(IntercomMode.TwoWay);
|
|
@@ -101,22 +104,66 @@ export const createUseCtx = _ref => {
|
|
|
101
104
|
const [bottomRightContent] = useAtom(initBottomRightContent || defaultBottomRightContent || []);
|
|
102
105
|
const [absoluteContent] = useAtom(initAbsoluteContent || defaultAbsoluteContent || []);
|
|
103
106
|
const {
|
|
104
|
-
_playState
|
|
107
|
+
_playState,
|
|
108
|
+
currentResolution
|
|
105
109
|
} = useStore({
|
|
106
|
-
_playState: playState
|
|
110
|
+
_playState: playState,
|
|
111
|
+
currentResolution: resolution
|
|
107
112
|
});
|
|
113
|
+
const restoredAutoRef = useRef(false);
|
|
114
|
+
const refreshedAutoRef = useRef(false);
|
|
115
|
+
const freshAutoClarityRef = useRef(false);
|
|
116
|
+
const pendingAutoSelectionRef = useRef(false);
|
|
117
|
+
const userSelectedResolutionRef = useRef(false);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
updateAtom(autoClarity, null);
|
|
120
|
+
restoredAutoRef.current = false;
|
|
121
|
+
refreshedAutoRef.current = false;
|
|
122
|
+
freshAutoClarityRef.current = false;
|
|
123
|
+
userSelectedResolutionRef.current = false;
|
|
124
|
+
if (!devId) return undefined;
|
|
125
|
+
return subscribeClarityChanged(devId, res => {
|
|
126
|
+
if (getDefaultStore().get(resolution) !== ClarityType.AUTO && !pendingAutoSelectionRef.current) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
freshAutoClarityRef.current = true;
|
|
130
|
+
updateAtom(autoClarity, res.clarity);
|
|
131
|
+
setCachedAutoClarity(devId, res.clarity);
|
|
132
|
+
});
|
|
133
|
+
}, [autoClarity, devId, resolution]);
|
|
108
134
|
const eventRef = useRef();
|
|
109
135
|
if (!eventRef.current) {
|
|
110
136
|
eventRef.current = getEventInstance();
|
|
111
137
|
}
|
|
112
138
|
|
|
113
139
|
/**
|
|
114
|
-
*
|
|
140
|
+
* 只有宿主支持自动清晰度事件,且接口返回的清晰度档位数量不少于 2 个时,才展示 AUTO:
|
|
115
141
|
* 竖屏宿主弹框(由 resolutionList 构建 actionData)与横屏 FullResolutionControl 共用。
|
|
116
142
|
*/
|
|
143
|
+
const canShowAutoClarity = function () {
|
|
144
|
+
let list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
145
|
+
return isClarityChangedSupported() && list.length >= 2;
|
|
146
|
+
};
|
|
117
147
|
const withAutoClarity = function () {
|
|
118
148
|
let list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
119
|
-
|
|
149
|
+
const withoutAuto = list.filter(clarity => clarity !== ClarityType.AUTO);
|
|
150
|
+
return canShowAutoClarity(list) ? [...withoutAuto, ClarityType.AUTO] : withoutAuto;
|
|
151
|
+
};
|
|
152
|
+
const normalizeResolution = (resolution, list) => {
|
|
153
|
+
if (resolution !== ClarityType.AUTO || canShowAutoClarity(list)) return resolution;
|
|
154
|
+
return list.find(clarity => clarity !== ClarityType.AUTO) || ClarityType.HD;
|
|
155
|
+
};
|
|
156
|
+
const restoreResolution = (cachedResolution, list) => {
|
|
157
|
+
if (userSelectedResolutionRef.current) return;
|
|
158
|
+
const target = normalizeResolution(cachedResolution, list);
|
|
159
|
+
if (target === ClarityType.AUTO) {
|
|
160
|
+
restoredAutoRef.current = true;
|
|
161
|
+
const cachedClarity = getCachedAutoClarity(devId);
|
|
162
|
+
if (cachedClarity && list.includes(cachedClarity) && !getDefaultStore().get(autoClarity)) {
|
|
163
|
+
updateAtom(autoClarity, cachedClarity);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
_setResolution(target, true);
|
|
120
167
|
};
|
|
121
168
|
useEffect(() => {
|
|
122
169
|
// 初始化获取缓存值
|
|
@@ -127,7 +174,7 @@ export const createUseCtx = _ref => {
|
|
|
127
174
|
var _res$maxZoomSettings;
|
|
128
175
|
const res = await getMemoryState(devId);
|
|
129
176
|
setResolutionList(withAutoClarity(res.resolutionList));
|
|
130
|
-
|
|
177
|
+
restoreResolution(res.resolution, res.resolutionList);
|
|
131
178
|
_setMute(res.mute, true);
|
|
132
179
|
setIntercomMode(res.intercomMode);
|
|
133
180
|
setIntercomSupported(res.isIntercomSupported);
|
|
@@ -144,7 +191,7 @@ export const createUseCtx = _ref => {
|
|
|
144
191
|
var _res$maxZoomSettings2;
|
|
145
192
|
setResolutionList(withAutoClarity(res.resolutionList));
|
|
146
193
|
// 传true表示值即可,会取播放器的值
|
|
147
|
-
|
|
194
|
+
restoreResolution(res.resolution, res.resolutionList);
|
|
148
195
|
_setMute(res.mute, true);
|
|
149
196
|
setIntercomMode(res.intercomMode);
|
|
150
197
|
setIntercomSupported(res.isIntercomSupported);
|
|
@@ -152,6 +199,18 @@ export const createUseCtx = _ref => {
|
|
|
152
199
|
});
|
|
153
200
|
}
|
|
154
201
|
}, [devId, _playState]);
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
var _IPCPlayerInstance$cu;
|
|
204
|
+
if (!devId || _playState !== PlayState.PLAYING || currentResolution !== ClarityType.AUTO || !restoredAutoRef.current || freshAutoClarityRef.current || refreshedAutoRef.current) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
refreshedAutoRef.current = true;
|
|
208
|
+
// 缓存只保证首屏有上次档位;出流后重申自动,让宿主回报本次实际档位。
|
|
209
|
+
(_IPCPlayerInstance$cu = IPCPlayerInstance.current) === null || _IPCPlayerInstance$cu === void 0 || _IPCPlayerInstance$cu.setClarity({
|
|
210
|
+
clarity: 'auto',
|
|
211
|
+
fail: error => console.warn('res===restore auto clarity fail', error)
|
|
212
|
+
});
|
|
213
|
+
}, [devId, _playState, currentResolution]);
|
|
155
214
|
// 获取content数据
|
|
156
215
|
const getContent = () => {
|
|
157
216
|
const store = getDefaultStore();
|
|
@@ -246,6 +305,13 @@ export const createUseCtx = _ref => {
|
|
|
246
305
|
updateAtom(resolution, target);
|
|
247
306
|
return false;
|
|
248
307
|
}
|
|
308
|
+
userSelectedResolutionRef.current = true;
|
|
309
|
+
// 清晰度事件可能在 setClarity 的 success 回调前到达,进入自动前先清掉上次的值。
|
|
310
|
+
restoredAutoRef.current = false;
|
|
311
|
+
if (target === ClarityType.AUTO) {
|
|
312
|
+
pendingAutoSelectionRef.current = true;
|
|
313
|
+
updateAtom(autoClarity, null);
|
|
314
|
+
}
|
|
249
315
|
return new Promise((resolve, reject) => {
|
|
250
316
|
const clarityMap = {
|
|
251
317
|
[ClarityType.SS]: 'ss',
|
|
@@ -259,11 +325,13 @@ export const createUseCtx = _ref => {
|
|
|
259
325
|
IPCPlayerInstance.current.setClarity({
|
|
260
326
|
clarity: clarityMap[target] || 'normal',
|
|
261
327
|
success: () => {
|
|
328
|
+
pendingAutoSelectionRef.current = false;
|
|
262
329
|
setResolutionMemoryState(devId, target);
|
|
263
330
|
updateAtom(resolution, target);
|
|
264
331
|
resolve(true);
|
|
265
332
|
},
|
|
266
333
|
fail: err => {
|
|
334
|
+
pendingAutoSelectionRef.current = false;
|
|
267
335
|
console.log(err, 'setClarity err');
|
|
268
336
|
// updateAtom(mute, !target);
|
|
269
337
|
reject(err);
|
|
@@ -315,6 +383,7 @@ export const createUseCtx = _ref => {
|
|
|
315
383
|
mute,
|
|
316
384
|
resolution,
|
|
317
385
|
resolutionList,
|
|
386
|
+
autoClarity,
|
|
318
387
|
intercom,
|
|
319
388
|
intercomMode,
|
|
320
389
|
intercomSupported,
|
package/lib/i18n/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { kit } from '@ray-js/panel-sdk';
|
|
2
2
|
declare const Strings: kit.I18N<{
|
|
3
3
|
en: {
|
|
4
|
+
ipc_player_resolution_SS: string;
|
|
4
5
|
ipc_player_resolution_HD: string;
|
|
5
6
|
ipc_player_resolution_SD: string;
|
|
7
|
+
ipc_player_resolution_UD: string;
|
|
8
|
+
ipc_player_resolution_SSP: string;
|
|
6
9
|
ipc_player_resolution_AUTO: string;
|
|
10
|
+
ipc_player_resolution_AUDIO: string;
|
|
7
11
|
ipc_player_current_resolution_is_equal: string;
|
|
8
12
|
ipc_player_screenshot_success_tip: string;
|
|
9
13
|
ipc_player_screenshot_multi_success_tip: string;
|
|
@@ -42,9 +46,13 @@ declare const Strings: kit.I18N<{
|
|
|
42
46
|
ipc_player_low_phone_not_support: string;
|
|
43
47
|
};
|
|
44
48
|
zh: {
|
|
49
|
+
ipc_player_resolution_SS: string;
|
|
45
50
|
ipc_player_resolution_HD: string;
|
|
46
51
|
ipc_player_resolution_SD: string;
|
|
52
|
+
ipc_player_resolution_UD: string;
|
|
53
|
+
ipc_player_resolution_SSP: string;
|
|
47
54
|
ipc_player_resolution_AUTO: string;
|
|
55
|
+
ipc_player_resolution_AUDIO: string;
|
|
48
56
|
ipc_player_current_resolution_is_equal: string;
|
|
49
57
|
ipc_player_screenshot_success_tip: string;
|
|
50
58
|
ipc_player_screenshot_multi_success_tip: string;
|
|
@@ -83,9 +91,13 @@ declare const Strings: kit.I18N<{
|
|
|
83
91
|
ipc_player_low_phone_not_support: string;
|
|
84
92
|
};
|
|
85
93
|
}, {
|
|
94
|
+
ipc_player_resolution_SS: string;
|
|
86
95
|
ipc_player_resolution_HD: string;
|
|
87
96
|
ipc_player_resolution_SD: string;
|
|
97
|
+
ipc_player_resolution_UD: string;
|
|
98
|
+
ipc_player_resolution_SSP: string;
|
|
88
99
|
ipc_player_resolution_AUTO: string;
|
|
100
|
+
ipc_player_resolution_AUDIO: string;
|
|
89
101
|
ipc_player_current_resolution_is_equal: string;
|
|
90
102
|
ipc_player_screenshot_success_tip: string;
|
|
91
103
|
ipc_player_screenshot_multi_success_tip: string;
|
|
@@ -123,9 +135,13 @@ declare const Strings: kit.I18N<{
|
|
|
123
135
|
ipc_player_fetch_error: string;
|
|
124
136
|
ipc_player_low_phone_not_support: string;
|
|
125
137
|
} | {
|
|
138
|
+
ipc_player_resolution_SS: string;
|
|
126
139
|
ipc_player_resolution_HD: string;
|
|
127
140
|
ipc_player_resolution_SD: string;
|
|
141
|
+
ipc_player_resolution_UD: string;
|
|
142
|
+
ipc_player_resolution_SSP: string;
|
|
128
143
|
ipc_player_resolution_AUTO: string;
|
|
144
|
+
ipc_player_resolution_AUDIO: string;
|
|
129
145
|
ipc_player_current_resolution_is_equal: string;
|
|
130
146
|
ipc_player_screenshot_success_tip: string;
|
|
131
147
|
ipc_player_screenshot_multi_success_tip: string;
|
package/lib/i18n/strings.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
en: {
|
|
3
|
+
ipc_player_resolution_SS: string;
|
|
3
4
|
ipc_player_resolution_HD: string;
|
|
4
5
|
ipc_player_resolution_SD: string;
|
|
6
|
+
ipc_player_resolution_UD: string;
|
|
7
|
+
ipc_player_resolution_SSP: string;
|
|
5
8
|
ipc_player_resolution_AUTO: string;
|
|
9
|
+
ipc_player_resolution_AUDIO: string;
|
|
6
10
|
ipc_player_current_resolution_is_equal: string;
|
|
7
11
|
ipc_player_screenshot_success_tip: string;
|
|
8
12
|
ipc_player_screenshot_multi_success_tip: string;
|
|
@@ -41,9 +45,13 @@ declare const _default: {
|
|
|
41
45
|
ipc_player_low_phone_not_support: string;
|
|
42
46
|
};
|
|
43
47
|
zh: {
|
|
48
|
+
ipc_player_resolution_SS: string;
|
|
44
49
|
ipc_player_resolution_HD: string;
|
|
45
50
|
ipc_player_resolution_SD: string;
|
|
51
|
+
ipc_player_resolution_UD: string;
|
|
52
|
+
ipc_player_resolution_SSP: string;
|
|
46
53
|
ipc_player_resolution_AUTO: string;
|
|
54
|
+
ipc_player_resolution_AUDIO: string;
|
|
47
55
|
ipc_player_current_resolution_is_equal: string;
|
|
48
56
|
ipc_player_screenshot_success_tip: string;
|
|
49
57
|
ipc_player_screenshot_multi_success_tip: string;
|
package/lib/i18n/strings.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
en: {
|
|
3
|
+
ipc_player_resolution_SS: 'Data Saver',
|
|
3
4
|
ipc_player_resolution_HD: 'HD',
|
|
4
5
|
ipc_player_resolution_SD: 'SD',
|
|
6
|
+
ipc_player_resolution_UD: 'Ultra HD',
|
|
7
|
+
ipc_player_resolution_SSP: 'Super Ultra HD',
|
|
5
8
|
ipc_player_resolution_AUTO: 'Auto',
|
|
9
|
+
ipc_player_resolution_AUDIO: 'Audio Mode',
|
|
6
10
|
ipc_player_current_resolution_is_equal: 'Already at current clarity',
|
|
7
11
|
ipc_player_screenshot_success_tip: 'Screenshot saved to album',
|
|
8
12
|
ipc_player_screenshot_multi_success_tip: 'Screenshots saved to album',
|
|
@@ -41,9 +45,13 @@ export default {
|
|
|
41
45
|
ipc_player_low_phone_not_support: 'This feature is not supported on this device'
|
|
42
46
|
},
|
|
43
47
|
zh: {
|
|
48
|
+
ipc_player_resolution_SS: '省流量',
|
|
44
49
|
ipc_player_resolution_HD: '高清',
|
|
45
50
|
ipc_player_resolution_SD: '标清',
|
|
51
|
+
ipc_player_resolution_UD: '超清',
|
|
52
|
+
ipc_player_resolution_SSP: '超超清',
|
|
46
53
|
ipc_player_resolution_AUTO: '自动',
|
|
54
|
+
ipc_player_resolution_AUDIO: '音频模式',
|
|
47
55
|
ipc_player_current_resolution_is_equal: '已是当前清晰度',
|
|
48
56
|
ipc_player_screenshot_success_tip: '截图已保存在APP相册',
|
|
49
57
|
ipc_player_screenshot_multi_success_tip: '图片已保存至相册',
|
package/lib/interface.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { PrimitiveAtom } from 'jotai';
|
|
3
|
+
import type { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
|
|
3
4
|
import type { Toast, IntercomMode } from './ports.output';
|
|
4
5
|
import { useMultiCameraCtx } from './ctx/multiCameraCtx';
|
|
5
6
|
import type { ZoomSkill } from './widgets/zoomTurntable/lensSkill';
|
|
@@ -74,6 +75,7 @@ export type UseCtx = (options: {
|
|
|
74
75
|
setZoomLensIndex: (value: number) => void;
|
|
75
76
|
resolution: RetAtom<string>;
|
|
76
77
|
resolutionList: RetAtom<string[]>;
|
|
78
|
+
autoClarity: RetAtom<ClarityType | null>;
|
|
77
79
|
playState: RetAtom<PlayState>;
|
|
78
80
|
IPCPlayerInstance: IpcContext;
|
|
79
81
|
topLeftContent: RetAtom<ComponentConfig[]>;
|
|
@@ -143,12 +145,7 @@ export type CaptureFileInfo = {
|
|
|
143
145
|
height?: number;
|
|
144
146
|
data?: string;
|
|
145
147
|
};
|
|
146
|
-
export type
|
|
147
|
-
index: number;
|
|
148
|
-
};
|
|
149
|
-
export type CaptureResult = boolean | CaptureFileInfo | {
|
|
150
|
-
items: MultiCaptureFileInfo[];
|
|
151
|
-
};
|
|
148
|
+
export type CaptureResult = boolean | CaptureFileInfo;
|
|
152
149
|
export type RecordInfoData = CaptureResult;
|
|
153
150
|
/**
|
|
154
151
|
* 多目屏幕模式
|
package/lib/ui/constant.d.ts
CHANGED
|
@@ -60,12 +60,6 @@ export declare const widgetLabs: {
|
|
|
60
60
|
*/
|
|
61
61
|
export declare const bottomLeftContentResize = "bottomLeftContentResize";
|
|
62
62
|
export declare const zoomLevelChange = "zoomLevelChange";
|
|
63
|
-
/**
|
|
64
|
-
* 自动清晰度状态变化事件:Resolution 控件检测到清晰度进入/退出自动模式或收到
|
|
65
|
-
* clarityChanged 回调结果时触发,携带 { enabled, clarity }(clarity 为 'HD' | 'SD' | null)。
|
|
66
|
-
* VideoBitKBP 监听此事件,在码率前展示当前高清/标清文案。
|
|
67
|
-
*/
|
|
68
|
-
export declare const autoClarityChange = "autoClarityChange";
|
|
69
63
|
export declare const setScaleMultipleEvent = "setScaleMultipleEvent";
|
|
70
64
|
export declare const decodeClarityDic: {
|
|
71
65
|
SS: string;
|
package/lib/ui/constant.js
CHANGED
|
@@ -63,13 +63,6 @@ export const widgetLabs = {
|
|
|
63
63
|
*/
|
|
64
64
|
export const bottomLeftContentResize = 'bottomLeftContentResize';
|
|
65
65
|
export const zoomLevelChange = 'zoomLevelChange';
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 自动清晰度状态变化事件:Resolution 控件检测到清晰度进入/退出自动模式或收到
|
|
69
|
-
* clarityChanged 回调结果时触发,携带 { enabled, clarity }(clarity 为 'HD' | 'SD' | null)。
|
|
70
|
-
* VideoBitKBP 监听此事件,在码率前展示当前高清/标清文案。
|
|
71
|
-
*/
|
|
72
|
-
export const autoClarityChange = 'autoClarityChange';
|
|
73
66
|
export const setScaleMultipleEvent = 'setScaleMultipleEvent';
|
|
74
67
|
export const decodeClarityDic = {
|
|
75
68
|
SS: 'ss',
|
package/lib/ui/ui.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
3
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
4
|
import "core-js/modules/esnext.iterator.filter.js";
|
|
4
5
|
import "core-js/modules/esnext.iterator.find.js";
|
|
5
6
|
import "core-js/modules/esnext.iterator.map.js";
|
|
7
|
+
import "core-js/modules/esnext.iterator.some.js";
|
|
6
8
|
import React, { useContext, useState, useRef, useMemo, useEffect, useImperativeHandle } from 'react';
|
|
7
9
|
import { View, CoverView, getSystemInfoSync, usePageEvent, setNavigationBarBack, setPageOrientation, getCurrentPages } from '@ray-js/ray';
|
|
8
10
|
import { unstable_batchedUpdates as batchedUpdates } from '@ray-core/ray';
|
|
9
11
|
import clsx from 'clsx';
|
|
10
12
|
import IPCPlayer from '@ray-js/ray-ipc-player';
|
|
11
13
|
import { ipcTTTOperatorLog } from '@ray-js/ray-ipc-utils';
|
|
14
|
+
import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
|
|
12
15
|
import { PlayState, PlayerStreamStatus, MultiCameraScreenMode } from '../interface';
|
|
13
16
|
import { useCtx } from '../ctx/ctx.composition';
|
|
14
17
|
import { useStore, updateAtom, getDefaultStore } from '../ctx/store';
|
|
@@ -18,7 +21,7 @@ import BottomLeftContent from './bottomLeftContent';
|
|
|
18
21
|
import BottomRightContent from './bottomRightContent';
|
|
19
22
|
import TopLeftContent from './topLeftContent';
|
|
20
23
|
import TopRightContent from './topRightContent';
|
|
21
|
-
import { FlowLowTip } from '../widgets';
|
|
24
|
+
import { FlowLowTip, VideoBitKBP } from '../widgets';
|
|
22
25
|
import { useMemoizedFn } from '../hooks';
|
|
23
26
|
import { Storage } from '../utils/storage';
|
|
24
27
|
import './ui.less';
|
|
@@ -27,6 +30,36 @@ import { getNgRawData, getSmartImageQualityState, isLowPhone, notifyOfflineShown
|
|
|
27
30
|
import { getCaptureResultSummary } from '../utils/captureResult';
|
|
28
31
|
import { lensCount } from '../widgets/zoomTurntable/lensSkill';
|
|
29
32
|
import { shouldRenderContent } from './absoluteContent';
|
|
33
|
+
const AutoClarityOnly = _ref => {
|
|
34
|
+
let {
|
|
35
|
+
instance
|
|
36
|
+
} = _ref;
|
|
37
|
+
return /*#__PURE__*/React.createElement(VideoBitKBP, _extends({}, instance, {
|
|
38
|
+
IPCPlayerContext: instance.IPCPlayerInstance,
|
|
39
|
+
className: "top-right-item-container",
|
|
40
|
+
hideKbsMenu: true,
|
|
41
|
+
hideSignalMenu: true
|
|
42
|
+
}));
|
|
43
|
+
};
|
|
44
|
+
const StandaloneAutoClarity = _ref2 => {
|
|
45
|
+
let {
|
|
46
|
+
instance,
|
|
47
|
+
show
|
|
48
|
+
} = _ref2;
|
|
49
|
+
const {
|
|
50
|
+
resolution,
|
|
51
|
+
autoClarity
|
|
52
|
+
} = useStore({
|
|
53
|
+
resolution: instance.resolution,
|
|
54
|
+
autoClarity: instance.autoClarity
|
|
55
|
+
});
|
|
56
|
+
if (!show || resolution !== ClarityType.AUTO || !autoClarity) return null;
|
|
57
|
+
return /*#__PURE__*/React.createElement(TopRightContent, {
|
|
58
|
+
ctx: instance
|
|
59
|
+
}, /*#__PURE__*/React.createElement(AutoClarityOnly, {
|
|
60
|
+
instance: instance
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
30
63
|
function getCtxInstance(instance, devId) {
|
|
31
64
|
if (instance) return instance;
|
|
32
65
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -661,8 +694,12 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
661
694
|
setRecording(false, true);
|
|
662
695
|
setIntercom(false, true);
|
|
663
696
|
instance === null || instance === void 0 || instance.stopRecordingOnUnload().then(async result => {
|
|
664
|
-
var _instance$multiCamera;
|
|
665
|
-
const summary = await getCaptureResultSummary(result,
|
|
697
|
+
var _instance$multiLens, _instance$multiCamera;
|
|
698
|
+
const summary = await getCaptureResultSummary(result, {
|
|
699
|
+
multiLens: (_instance$multiLens = instance === null || instance === void 0 ? void 0 : instance.multiLens) !== null && _instance$multiLens !== void 0 ? _instance$multiLens : false,
|
|
700
|
+
protocolCount: instance === null || instance === void 0 || (_instance$multiCamera = instance.multiCameraCtx) === null || _instance$multiCamera === void 0 || (_instance$multiCamera = _instance$multiCamera.protocol) === null || _instance$multiCamera === void 0 ? void 0 : _instance$multiCamera.total_split_num,
|
|
701
|
+
devId
|
|
702
|
+
});
|
|
666
703
|
ipcTTTOperatorLog(summary !== null && summary !== void 0 && summary.isMultiLens ? `hide: stop recording succeeded with ${summary.count} files` : 'hide: 调用停止录制方法成功');
|
|
667
704
|
}).catch(() => {
|
|
668
705
|
ipcTTTOperatorLog('hide: 调用停止录制方法失败');
|
|
@@ -1009,6 +1046,7 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
1009
1046
|
};
|
|
1010
1047
|
}, []);
|
|
1011
1048
|
const playerReady = playState === PlayState.PLAYING;
|
|
1049
|
+
const hasVisibleBitrateWidget = topRightContent === null || topRightContent === void 0 ? void 0 : topRightContent.some(item => item.id === 'VideoBitKBP' && !item.hidden);
|
|
1012
1050
|
/**
|
|
1013
1051
|
* 监听当前的zoom比例状态
|
|
1014
1052
|
*/
|
|
@@ -1202,7 +1240,12 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
|
|
|
1202
1240
|
ctx: instance
|
|
1203
1241
|
}, renderTopLeftContent), /*#__PURE__*/React.createElement(TopRightContent, {
|
|
1204
1242
|
ctx: instance
|
|
1205
|
-
}, renderTopRightContent
|
|
1243
|
+
}, renderTopRightContent, !hasVisibleBitrateWidget && /*#__PURE__*/React.createElement(AutoClarityOnly, {
|
|
1244
|
+
instance: instance
|
|
1245
|
+
})))), /*#__PURE__*/React.createElement(StandaloneAutoClarity, {
|
|
1246
|
+
instance: instance,
|
|
1247
|
+
show: !showTopContent || componentHideState || !playerReady
|
|
1248
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
1206
1249
|
className: clsx('ipc-player-bottom-content', {
|
|
1207
1250
|
'ipc-player-bottom-content-hide': componentHideState,
|
|
1208
1251
|
'ipc-player-bottom-content-show': !componentHideState,
|
|
@@ -4,6 +4,11 @@ export type CaptureResultSummary = {
|
|
|
4
4
|
isMultiLens: boolean;
|
|
5
5
|
thumbnailPath: string;
|
|
6
6
|
};
|
|
7
|
+
export type CaptureResultOptions = {
|
|
8
|
+
multiLens: boolean;
|
|
9
|
+
protocolCount?: number | string;
|
|
10
|
+
devId: string;
|
|
11
|
+
};
|
|
7
12
|
/** 从新多目高级能力配置获取当前设备的总镜头数 */
|
|
8
13
|
export declare function getMultiLensCountFromAbility(devId: string): Promise<number>;
|
|
9
|
-
export declare function getCaptureResultSummary(result: CaptureResult,
|
|
14
|
+
export declare function getCaptureResultSummary(result: CaptureResult, { multiLens, protocolCount, devId }: CaptureResultOptions): Promise<CaptureResultSummary | null>;
|
|
@@ -33,36 +33,38 @@ const extractPath = item => {
|
|
|
33
33
|
if (typeof (item === null || item === void 0 ? void 0 : item.value) === 'string') return item.value;
|
|
34
34
|
return '';
|
|
35
35
|
};
|
|
36
|
-
export async function getCaptureResultSummary(result,
|
|
36
|
+
export async function getCaptureResultSummary(result, _ref) {
|
|
37
|
+
let {
|
|
38
|
+
multiLens,
|
|
39
|
+
protocolCount,
|
|
40
|
+
devId
|
|
41
|
+
} = _ref;
|
|
37
42
|
if (!result || typeof result === 'boolean') return null;
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
if ('items' in result && Array.isArray(result.items) && result.items.length > 0) {
|
|
41
|
-
const firstItem = result.items[0];
|
|
42
|
-
const firstThumb = extractPath(firstItem === null || firstItem === void 0 ? void 0 : firstItem.tempImagePath) || extractPath(firstItem === null || firstItem === void 0 ? void 0 : firstItem.thumbPath) || extractPath(firstItem === null || firstItem === void 0 ? void 0 : firstItem.filePath) || singleThumb;
|
|
43
|
+
const thumbnailPath = extractPath(result.tempImagePath) || extractPath(result.thumbPath) || extractPath(result.filePath) || '';
|
|
44
|
+
if (!multiLens) {
|
|
43
45
|
return {
|
|
44
|
-
count:
|
|
45
|
-
isMultiLens:
|
|
46
|
-
thumbnailPath
|
|
46
|
+
count: 1,
|
|
47
|
+
isMultiLens: false,
|
|
48
|
+
thumbnailPath
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
|
-
const
|
|
51
|
+
const splitCount = Number(protocolCount) > 1 ? Number(protocolCount) : 0;
|
|
50
52
|
const multiLensAbilityCount = await getMultiLensCountFromAbility(devId);
|
|
51
53
|
|
|
52
54
|
// The native multi-lens snapshot can return one object while writing lens-specific
|
|
53
55
|
// files. Use the ability result to distinguish that file-name convention from the
|
|
54
56
|
// legacy split protocol.
|
|
55
|
-
const multiCount =
|
|
57
|
+
const multiCount = splitCount || multiLensAbilityCount;
|
|
56
58
|
if (multiCount > 1) {
|
|
57
59
|
return {
|
|
58
60
|
count: multiCount,
|
|
59
61
|
isMultiLens: true,
|
|
60
|
-
thumbnailPath: multiLensAbilityCount > 1 ? normalizeMultiLensThumbnailPath(
|
|
62
|
+
thumbnailPath: multiLensAbilityCount > 1 ? normalizeMultiLensThumbnailPath(thumbnailPath) : thumbnailPath
|
|
61
63
|
};
|
|
62
64
|
}
|
|
63
65
|
return {
|
|
64
66
|
count: 1,
|
|
65
67
|
isMultiLens: false,
|
|
66
|
-
thumbnailPath
|
|
68
|
+
thumbnailPath
|
|
67
69
|
};
|
|
68
70
|
}
|