@ray-js/ipc-player-integration 0.0.53-beta.1 → 0.0.53-beta.3

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.
@@ -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;
@@ -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;
@@ -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: '图片已保存至相册',
@@ -143,12 +143,7 @@ export type CaptureFileInfo = {
143
143
  height?: number;
144
144
  data?: string;
145
145
  };
146
- export type MultiCaptureFileInfo = CaptureFileInfo & {
147
- index: number;
148
- };
149
- export type CaptureResult = boolean | CaptureFileInfo | {
150
- items: MultiCaptureFileInfo[];
151
- };
146
+ export type CaptureResult = boolean | CaptureFileInfo;
152
147
  export type RecordInfoData = CaptureResult;
153
148
  /**
154
149
  * 多目屏幕模式
@@ -62,7 +62,7 @@ export declare const bottomLeftContentResize = "bottomLeftContentResize";
62
62
  export declare const zoomLevelChange = "zoomLevelChange";
63
63
  /**
64
64
  * 自动清晰度状态变化事件:Resolution 控件检测到清晰度进入/退出自动模式或收到
65
- * clarityChanged 回调结果时触发,携带 { enabled, clarity }(clarity 为 'HD' | 'SD' | null)。
65
+ * onClarityChanged 事件时触发,携带 { enabled, clarity }(clarity 为 ClarityType | null)。
66
66
  * VideoBitKBP 监听此事件,在码率前展示当前高清/标清文案。
67
67
  */
68
68
  export declare const autoClarityChange = "autoClarityChange";
@@ -66,7 +66,7 @@ export const zoomLevelChange = 'zoomLevelChange';
66
66
 
67
67
  /**
68
68
  * 自动清晰度状态变化事件:Resolution 控件检测到清晰度进入/退出自动模式或收到
69
- * clarityChanged 回调结果时触发,携带 { enabled, clarity }(clarity 为 'HD' | 'SD' | null)。
69
+ * onClarityChanged 事件时触发,携带 { enabled, clarity }(clarity 为 ClarityType | null)。
70
70
  * VideoBitKBP 监听此事件,在码率前展示当前高清/标清文案。
71
71
  */
72
72
  export const autoClarityChange = 'autoClarityChange';
package/lib/ui/ui.js CHANGED
@@ -661,8 +661,12 @@ export const IPCPlayerIntegration = /*#__PURE__*/React.memo(props => {
661
661
  setRecording(false, true);
662
662
  setIntercom(false, true);
663
663
  instance === null || instance === void 0 || instance.stopRecordingOnUnload().then(async result => {
664
- var _instance$multiCamera;
665
- const summary = await getCaptureResultSummary(result, 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, devId);
664
+ var _instance$multiLens, _instance$multiCamera;
665
+ const summary = await getCaptureResultSummary(result, {
666
+ multiLens: (_instance$multiLens = instance === null || instance === void 0 ? void 0 : instance.multiLens) !== null && _instance$multiLens !== void 0 ? _instance$multiLens : false,
667
+ 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,
668
+ devId
669
+ });
666
670
  ipcTTTOperatorLog(summary !== null && summary !== void 0 && summary.isMultiLens ? `hide: stop recording succeeded with ${summary.count} files` : 'hide: 调用停止录制方法成功');
667
671
  }).catch(() => {
668
672
  ipcTTTOperatorLog('hide: 调用停止录制方法失败');
@@ -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, fallbackCount: number | undefined, devId: string): Promise<CaptureResultSummary | null>;
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, fallbackCount, devId) {
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 rawResult = result;
39
- const singleThumb = extractPath(rawResult.tempImagePath) || extractPath(rawResult.thumbPath) || extractPath(rawResult.filePath) || '';
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: result.items.length,
45
- isMultiLens: true,
46
- thumbnailPath: firstThumb
46
+ count: 1,
47
+ isMultiLens: false,
48
+ thumbnailPath
47
49
  };
48
50
  }
49
- const legacySplitCount = fallbackCount && fallbackCount > 1 ? fallbackCount : 0;
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 = legacySplitCount || multiLensAbilityCount;
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(singleThumb) : singleThumb
62
+ thumbnailPath: multiLensAbilityCount > 1 ? normalizeMultiLensThumbnailPath(thumbnailPath) : thumbnailPath
61
63
  };
62
64
  }
63
65
  return {
64
66
  count: 1,
65
67
  isMultiLens: false,
66
- thumbnailPath: singleThumb
68
+ thumbnailPath
67
69
  };
68
70
  }
@@ -24,14 +24,33 @@ describe('getCaptureResultSummary', () => {
24
24
  }
25
25
  }
26
26
  });
27
- await expect(getCaptureResultSummary(createCaptureResult(basePath), undefined, 'dev-1')).resolves.toEqual({
27
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
28
+ multiLens: true,
29
+ devId: 'dev-1'
30
+ })).resolves.toEqual({
28
31
  count: 4,
29
32
  isMultiLens: true,
30
33
  thumbnailPath: 'thingfile://tmp/capture_123_lens1.jpg'
31
34
  });
32
35
  });
33
- it('keeps the legacy path when the ability is unavailable', async () => {
34
- await expect(getCaptureResultSummary(createCaptureResult(basePath), 4, 'dev-1')).resolves.toEqual({
36
+ it('keeps the single-lens result for a legacy multi-camera device', async () => {
37
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
38
+ multiLens: false,
39
+ protocolCount: 4,
40
+ devId: 'dev-1'
41
+ })).resolves.toEqual({
42
+ count: 1,
43
+ isMultiLens: false,
44
+ thumbnailPath: basePath
45
+ });
46
+ expect(mockGetDeviceInfo).not.toHaveBeenCalled();
47
+ });
48
+ it('uses the protocol count when the multi-lens mode is enabled', async () => {
49
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
50
+ multiLens: true,
51
+ protocolCount: 4,
52
+ devId: 'dev-1'
53
+ })).resolves.toEqual({
35
54
  count: 4,
36
55
  isMultiLens: true,
37
56
  thumbnailPath: basePath
@@ -46,7 +65,11 @@ describe('getCaptureResultSummary', () => {
46
65
  }
47
66
  }
48
67
  });
49
- await expect(getCaptureResultSummary(createCaptureResult(basePath), 4, 'dev-1')).resolves.toEqual({
68
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
69
+ multiLens: true,
70
+ protocolCount: 4,
71
+ devId: 'dev-1'
72
+ })).resolves.toEqual({
50
73
  count: 4,
51
74
  isMultiLens: true,
52
75
  thumbnailPath: 'thingfile://tmp/capture_123_lens1.jpg'
@@ -61,29 +84,33 @@ describe('getCaptureResultSummary', () => {
61
84
  }
62
85
  });
63
86
  const path = 'thingfile://tmp/capture_123_lens1.jpg';
64
- await expect(getCaptureResultSummary(createCaptureResult(path), undefined, 'dev-1')).resolves.toEqual({
87
+ await expect(getCaptureResultSummary(createCaptureResult(path), {
88
+ multiLens: true,
89
+ devId: 'dev-1'
90
+ })).resolves.toEqual({
65
91
  count: 4,
66
92
  isMultiLens: true,
67
93
  thumbnailPath: path
68
94
  });
69
95
  });
70
96
  it('keeps a mono result unchanged', async () => {
71
- await expect(getCaptureResultSummary(createCaptureResult(basePath), undefined, 'dev-1')).resolves.toEqual({
97
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
98
+ multiLens: false,
99
+ devId: 'dev-1'
100
+ })).resolves.toEqual({
72
101
  count: 1,
73
102
  isMultiLens: false,
74
103
  thumbnailPath: basePath
75
104
  });
76
105
  });
77
- it('keeps item paths unchanged', async () => {
78
- await expect(getCaptureResultSummary({
79
- items: [{
80
- index: 1,
81
- tempImagePath: basePath,
82
- filePath: basePath
83
- }]
84
- }, undefined, 'dev-1')).resolves.toEqual({
106
+ it('keeps a single-lens result when multi-lens mode has one lens', async () => {
107
+ await expect(getCaptureResultSummary(createCaptureResult(basePath), {
108
+ multiLens: true,
109
+ protocolCount: 1,
110
+ devId: 'dev-1'
111
+ })).resolves.toEqual({
85
112
  count: 1,
86
- isMultiLens: true,
113
+ isMultiLens: false,
87
114
  thumbnailPath: basePath
88
115
  });
89
116
  });
@@ -1,3 +1,4 @@
1
+ import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
1
2
  export type SmartImageQualityResult = {
2
3
  isPurchase: boolean;
3
4
  buttonState: number;
@@ -48,6 +49,17 @@ export declare function notifyOfflineShown(deviceId: string): boolean;
48
49
  export declare function getNgRawData(): Promise<unknown>;
49
50
  export declare function isClarityChangedSupported(): boolean;
50
51
  export type ClarityChangedResult = {
51
- clarity: 'HD' | 'SD';
52
+ deviceId?: string;
53
+ clarity: ClarityType;
52
54
  };
53
- export declare function clarityChanged(devId: string): Promise<ClarityChangedResult | null>;
55
+ export type ClarityChangedHandler = (result: ClarityChangedResult) => void;
56
+ type ClarityChangedListener = (payload: ClarityChangedResult) => void;
57
+ export declare function offClarityChanged(listener: ClarityChangedListener): void;
58
+ /**
59
+ * 监听自动清晰度变化,返回取消监听函数。
60
+ *
61
+ * onClarityChanged / offClarityChanged 均使用同一个 listener 引用,
62
+ * 否则宿主无法正确移除监听。
63
+ */
64
+ export declare function subscribeClarityChanged(devId: string, handler: ClarityChangedHandler): () => void;
65
+ export {};
package/lib/utils/ttt.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
2
3
  export function getSmartImageQualityState(devId) {
3
4
  return new Promise(resolve => {
4
5
  var _ty$ipc;
@@ -165,35 +166,63 @@ export function getNgRawData() {
165
166
  });
166
167
  }
167
168
 
168
- // 是否支持自动清晰度(ttt 方法 clarityChanged 存在即支持)
169
+ // 是否支持自动清晰度(ttt 方法 onClarityChanged 存在即支持)
169
170
  export function isClarityChangedSupported() {
170
- var _ty$ipc6;
171
- return typeof ((_ty$ipc6 = ty.ipc) === null || _ty$ipc6 === void 0 ? void 0 : _ty$ipc6.clarityChanged) === 'function';
171
+ var _ty5;
172
+ return typeof ty !== 'undefined' && typeof ((_ty5 = ty) === null || _ty5 === void 0 || (_ty5 = _ty5.ipc) === null || _ty5 === void 0 ? void 0 : _ty5.onClarityChanged) === 'function';
172
173
  }
173
- export function clarityChanged(devId) {
174
- return new Promise(resolve => {
175
- var _ty$ipc7;
176
- if (typeof ((_ty$ipc7 = ty.ipc) === null || _ty$ipc7 === void 0 ? void 0 : _ty$ipc7.clarityChanged) !== 'function') {
177
- resolve(null);
174
+ export function offClarityChanged(listener) {
175
+ var _ty6;
176
+ const ipc = typeof ty !== 'undefined' ? (_ty6 = ty) === null || _ty6 === void 0 ? void 0 : _ty6.ipc : undefined;
177
+ if (!ipc || typeof ipc.offClarityChanged !== 'function') {
178
+ return;
179
+ }
180
+ try {
181
+ ipc.offClarityChanged(listener);
182
+ } catch (error) {
183
+ console.warn('res===offClarityChanged fail', error);
184
+ }
185
+ }
186
+
187
+ /**
188
+ * 监听自动清晰度变化,返回取消监听函数。
189
+ *
190
+ * onClarityChanged / offClarityChanged 均使用同一个 listener 引用,
191
+ * 否则宿主无法正确移除监听。
192
+ */
193
+ export function subscribeClarityChanged(devId, handler) {
194
+ var _ty7;
195
+ const ipc = typeof ty !== 'undefined' ? (_ty7 = ty) === null || _ty7 === void 0 ? void 0 : _ty7.ipc : undefined;
196
+ if (!ipc || typeof ipc.onClarityChanged !== 'function') {
197
+ return () => undefined;
198
+ }
199
+ const listener = payload => {
200
+ console.log('[resolution] onClarityChanged 事件到达', JSON.stringify(payload !== null && payload !== void 0 ? payload : null));
201
+ const {
202
+ deviceId,
203
+ clarity
204
+ } = payload || {};
205
+ if (!Object.values(ClarityType).includes(clarity)) {
206
+ console.warn('[resolution] onClarityChanged 缺少 clarity');
178
207
  return;
179
208
  }
180
- if (!isClarityChangedSupported()) {
181
- resolve(null);
209
+ // 一页多设备时只认自己的;宿主没带 deviceId 就不过滤
210
+ if (deviceId && deviceId !== devId) {
211
+ console.warn('[resolution] onClarityChanged 非本设备,已忽略', `${deviceId} != ${devId}`);
182
212
  return;
183
213
  }
184
- try {
185
- ty.ipc.clarityChanged({
186
- devId,
187
- success: res => {
188
- resolve(res !== null && res !== void 0 ? res : null);
189
- },
190
- fail: e => {
191
- console.warn('res===clarityChanged fail', e);
192
- resolve(null);
193
- }
194
- });
195
- } catch (e) {
196
- resolve(null);
197
- }
198
- });
214
+ handler({
215
+ deviceId,
216
+ clarity
217
+ });
218
+ };
219
+ try {
220
+ ipc.onClarityChanged(listener);
221
+ } catch (error) {
222
+ console.warn('res===onClarityChanged fail', error);
223
+ return () => undefined;
224
+ }
225
+ return () => {
226
+ offClarityChanged(listener);
227
+ };
199
228
  }
@@ -5,7 +5,7 @@ import { Image, Text, View } from '@ray-js/ray';
5
5
  import clsx from 'clsx';
6
6
  import Strings from '../../i18n';
7
7
  import './captureResult.less';
8
- const THUMBNAIL_LAYERS = ['back', 'middle', 'front'];
8
+ const BACKDROP_LAYERS = ['back', 'middle'];
9
9
  const TEXT_KEYS = {
10
10
  record: {
11
11
  check: 'ipc_player_record_success_check',
@@ -55,18 +55,17 @@ export function CaptureResultToast(_ref) {
55
55
  const textKeys = TEXT_KEYS[kind];
56
56
  const legacyCls = LEGACY_CLASS_MAP[kind];
57
57
  const imageClassName = clsx('ipc-player-plugin-capture-result-image', legacyCls.image);
58
+ const backdropLayers = BACKDROP_LAYERS.slice(-Math.min(count - 1, BACKDROP_LAYERS.length));
58
59
  return /*#__PURE__*/React.createElement(View, {
59
60
  className: clsx('ipc-player-plugin-capture-result-toast', legacyCls.toast, className)
60
61
  }, /*#__PURE__*/React.createElement(View, {
61
62
  className: clsx('ipc-player-plugin-capture-result-image-box', legacyCls.imageBox, isMultiLens && ['ipc-player-plugin-capture-result-image-box-multi', legacyCls.imageBoxMulti])
62
- }, isMultiLens ? THUMBNAIL_LAYERS.slice(0, count).map((layer, index) => /*#__PURE__*/React.createElement(Image, {
63
+ }, isMultiLens ? /*#__PURE__*/React.createElement(React.Fragment, null, backdropLayers.map(layer => /*#__PURE__*/React.createElement(View, {
63
64
  key: layer,
64
- className: imageClassName,
65
- src: thumbnailPath,
66
- style: {
67
- left: `${index * 5}px`,
68
- zIndex: index + 1
69
- }
65
+ className: clsx('ipc-player-plugin-capture-result-backdrop', `ipc-player-plugin-capture-result-image-${layer}`)
66
+ })), /*#__PURE__*/React.createElement(Image, {
67
+ className: clsx(imageClassName, 'ipc-player-plugin-capture-result-image-front'),
68
+ src: thumbnailPath
70
69
  })) : /*#__PURE__*/React.createElement(Image, {
71
70
  className: imageClassName,
72
71
  src: thumbnailPath
@@ -29,17 +29,47 @@
29
29
  object-fit: cover;
30
30
  }
31
31
 
32
- .ipc-player-plugin-capture-result-image-box-multi .ipc-player-plugin-capture-result-image,
33
- .ipc-player-plugin-record-success-toast-image-box-multi .ipc-player-plugin-record-success-toast-image,
34
- .ipc-player-plugin-screenshot-toast-image-box-multi .ipc-player-plugin-screenshot-toast-image {
32
+ .ipc-player-plugin-capture-result-image-box-multi,
33
+ .ipc-player-plugin-record-success-toast-image-box-multi,
34
+ .ipc-player-plugin-screenshot-toast-image-box-multi {
35
+ height: calc(39px * var(--ipc-player-size-scale, 1));
36
+ }
37
+
38
+ .ipc-player-plugin-capture-result-backdrop,
39
+ .ipc-player-plugin-capture-result-image-front {
35
40
  position: absolute;
36
- top: 0;
37
- width: calc(56px * var(--ipc-player-size-scale, 1));
38
41
  box-sizing: border-box;
39
- border: 1px solid var(--shot-card-bg-color);
40
42
  border-radius: calc(4px * var(--ipc-player-size-scale, 1));
41
43
  }
42
44
 
45
+ .ipc-player-plugin-capture-result-backdrop {
46
+ background: rgba(255, 255, 255, 0.2);
47
+ }
48
+
49
+ .ipc-player-plugin-capture-result-image-back {
50
+ top: 0;
51
+ left: calc(7px * var(--ipc-player-size-scale, 1));
52
+ z-index: 1;
53
+ width: calc(52px * var(--ipc-player-size-scale, 1));
54
+ height: calc(28px * var(--ipc-player-size-scale, 1));
55
+ }
56
+
57
+ .ipc-player-plugin-capture-result-image-middle {
58
+ top: calc(3px * var(--ipc-player-size-scale, 1));
59
+ left: calc(2.5px * var(--ipc-player-size-scale, 1));
60
+ z-index: 2;
61
+ width: calc(61px * var(--ipc-player-size-scale, 1));
62
+ height: calc(30.5px * var(--ipc-player-size-scale, 1));
63
+ }
64
+
65
+ .ipc-player-plugin-capture-result-image-front {
66
+ top: calc(6px * var(--ipc-player-size-scale, 1));
67
+ left: 0;
68
+ z-index: 3;
69
+ width: calc(66px * var(--ipc-player-size-scale, 1));
70
+ height: calc(33px * var(--ipc-player-size-scale, 1));
71
+ }
72
+
43
73
  .ipc-player-plugin-capture-result-play-icon-box,
44
74
  .ipc-player-plugin-record-success-play-icon-box {
45
75
  position: absolute;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,79 @@
1
+ import React from 'react';
2
+ import { renderToStaticMarkup } from 'react-dom/server';
3
+ jest.mock('@ray-js/ray', () => {
4
+ const React = require('react');
5
+ return {
6
+ Image: _ref => {
7
+ let {
8
+ className,
9
+ src
10
+ } = _ref;
11
+ return /*#__PURE__*/React.createElement("img", {
12
+ alt: "",
13
+ className: className,
14
+ src: src
15
+ });
16
+ },
17
+ Text: _ref2 => {
18
+ let {
19
+ children,
20
+ className
21
+ } = _ref2;
22
+ return /*#__PURE__*/React.createElement("span", {
23
+ className: className
24
+ }, children);
25
+ },
26
+ View: _ref3 => {
27
+ let {
28
+ children,
29
+ className
30
+ } = _ref3;
31
+ return /*#__PURE__*/React.createElement("div", {
32
+ className: className
33
+ }, children);
34
+ }
35
+ };
36
+ });
37
+ jest.mock('../../i18n', () => ({
38
+ __esModule: true,
39
+ default: {
40
+ getLang: key => key,
41
+ formatString: (template, count) => `${template}:${count}`
42
+ }
43
+ }));
44
+ jest.mock('./captureResult.less', () => ({}));
45
+ const {
46
+ CaptureResultToast
47
+ } = require('./captureResult');
48
+ const renderToast = count => renderToStaticMarkup(/*#__PURE__*/React.createElement(CaptureResultToast, {
49
+ brandColor: "#ff592a",
50
+ count: count,
51
+ kind: "screenshot",
52
+ onCheck: () => undefined,
53
+ thumbnailPath: "thingfile://capture.jpg"
54
+ }));
55
+ const countClass = (markup, className) => [...markup.matchAll(/class="([^"]*)"/g)].filter(_ref4 => {
56
+ let [, names] = _ref4;
57
+ return names.split(/\s+/).includes(className);
58
+ }).length;
59
+ describe('CaptureResultToast', () => {
60
+ it('keeps the single-item thumbnail unchanged', () => {
61
+ const markup = renderToast(1);
62
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(0);
63
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(0);
64
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image')).toBe(1);
65
+ });
66
+ it('renders one backdrop for two captured items', () => {
67
+ const markup = renderToast(2);
68
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(1);
69
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-middle')).toBe(1);
70
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(1);
71
+ });
72
+ it('caps the backdrop count at two', () => {
73
+ const markup = renderToast(4);
74
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-backdrop')).toBe(2);
75
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-back')).toBe(1);
76
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-middle')).toBe(1);
77
+ expect(countClass(markup, 'ipc-player-plugin-capture-result-image-front')).toBe(1);
78
+ });
79
+ });
@@ -117,7 +117,11 @@ export function RecordVideo(props) {
117
117
  var _props$multiCameraCtx;
118
118
  const requestId = ++recordResultRequestIdRef.current;
119
119
  const splitNum = (_props$multiCameraCtx = props.multiCameraCtx) === null || _props$multiCameraCtx === void 0 || (_props$multiCameraCtx = _props$multiCameraCtx.protocol) === null || _props$multiCameraCtx === void 0 ? void 0 : _props$multiCameraCtx.total_split_num;
120
- const summary = await getCaptureResultSummary(recordInfo, splitNum, devId);
120
+ const summary = await getCaptureResultSummary(recordInfo, {
121
+ multiLens: props.multiLens,
122
+ protocolCount: splitNum,
123
+ devId
124
+ });
121
125
  if (requestId !== recordResultRequestIdRef.current) return;
122
126
  if (!summary) return;
123
127
  setState({
@@ -9,7 +9,7 @@ import { FullResolutionControl } from './fullResolutionControl';
9
9
  import { fullResolutionId, pauseTimeToHideAllComponent, hideAllComponent, widgetLabs, widgetClick, autoClarityChange } from '../../ui/constant';
10
10
  import { UIEventContext } from '../../ui/context';
11
11
  import { useStore } from '../../ctx/store';
12
- import { clarityChanged } from '../../utils/ttt';
12
+ import { subscribeClarityChanged } from '../../utils/ttt';
13
13
  import './resolution.less';
14
14
  export const Resolution = props => {
15
15
  const {
@@ -33,7 +33,7 @@ export const Resolution = props => {
33
33
  } = useContext(UIEventContext);
34
34
 
35
35
  // 广播自动清晰度状态给 VideoBitKBP 等监听方;
36
- // 自动模式下读取一次当前实际清晰度,仅用于码率区域展示。
36
+ // 自动模式下监听当前实际清晰度,仅用于码率区域展示。
37
37
  useEffect(() => {
38
38
  const emitClarity = (enabled, clarity) => {
39
39
  event.emit(autoClarityChange, {
@@ -43,18 +43,14 @@ export const Resolution = props => {
43
43
  };
44
44
  if (resolution !== ClarityType.AUTO) {
45
45
  emitClarity(false, null);
46
- return;
46
+ return undefined;
47
47
  }
48
48
  emitClarity(true, null);
49
- if (devId) {
50
- clarityChanged(devId).then(res => {
51
- if (res !== null && res !== void 0 && res.clarity) {
52
- emitClarity(true, res.clarity);
53
- }
54
- });
55
- }
56
- // eslint-disable-next-line react-hooks/exhaustive-deps
57
- }, [devId, resolution]);
49
+ if (!devId) return undefined;
50
+ return subscribeClarityChanged(devId, res => {
51
+ emitClarity(true, res.clarity);
52
+ });
53
+ }, [devId, event, resolution]);
58
54
  const onResolution = useMemoizedFn(() => {
59
55
  event.emit(widgetClick, {
60
56
  widgetId: widgetLabs.RESOLUTION
@@ -139,7 +139,11 @@ export function Screenshot(props) {
139
139
  var _props$multiCameraCtx;
140
140
  setIgnoreHideStopPreview(false);
141
141
  const splitNum = (_props$multiCameraCtx = props.multiCameraCtx) === null || _props$multiCameraCtx === void 0 || (_props$multiCameraCtx = _props$multiCameraCtx.protocol) === null || _props$multiCameraCtx === void 0 ? void 0 : _props$multiCameraCtx.total_split_num;
142
- const summary = await getCaptureResultSummary(res, splitNum, devId);
142
+ const summary = await getCaptureResultSummary(res, {
143
+ multiLens: props.multiLens,
144
+ protocolCount: splitNum,
145
+ devId
146
+ });
143
147
  if (requestId !== snapshotRequestIdRef.current) return;
144
148
  if (!summary) {
145
149
  handleSnapshotFail({});
@@ -29,7 +29,6 @@ export const VideoBitKBP = props => {
29
29
  event
30
30
  } = useContext(UIEventContext);
31
31
  const timerRef = useRef();
32
-
33
32
  // 监听 Resolution 控件广播的自动清晰度状态
34
33
  useEffect(() => {
35
34
  const onAutoClarityChange = payload => {
@@ -103,7 +102,26 @@ export const VideoBitKBP = props => {
103
102
  className: "ipc-player-plugin-videoBitKBP-kbps"
104
103
  }, autoClarity && /*#__PURE__*/React.createElement(Text, {
105
104
  className: "ipc-player-plugin-videoBitKBP-clarity"
106
- }, autoClarity === 'HD' ? Strings.getLang('ipc_player_resolution_HD') : Strings.getLang('ipc_player_resolution_SD')), /*#__PURE__*/React.createElement(Text, null, bitKBP), /*#__PURE__*/React.createElement(Text, {
105
+ }, (clarity => {
106
+ switch (clarity) {
107
+ case ClarityType.SS:
108
+ return Strings.getLang('ipc_player_resolution_SS');
109
+ case ClarityType.SD:
110
+ return Strings.getLang('ipc_player_resolution_SD');
111
+ case ClarityType.HD:
112
+ return Strings.getLang('ipc_player_resolution_HD');
113
+ case ClarityType.UD:
114
+ return Strings.getLang('ipc_player_resolution_UD');
115
+ case ClarityType.SSP:
116
+ return Strings.getLang('ipc_player_resolution_SSP');
117
+ case ClarityType.AUTO:
118
+ return Strings.getLang('ipc_player_resolution_AUTO');
119
+ case ClarityType.AUDIO:
120
+ return Strings.getLang('ipc_player_resolution_AUDIO');
121
+ default:
122
+ return clarity;
123
+ }
124
+ })(autoClarity)), /*#__PURE__*/React.createElement(Text, null, bitKBP), /*#__PURE__*/React.createElement(Text, {
107
125
  className: "ipc-player-plugin-videoBitKBP-unit-kbs"
108
126
  }, "KB/S"))));
109
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.53-beta.1",
3
+ "version": "0.0.53-beta.3",
4
4
  "description": "IPC 融合播放器",
5
5
  "main": "lib/index",
6
6
  "files": [