trtc-electron-sdk 12.2.115-beta.7 → 12.2.115-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/liteav/MediaMixingDesigner/index.js +30 -13
  2. package/liteav/constant.d.ts +1 -0
  3. package/liteav/constant.js +4 -0
  4. package/liteav/extensions/MediaMixingManager/StreamLayout/BaseStreamLayoutManager.d.ts +27 -0
  5. package/liteav/extensions/MediaMixingManager/StreamLayout/BaseStreamLayoutManager.js +99 -0
  6. package/liteav/extensions/MediaMixingManager/StreamLayout/CustomStreamLayoutManager.d.ts +8 -12
  7. package/liteav/extensions/MediaMixingManager/StreamLayout/CustomStreamLayoutManager.js +101 -18
  8. package/liteav/extensions/MediaMixingManager/StreamLayout/NoneStreamLayoutManager.d.ts +7 -12
  9. package/liteav/extensions/MediaMixingManager/StreamLayout/NoneStreamLayoutManager.js +9 -18
  10. package/liteav/extensions/MediaMixingManager/StreamLayout/index.d.ts +2 -2
  11. package/liteav/extensions/MediaMixingManager/StreamLayout/index.js +3 -11
  12. package/liteav/extensions/MediaMixingManager/StreamLayout/types.d.ts +12 -4
  13. package/liteav/extensions/MediaMixingManager/index.d.ts +1 -1
  14. package/liteav/extensions/MediaMixingManager/index.js +13 -19
  15. package/liteav/extensions/MediaMixingManager/types.d.ts +16 -4
  16. package/liteav/extensions/MediaMixingManager/types.js +0 -2
  17. package/liteav/utils.d.ts +27 -0
  18. package/liteav/utils.js +85 -1
  19. package/package.json +1 -1
  20. package/liteav/extensions/MediaMixingManager/StreamLayout/FloatStreamLayoutManager.d.ts +0 -15
  21. package/liteav/extensions/MediaMixingManager/StreamLayout/FloatStreamLayoutManager.js +0 -36
  22. package/liteav/extensions/MediaMixingManager/StreamLayout/GridStreamLayoutManager.d.ts +0 -15
  23. package/liteav/extensions/MediaMixingManager/StreamLayout/GridStreamLayoutManager.js +0 -36
@@ -225,10 +225,10 @@ class TRTCMediaMixingDesigner {
225
225
  }
226
226
  updateOverlay() {
227
227
  if (this.moveAndResizeOverlay) {
228
- let left = `${this.absoluteWorkingArea.left + this.previewLeft}px`;
229
- let top = `${this.absoluteWorkingArea.top + this.previewTop}px`;
230
- let width = '0px';
231
- let height = '0px';
228
+ let left = this.absoluteWorkingArea.left + this.previewLeft;
229
+ let top = this.absoluteWorkingArea.top + this.previewTop;
230
+ let width = 0;
231
+ let height = 0;
232
232
  if (this.selectedMediaIndex >= 0) {
233
233
  logger_1.default.debug(`${this.logPrefix}updateOverlay: selected media:`, this.mediaList[this.selectedMediaIndex].rect);
234
234
  const selectedPreviewRect = {
@@ -237,16 +237,33 @@ class TRTCMediaMixingDesigner {
237
237
  right: this.mediaList[this.selectedMediaIndex].rect.right * this.previewScale,
238
238
  bottom: this.mediaList[this.selectedMediaIndex].rect.bottom * this.previewScale
239
239
  };
240
- left = `${this.absoluteWorkingArea.left + this.previewLeft + selectedPreviewRect.left}px`;
241
- top = `${this.absoluteWorkingArea.top + this.previewTop + selectedPreviewRect.top}px`;
242
- width = `${selectedPreviewRect.right - selectedPreviewRect.left}px`;
243
- height = `${selectedPreviewRect.bottom - selectedPreviewRect.top}px`;
240
+ left = this.absoluteWorkingArea.left + this.previewLeft + selectedPreviewRect.left;
241
+ top = this.absoluteWorkingArea.top + this.previewTop + selectedPreviewRect.top;
242
+ width = selectedPreviewRect.right - selectedPreviewRect.left;
243
+ height = selectedPreviewRect.bottom - selectedPreviewRect.top;
244
244
  }
245
- this.moveAndResizeOverlay.style.left = left;
246
- this.moveAndResizeOverlay.style.top = top;
247
- this.moveAndResizeOverlay.style.width = width;
248
- this.moveAndResizeOverlay.style.height = height;
249
- logger_1.default.debug(`${this.logPrefix}updateOverlay: ${left} ${top} ${width} ${height}`);
245
+ let renderScale = 1;
246
+ if (this.container) {
247
+ const containerLayoutWidth = this.container.offsetWidth;
248
+ const containerRenderWidth = Math.round(this.container.getBoundingClientRect().width);
249
+ if (containerLayoutWidth !== containerRenderWidth) {
250
+ logger_1.default.warn(`${this.logPrefix}updateOverlay container layout width: ${containerLayoutWidth} container render width: ${containerRenderWidth}`);
251
+ renderScale = containerRenderWidth / containerLayoutWidth;
252
+ }
253
+ }
254
+ this.moveAndResizeOverlay.style.left = `${left}px`;
255
+ this.moveAndResizeOverlay.style.top = `${top}px`;
256
+ this.moveAndResizeOverlay.style.width = `${width}px`;
257
+ this.moveAndResizeOverlay.style.height = `${height}px`;
258
+ if (renderScale !== 1) {
259
+ this.moveAndResizeOverlay.style.transform = `scale(${1 / renderScale})`;
260
+ this.moveAndResizeOverlay.style.transformOrigin = `-${left}px -${top}px`; // Why?
261
+ }
262
+ else {
263
+ this.moveAndResizeOverlay.style.transform = 'none';
264
+ this.moveAndResizeOverlay.style.transformOrigin = 'none';
265
+ }
266
+ logger_1.default.debug(`${this.logPrefix}updateOverlay: ${left} ${top} ${width} ${height} ${renderScale}`);
250
267
  }
251
268
  }
252
269
  onMove(left, top) {
@@ -0,0 +1 @@
1
+ export declare const LOCAL_USER_ID = "";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LOCAL_USER_ID = void 0;
4
+ exports.LOCAL_USER_ID = '';
@@ -0,0 +1,27 @@
1
+ import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
2
+ import { ITRTCStreamLayoutManager, INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
3
+ declare class BaseStreamLayoutManager implements ITRTCStreamLayoutManager {
4
+ protected logPrefix: string;
5
+ protected nativeStreamLayoutManager: INativeStreamLayoutManager;
6
+ protected layout: TRTCStreamLayout;
7
+ protected context: TRTCStreamLayoutContext | null;
8
+ protected container: HTMLElement | null;
9
+ protected displayArea: {
10
+ left: number;
11
+ top: number;
12
+ right: number;
13
+ bottom: number;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ protected resizeObserver: ResizeObserver | null;
18
+ constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
19
+ setLayout(layout: TRTCStreamLayout): void;
20
+ getLayoutMode(): TRTCStreamLayoutMode;
21
+ destroy(): void;
22
+ protected refreshLayout(): void;
23
+ private onResize;
24
+ private setResizeObserver;
25
+ private updateDisplayArea;
26
+ }
27
+ export default BaseStreamLayoutManager;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const types_1 = require("../types");
7
+ const utils_1 = require("../../../utils");
8
+ const logger_1 = __importDefault(require("../../../logger"));
9
+ class BaseStreamLayoutManager {
10
+ constructor(nativeStreamLayoutManager, context) {
11
+ this.logPrefix = "[BaseStreamLayoutManager]";
12
+ this.container = null;
13
+ this.displayArea = {
14
+ left: 0,
15
+ top: 0,
16
+ right: 0,
17
+ bottom: 0,
18
+ width: 0,
19
+ height: 0,
20
+ };
21
+ this.resizeObserver = null;
22
+ this.nativeStreamLayoutManager = nativeStreamLayoutManager;
23
+ this.layout = {
24
+ layoutMode: types_1.TRTCStreamLayoutMode.None,
25
+ };
26
+ this.context = context;
27
+ this.container = context.container;
28
+ this.onResize = (0, utils_1.debounce)(this.onResize.bind(this), 100);
29
+ if (this.container) {
30
+ this.setResizeObserver();
31
+ this.updateDisplayArea();
32
+ }
33
+ else {
34
+ logger_1.default.warn(`${this.logPrefix}constructor failed, no context.container.`);
35
+ }
36
+ }
37
+ setLayout(layout) {
38
+ this.layout = layout;
39
+ this.refreshLayout();
40
+ }
41
+ getLayoutMode() {
42
+ return this.layout.layoutMode;
43
+ }
44
+ destroy() {
45
+ this.layout = {
46
+ layoutMode: types_1.TRTCStreamLayoutMode.None,
47
+ };
48
+ this.container = null;
49
+ this.context = null;
50
+ if (this.resizeObserver) {
51
+ this.resizeObserver.disconnect();
52
+ this.resizeObserver = null;
53
+ }
54
+ }
55
+ refreshLayout() {
56
+ logger_1.default.warn(`${this.logPrefix}refreshLayout should be implemented by sub-class.`);
57
+ }
58
+ onResize(entries) {
59
+ logger_1.default.log(`${this.logPrefix}onResize entries:`, entries);
60
+ for (const entry of entries) {
61
+ if (entry.target === this.container) {
62
+ logger_1.default.debug(`${this.logPrefix}onResize:`, this.container.getBoundingClientRect());
63
+ this.updateDisplayArea();
64
+ this.refreshLayout();
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ setResizeObserver() {
70
+ logger_1.default.debug(`${this.logPrefix}setResizeObserver container:`, this.container, ' resizeObserver:', this.resizeObserver);
71
+ if (this.resizeObserver) {
72
+ this.resizeObserver.disconnect();
73
+ }
74
+ if (this.container) {
75
+ this.resizeObserver = new ResizeObserver(this.onResize);
76
+ this.resizeObserver.observe(this.container);
77
+ }
78
+ else {
79
+ logger_1.default.warn(`${this.logPrefix}setResizeObserver failed, container is null.`);
80
+ }
81
+ }
82
+ updateDisplayArea() {
83
+ if (this.container) {
84
+ const containerRect = this.container.getBoundingClientRect();
85
+ this.displayArea = {
86
+ left: containerRect.left,
87
+ top: containerRect.top,
88
+ right: containerRect.right,
89
+ bottom: containerRect.bottom,
90
+ width: containerRect.width,
91
+ height: containerRect.height,
92
+ };
93
+ }
94
+ else {
95
+ logger_1.default.warn(`${this.logPrefix}updateDisplayArea failed, no container.`);
96
+ }
97
+ }
98
+ }
99
+ exports.default = BaseStreamLayoutManager;
@@ -1,15 +1,11 @@
1
- import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
2
- import { ITRTCStreamLayoutManager, INativeStreamLayoutManager } from "./types";
3
- declare class CustomStreamLayoutManager implements ITRTCStreamLayoutManager {
4
- private logPrefix;
5
- private layoutMode;
6
- private nativeStreamLayoutManager;
7
- private layout;
8
- private context;
9
- constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context?: Record<string, any>);
1
+ import BaseStreamLayoutManager from "./BaseStreamLayoutManager";
2
+ import { TRTCStreamLayout } from "../types";
3
+ import { INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
4
+ declare class CustomStreamLayoutManager extends BaseStreamLayoutManager {
5
+ protected logPrefix: string;
6
+ constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
10
7
  setLayout(layout: TRTCStreamLayout): void;
11
- getLayoutMode(): TRTCStreamLayoutMode;
12
- setContext(context: Record<string, any>): void;
13
- destroy(): void;
8
+ protected refreshLayout(): void;
9
+ private convertRelativeToAbsolute;
14
10
  }
15
11
  export default CustomStreamLayoutManager;
@@ -3,34 +3,117 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const BaseStreamLayoutManager_1 = __importDefault(require("./BaseStreamLayoutManager"));
6
7
  const types_1 = require("../types");
8
+ const trtc_define_1 = require("../../../trtc_define");
7
9
  const logger_1 = __importDefault(require("../../../logger"));
8
- class CustomStreamLayoutManager {
10
+ const constant_1 = require("../../../constant");
11
+ class CustomStreamLayoutManager extends BaseStreamLayoutManager_1.default {
9
12
  constructor(nativeStreamLayoutManager, context) {
13
+ super(nativeStreamLayoutManager, context);
10
14
  this.logPrefix = "[TRTCCustomStreamLayoutManager]";
11
- this.layoutMode = types_1.TRTCStreamLayoutMode.Custom;
12
- this.nativeStreamLayoutManager = nativeStreamLayoutManager;
13
- this.layout = null;
14
- this.context = context;
15
+ this.layout = {
16
+ layoutMode: types_1.TRTCStreamLayoutMode.Custom,
17
+ };
15
18
  }
16
19
  setLayout(layout) {
17
- this.layout = layout;
18
- if (layout.userList) {
19
- this.nativeStreamLayoutManager.setStreamLayout(layout.userList);
20
+ this.layout = Object.assign(Object.assign({}, layout), { layoutMode: types_1.TRTCStreamLayoutMode.Custom });
21
+ this.refreshLayout();
22
+ }
23
+ refreshLayout() {
24
+ var _a;
25
+ if (this.layout.userList) {
26
+ this.nativeStreamLayoutManager.setStreamLayout(this.layout.userList);
27
+ }
28
+ else if (this.layout.size && this.layout.streams) {
29
+ const userList = this.convertRelativeToAbsolute(this.layout);
30
+ if (userList) {
31
+ logger_1.default.debug(`${this.logPrefix}refreshLayout userList:`, userList);
32
+ const localUser = userList.filter(user => user.userId === constant_1.LOCAL_USER_ID)[0];
33
+ if ((localUser === null || localUser === void 0 ? void 0 : localUser.rect) && ((_a = this.context) === null || _a === void 0 ? void 0 : _a.mediaMixingDesigner)) {
34
+ const workingArea = localUser.rect;
35
+ this.context.mediaMixingDesigner.setWorkingArea({
36
+ left: workingArea.left / this.displayArea.width,
37
+ top: workingArea.top / this.displayArea.height,
38
+ right: workingArea.right / this.displayArea.width,
39
+ bottom: workingArea.bottom / this.displayArea.height,
40
+ }, localUser.fillMode);
41
+ }
42
+ userList.forEach(user => {
43
+ if (user.rect) {
44
+ user.rect = {
45
+ left: user.rect.left * window.devicePixelRatio,
46
+ right: user.rect.right * window.devicePixelRatio,
47
+ top: user.rect.top * window.devicePixelRatio,
48
+ bottom: user.rect.bottom * window.devicePixelRatio,
49
+ };
50
+ }
51
+ });
52
+ logger_1.default.debug(`${this.logPrefix}refreshLayout transfer layout to pixel unit::`, userList);
53
+ this.nativeStreamLayoutManager.setStreamLayout(userList);
54
+ }
55
+ else {
56
+ logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter, no 'streams' or 'size'`, JSON.stringify(this.layout));
57
+ }
20
58
  }
21
59
  else {
22
- logger_1.default.error(`${this.logPrefix}setLayout invalid parameter, no 'userList'`);
60
+ logger_1.default.error(`${this.logPrefix}refreshLayout invalid parameter:`, JSON.stringify(this.layout));
23
61
  }
24
62
  }
25
- getLayoutMode() {
26
- return this.layoutMode;
27
- }
28
- setContext(context) {
29
- this.context = context;
30
- }
31
- destroy() {
32
- this.layout = null;
33
- this.context = null;
63
+ convertRelativeToAbsolute(serverMixingLayout) {
64
+ if (!serverMixingLayout.streams || !serverMixingLayout.size) {
65
+ return null;
66
+ }
67
+ // 1. calculate valid video content width and height
68
+ let minX = 1;
69
+ let minY = 1;
70
+ let maxX = 0;
71
+ let maxY = 0;
72
+ for (let i = 0; i < serverMixingLayout.streams.length; i++) {
73
+ const stream = serverMixingLayout.streams[i];
74
+ minX = Math.min(minX, stream.x);
75
+ minY = Math.min(minY, stream.y);
76
+ maxX = Math.max(maxX, stream.x + stream.w);
77
+ maxY = Math.max(maxY, stream.y + stream.h);
78
+ }
79
+ const xLength = maxX - minX;
80
+ const yLength = maxY - minY;
81
+ const contentWidth = xLength * serverMixingLayout.size.width;
82
+ const contentHeight = yLength * serverMixingLayout.size.height;
83
+ // 2. calculate fitting scale rate and fitting area
84
+ const scaleRate = Math.min(this.displayArea.width / contentWidth, this.displayArea.height / contentHeight);
85
+ const fittingArea = {
86
+ width: contentWidth * scaleRate,
87
+ height: contentHeight * scaleRate,
88
+ left: (this.displayArea.width - contentWidth * scaleRate) / 2,
89
+ top: (this.displayArea.height - contentHeight * scaleRate) / 2,
90
+ right: (this.displayArea.width + contentWidth * scaleRate) / 2,
91
+ bottom: (this.displayArea.height + contentHeight * scaleRate) / 2,
92
+ };
93
+ // 3. transfer relative coordinates to absolute coordinates
94
+ return serverMixingLayout.streams.map((stream, index, list) => {
95
+ // 3.1 cut left and top black area
96
+ // 3.2 transfer relative video ratio to valid video content ratio
97
+ // 3.3 fit valid video content to dispaying area, that is fitting area
98
+ const result = {
99
+ x: (stream.x - minX) / xLength * contentWidth * scaleRate + fittingArea.left,
100
+ y: (stream.y - minY) / yLength * contentHeight * scaleRate + fittingArea.top,
101
+ w: (stream.w) / xLength * contentWidth * scaleRate,
102
+ h: (stream.h) / yLength * contentHeight * scaleRate,
103
+ };
104
+ // 3.4 convert to TRTCStreamLayout.userList item
105
+ return {
106
+ userId: stream.userId,
107
+ fillMode: list.length >= 2 ? trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fill : trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fit,
108
+ zOrder: index,
109
+ rect: {
110
+ left: Math.round(result.x),
111
+ top: Math.round(result.y),
112
+ right: Math.round(result.x + result.w),
113
+ bottom: Math.round(result.y + result.h),
114
+ }
115
+ };
116
+ });
34
117
  }
35
118
  }
36
119
  exports.default = CustomStreamLayoutManager;
@@ -1,16 +1,11 @@
1
- import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
2
- import { ITRTCStreamLayoutManager, INativeStreamLayoutManager } from "./types";
3
- declare class NoneStreamLayoutManager implements ITRTCStreamLayoutManager {
4
- private logPrefix;
5
- private layoutMode;
6
- private nativeStreamLayoutManager;
7
- private layout;
8
- private context;
9
- constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context?: Record<string, any>);
1
+ import BaseStreamLayoutManager from "./BaseStreamLayoutManager";
2
+ import { TRTCStreamLayout } from "../types";
3
+ import { INativeStreamLayoutManager, TRTCStreamLayoutContext } from "./types";
4
+ declare class NoneStreamLayoutManager extends BaseStreamLayoutManager {
5
+ protected logPrefix: string;
6
+ constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext);
10
7
  setLayout(layout: TRTCStreamLayout): void;
11
- getLayoutMode(): TRTCStreamLayoutMode;
12
- setContext(context: Record<string, any>): void;
13
- destroy(): void;
8
+ protected refreshLayout(): void;
14
9
  private centerLiveOwner;
15
10
  }
16
11
  export default NoneStreamLayoutManager;
@@ -3,20 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const BaseStreamLayoutManager_1 = __importDefault(require("./BaseStreamLayoutManager"));
6
7
  const types_1 = require("../types");
7
8
  const trtc_define_1 = require("../../../trtc_define");
8
9
  const logger_1 = __importDefault(require("../../../logger"));
9
- class NoneStreamLayoutManager {
10
+ class NoneStreamLayoutManager extends BaseStreamLayoutManager_1.default {
10
11
  constructor(nativeStreamLayoutManager, context) {
12
+ super(nativeStreamLayoutManager, context);
11
13
  this.logPrefix = "[TRTCNoneStreamLayoutManager]";
12
- this.layoutMode = types_1.TRTCStreamLayoutMode.None;
13
- this.nativeStreamLayoutManager = nativeStreamLayoutManager;
14
- this.layout = null;
15
- this.context = context;
16
14
  }
17
15
  setLayout(layout) {
16
+ this.layout = Object.assign(Object.assign({}, layout), { layoutMode: types_1.TRTCStreamLayoutMode.None, userList: [] });
17
+ this.refreshLayout();
18
+ }
19
+ refreshLayout() {
18
20
  var _a;
19
- this.layout = layout || { layoutMode: types_1.TRTCStreamLayoutMode.None, userList: [] };
20
21
  if (this.context && this.layout.userList) {
21
22
  this.centerLiveOwner();
22
23
  (_a = this.nativeStreamLayoutManager) === null || _a === void 0 ? void 0 : _a.setStreamLayout(this.layout.userList);
@@ -25,20 +26,10 @@ class NoneStreamLayoutManager {
25
26
  logger_1.default.error(`${this.logPrefix}setLayout context is null or no user`);
26
27
  }
27
28
  }
28
- getLayoutMode() {
29
- return this.layoutMode;
30
- }
31
- setContext(context) {
32
- this.context = context;
33
- }
34
- destroy() {
35
- this.layout = null;
36
- this.context = null;
37
- }
38
29
  centerLiveOwner() {
39
30
  if (this.context && this.layout) {
40
- const layoutPixelWidth = this.context.layoutPixelRect.width;
41
- const layoutPixelHeight = this.context.layoutPixelRect.height;
31
+ const layoutPixelWidth = this.displayArea.width * window.devicePixelRatio;
32
+ const layoutPixelHeight = this.displayArea.height * window.devicePixelRatio;
42
33
  const mixingVideoWidth = this.context.mixingVideoSize.width;
43
34
  const mixingVideoHeight = this.context.mixingVideoSize.height;
44
35
  // Live Owner(local user)
@@ -1,7 +1,7 @@
1
1
  import { TRTCStreamLayoutMode } from '../types';
2
- import { ITRTCStreamLayoutManager, INativeStreamLayoutManager } from './types';
2
+ import { ITRTCStreamLayoutManager, INativeStreamLayoutManager, TRTCStreamLayoutContext } from './types';
3
3
  export * from './types';
4
- declare function create(layoutMode: TRTCStreamLayoutMode, nativeStreamLayoutManager: INativeStreamLayoutManager): ITRTCStreamLayoutManager;
4
+ declare function create(layoutMode: TRTCStreamLayoutMode, nativeStreamLayoutManager: INativeStreamLayoutManager, context: TRTCStreamLayoutContext): ITRTCStreamLayoutManager;
5
5
  export declare const StreamLayoutFactory: {
6
6
  create: typeof create;
7
7
  };
@@ -14,26 +14,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  };
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.StreamLayoutFactory = void 0;
17
- const FloatStreamLayoutManager_1 = __importDefault(require("./FloatStreamLayoutManager"));
18
- const GridStreamLayoutManager_1 = __importDefault(require("./GridStreamLayoutManager"));
19
17
  const CustomStreamLayoutManager_1 = __importDefault(require("./CustomStreamLayoutManager"));
20
18
  const NoneStreamLayoutManager_1 = __importDefault(require("./NoneStreamLayoutManager"));
21
19
  const types_1 = require("../types");
22
20
  __exportStar(require("./types"), exports);
23
- function create(layoutMode, nativeStreamLayoutManager) {
21
+ function create(layoutMode, nativeStreamLayoutManager, context) {
24
22
  let layoutManager;
25
23
  if (layoutMode === types_1.TRTCStreamLayoutMode.Custom) {
26
- layoutManager = new CustomStreamLayoutManager_1.default(nativeStreamLayoutManager);
27
- }
28
- else if (layoutMode === types_1.TRTCStreamLayoutMode.Float) {
29
- layoutManager = new FloatStreamLayoutManager_1.default(nativeStreamLayoutManager);
30
- }
31
- else if (layoutMode === types_1.TRTCStreamLayoutMode.Grid) {
32
- layoutManager = new GridStreamLayoutManager_1.default(nativeStreamLayoutManager);
24
+ layoutManager = new CustomStreamLayoutManager_1.default(nativeStreamLayoutManager, context);
33
25
  }
34
26
  else {
35
27
  // layoutMode === TRTCStreamLayoutMode.None
36
- layoutManager = new NoneStreamLayoutManager_1.default(nativeStreamLayoutManager);
28
+ layoutManager = new NoneStreamLayoutManager_1.default(nativeStreamLayoutManager, context);
37
29
  }
38
30
  return layoutManager;
39
31
  }
@@ -1,13 +1,21 @@
1
- import { TRTCStreamInfo, TRTCStreamLayout, TRTCStreamLayoutMode } from '../types';
1
+ import { TRTCUserStream, TRTCStreamLayout, TRTCStreamLayoutMode } from '../types';
2
+ import TRTCMediaMixingDesigner from '../../../MediaMixingDesigner';
2
3
  export interface INativeStreamLayoutManager {
3
- setStreamLayout: (streamList: Array<TRTCStreamInfo>) => void;
4
+ setStreamLayout: (streamList: Array<TRTCUserStream>) => void;
5
+ }
6
+ export interface TRTCStreamLayoutContext {
7
+ container: HTMLElement | null;
8
+ mixingVideoSize: {
9
+ width: number;
10
+ height: number;
11
+ };
12
+ mediaMixingDesigner: TRTCMediaMixingDesigner | null;
4
13
  }
5
14
  export interface ITRTCStreamLayoutManager {
6
15
  setLayout(layout: TRTCStreamLayout): void;
7
16
  getLayoutMode(): TRTCStreamLayoutMode;
8
17
  destroy(): void;
9
- setContext(context: Record<string, any>): void;
10
18
  }
11
19
  export interface ITRTCStreamLayoutEvent {
12
- onStreamLayoutChanged(streams: Array<TRTCStreamInfo>): void;
20
+ onStreamLayoutChanged(streams: Array<TRTCUserStream>): void;
13
21
  }
@@ -1,7 +1,7 @@
1
1
  import { TRTCCameraCaptureParams, Rect, TRTCScreenCaptureProperty } from '../../trtc_define';
2
2
  import { TRTCMediaSource, TRTCMediaMixingEncParam, ITRTCMediaMixingManager, TRTCPhoneMirrorParam, TRTCStreamLayout } from './types';
3
3
  import { TRTCDeviceManager } from '../DeviceManager';
4
- export { TRTCMediaMixingErrorCode, TRTCMediaSourceType, TRTCMediaSource, TRTCMediaMixingEncParam, TRTCPhoneMirrorParam, TRTCStreamLayoutMode, TRTCStreamInfo, TRTCStreamLayout } from './types';
4
+ export { TRTCMediaMixingErrorCode, TRTCMediaSourceType, TRTCMediaSource, TRTCMediaMixingEncParam, TRTCPhoneMirrorParam, TRTCStreamLayoutMode, TRTCUserStream, TRTCStreamInfo, TRTCStreamLayout } from './types';
5
5
  declare const NodeTRTCEngine: any;
6
6
  /**
7
7
  * @namespace TRTCMediaMixingEvent
@@ -16,6 +16,7 @@ exports.TRTCMediaMixingManager = exports.TRTCMediaMixingEvent = exports.TRTCStre
16
16
  const events_1 = require("events");
17
17
  const trtc_define_1 = require("../../trtc_define");
18
18
  const utils_1 = require("../../utils");
19
+ const constant_1 = require("../../constant");
19
20
  const logger_1 = __importDefault(require("../../logger"));
20
21
  const index_1 = __importDefault(require("../../MediaMixingDesigner/index"));
21
22
  const StreamLayout_1 = require("./StreamLayout");
@@ -146,7 +147,6 @@ const initResolutionMap = () => {
146
147
  return map;
147
148
  };
148
149
  const resolutionMap = initResolutionMap();
149
- const LOCAL_USER_ID = '';
150
150
  /**
151
151
  * @namespace TRTCMediaMixingEvent
152
152
  * @description 目前只支持 `Windows` 操作系统
@@ -653,32 +653,26 @@ class TRTCMediaMixingManager {
653
653
  setStreamLayout(layout) {
654
654
  var _a, _b;
655
655
  logger_1.default.log(`${this.logPrefix}setStreamLayout:`, layout);
656
+ const context = {
657
+ container: this.view,
658
+ mixingVideoSize: {
659
+ width: this.mixingVideoWidth,
660
+ height: this.mixingVideoHeight
661
+ },
662
+ mediaMixingDesigner: this.mediaMixingDesigner
663
+ };
656
664
  if (!this.streamLayoutManager) {
657
- this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin);
665
+ this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
658
666
  }
659
667
  else if (this.streamLayoutManager.getLayoutMode() !== layout.layoutMode) {
660
668
  this.streamLayoutManager.destroy();
661
- this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin);
669
+ this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
662
670
  }
663
671
  let transferredUserList = layout.userList;
664
672
  if (this.view) {
665
673
  const viewRect = this.view.getBoundingClientRect();
666
- this.streamLayoutManager.setContext({
667
- mixingVideoSize: {
668
- width: this.mixingVideoWidth,
669
- height: this.mixingVideoHeight
670
- },
671
- layoutPixelRect: {
672
- left: viewRect.left * window.devicePixelRatio,
673
- right: viewRect.right * window.devicePixelRatio,
674
- top: viewRect.top * window.devicePixelRatio,
675
- bottom: viewRect.bottom * window.devicePixelRatio,
676
- width: viewRect.width * window.devicePixelRatio,
677
- height: viewRect.height * window.devicePixelRatio
678
- }
679
- });
680
674
  if ((_a = layout.userList) === null || _a === void 0 ? void 0 : _a.length) {
681
- const localUser = layout.userList.filter(user => user.userId === LOCAL_USER_ID)[0];
675
+ const localUser = layout.userList.filter(user => user.userId === constant_1.LOCAL_USER_ID)[0];
682
676
  if (localUser === null || localUser === void 0 ? void 0 : localUser.rect) {
683
677
  const workingArea = localUser.rect;
684
678
  (_b = this.mediaMixingDesigner) === null || _b === void 0 ? void 0 : _b.setWorkingArea({
@@ -731,7 +725,7 @@ class TRTCMediaMixingManager {
731
725
  else {
732
726
  const { resourcesPath, execPath } = globalThis.process;
733
727
  if (execPath.endsWith('electron.exe')) {
734
- serverPath = '..\\..\\..\\..\\node_modules\\trtc-electron-sdk\\build\\Release\\liteav_media_server.exe';
728
+ serverPath = 'node_modules\\trtc-electron-sdk\\build\\Release\\liteav_media_server.exe';
735
729
  }
736
730
  else {
737
731
  serverPath = `${resourcesPath}\\liteav_media_server.exe`;
@@ -41,20 +41,32 @@ export declare type TRTCMediaMixingEncParam = {
41
41
  selectedBorderColor?: number | 0xFFFF00;
42
42
  };
43
43
  export declare enum TRTCStreamLayoutMode {
44
- Float = "Float",
45
- Grid = "Grid",
46
44
  Custom = "Custom",
47
45
  None = "None"
48
46
  }
49
- export declare type TRTCStreamInfo = {
47
+ export declare type TRTCUserStream = {
50
48
  userId: string;
51
49
  fillMode?: TRTCVideoFillMode;
52
50
  rect?: Rect;
53
51
  zOrder?: number;
54
52
  };
53
+ export declare type TRTCStreamInfo = {
54
+ userId: string;
55
+ x: number;
56
+ y: number;
57
+ w: number;
58
+ h: number;
59
+ zOrder?: number;
60
+ fillMode?: TRTCVideoFillMode;
61
+ };
55
62
  export declare type TRTCStreamLayout = {
56
63
  layoutMode: TRTCStreamLayoutMode;
57
- userList?: Array<TRTCStreamInfo>;
64
+ userList?: Array<TRTCUserStream>;
65
+ size?: {
66
+ width: number;
67
+ height: number;
68
+ };
69
+ streams?: Array<TRTCStreamInfo>;
58
70
  };
59
71
  export interface ITRTCMediaMixingManager {
60
72
  addMediaSource(mediaSource: TRTCMediaSource): Promise<Rect>;
@@ -21,8 +21,6 @@ var TRTCMediaSourceType;
21
21
  })(TRTCMediaSourceType = exports.TRTCMediaSourceType || (exports.TRTCMediaSourceType = {}));
22
22
  var TRTCStreamLayoutMode;
23
23
  (function (TRTCStreamLayoutMode) {
24
- TRTCStreamLayoutMode["Float"] = "Float";
25
- TRTCStreamLayoutMode["Grid"] = "Grid";
26
24
  TRTCStreamLayoutMode["Custom"] = "Custom";
27
25
  TRTCStreamLayoutMode["None"] = "None";
28
26
  })(TRTCStreamLayoutMode = exports.TRTCStreamLayoutMode || (exports.TRTCStreamLayoutMode = {}));
package/liteav/utils.d.ts CHANGED
@@ -8,3 +8,30 @@ export declare function isNullOrUndefined(val: unknown): boolean;
8
8
  */
9
9
  export declare function safelyParse(data: string): unknown | Array<any> | Record<string, any>;
10
10
  export declare function convertUint8ArrayToNumber(value: Uint8Array): number;
11
+ /**
12
+ * 防抖函数 (debounce)
13
+ *
14
+ * 适用场景:搜索框输入联想、窗口resize结束事件
15
+ *
16
+ * @param func 需要防抖的函数
17
+ * @param wait 等待时间(毫秒)
18
+ * @param immediate 是否立即执行第一次调用(true=立即执行,false=等待后执行)
19
+ * @returns 包装后的防抖函数
20
+ */
21
+ export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number, immediate?: boolean): (...args: Parameters<T>) => void;
22
+ /**
23
+ * 节流函数 (throttle)
24
+ *
25
+ * 适用场景:滚动事件、按钮防重复点击、鼠标移动事件
26
+ *
27
+ * @param func 需要节流的函数
28
+ * @param wait 等待时间(毫秒)
29
+ * @param options 配置选项
30
+ * leading: 是否执行第一次调用(true=执行,false=跳过)
31
+ * trailing: 是否执行最后一次调用(true=执行,false=跳过)
32
+ * @returns 包装后的节流函数
33
+ */
34
+ export declare function throttle<T extends (...args: any[]) => any>(func: T, wait: number, options?: {
35
+ leading?: boolean;
36
+ trailing?: boolean;
37
+ }): (...args: Parameters<T>) => void;
package/liteav/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertUint8ArrayToNumber = exports.safelyParse = exports.isNullOrUndefined = exports.isUndefined = exports.isNull = void 0;
3
+ exports.throttle = exports.debounce = exports.convertUint8ArrayToNumber = exports.safelyParse = exports.isNullOrUndefined = exports.isUndefined = exports.isNull = void 0;
4
4
  function isNull(val) {
5
5
  return val === null;
6
6
  }
@@ -47,3 +47,87 @@ function convertUint8ArrayToNumber(value) {
47
47
  return result;
48
48
  }
49
49
  exports.convertUint8ArrayToNumber = convertUint8ArrayToNumber;
50
+ /**
51
+ * 防抖函数 (debounce)
52
+ *
53
+ * 适用场景:搜索框输入联想、窗口resize结束事件
54
+ *
55
+ * @param func 需要防抖的函数
56
+ * @param wait 等待时间(毫秒)
57
+ * @param immediate 是否立即执行第一次调用(true=立即执行,false=等待后执行)
58
+ * @returns 包装后的防抖函数
59
+ */
60
+ function debounce(func, wait, immediate = false) {
61
+ let timeout = null;
62
+ let inWait = false; // 是否处于等待周期
63
+ return function (...args) {
64
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
65
+ const context = this;
66
+ // 每次调用都清除现有定时器
67
+ if (timeout)
68
+ clearTimeout(timeout);
69
+ if (immediate && !inWait) {
70
+ // 立即执行模式且不在等待期
71
+ func.apply(context, args);
72
+ inWait = true;
73
+ }
74
+ // 设置新定时器
75
+ timeout = setTimeout(() => {
76
+ inWait = false;
77
+ if (!immediate) {
78
+ // 非立即执行模式:执行最后一次调用
79
+ func.apply(context, args);
80
+ }
81
+ }, wait);
82
+ };
83
+ }
84
+ exports.debounce = debounce;
85
+ /**
86
+ * 节流函数 (throttle)
87
+ *
88
+ * 适用场景:滚动事件、按钮防重复点击、鼠标移动事件
89
+ *
90
+ * @param func 需要节流的函数
91
+ * @param wait 等待时间(毫秒)
92
+ * @param options 配置选项
93
+ * leading: 是否执行第一次调用(true=执行,false=跳过)
94
+ * trailing: 是否执行最后一次调用(true=执行,false=跳过)
95
+ * @returns 包装后的节流函数
96
+ */
97
+ function throttle(func, wait, options = {}) {
98
+ const { leading = true, trailing = true } = options;
99
+ let lastExecTime = 0;
100
+ let timer = null;
101
+ let savedContext = null, savedArgs = null;
102
+ // 实际执行函数
103
+ const execute = () => {
104
+ lastExecTime = Date.now();
105
+ timer = null;
106
+ if (savedContext !== null && savedArgs !== null) {
107
+ func.apply(savedContext, savedArgs);
108
+ }
109
+ };
110
+ return function (...args) {
111
+ savedContext = this;
112
+ savedArgs = args;
113
+ const now = Date.now();
114
+ // 计算距离上次执行的时间差
115
+ const sinceLast = now - lastExecTime;
116
+ const remaining = wait - sinceLast;
117
+ // 超时情况:立即执行(无论是否在等待期)
118
+ if (remaining <= 0 || remaining > wait) {
119
+ if (timer) {
120
+ clearTimeout(timer);
121
+ timer = null;
122
+ }
123
+ if (leading) {
124
+ execute();
125
+ }
126
+ }
127
+ else if (!timer && trailing) {
128
+ // 设置定时器执行尾部调用
129
+ timer = setTimeout(execute, remaining);
130
+ }
131
+ };
132
+ }
133
+ exports.throttle = throttle;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trtc-electron-sdk",
3
- "version": "12.2.115-beta.7",
3
+ "version": "12.2.115-beta.8",
4
4
  "description": "trtc electron sdk",
5
5
  "main": "./liteav/index.js",
6
6
  "types": "./liteav/index.d.ts",
@@ -1,15 +0,0 @@
1
- import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
2
- import { ITRTCStreamLayoutManager, INativeStreamLayoutManager } from "./types";
3
- declare class FloatStreamLayoutManager implements ITRTCStreamLayoutManager {
4
- private logPrefix;
5
- private layoutMode;
6
- private nativeStreamLayoutManager;
7
- private layout;
8
- private context;
9
- constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context?: Record<string, any>);
10
- setLayout(layout: TRTCStreamLayout): void;
11
- getLayoutMode(): TRTCStreamLayoutMode;
12
- setContext(context: Record<string, any>): void;
13
- destroy(): void;
14
- }
15
- export default FloatStreamLayoutManager;
@@ -1,36 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const types_1 = require("../types");
7
- const logger_1 = __importDefault(require("../../../logger"));
8
- class FloatStreamLayoutManager {
9
- constructor(nativeStreamLayoutManager, context) {
10
- this.logPrefix = "[TRTCFloatStreamLayoutManager]";
11
- this.layoutMode = types_1.TRTCStreamLayoutMode.Float;
12
- this.nativeStreamLayoutManager = nativeStreamLayoutManager;
13
- this.layout = null;
14
- this.context = context;
15
- }
16
- setLayout(layout) {
17
- this.layout = layout;
18
- if (layout.userList) {
19
- this.nativeStreamLayoutManager.setStreamLayout(layout.userList);
20
- }
21
- else {
22
- logger_1.default.error(`${this.logPrefix}setLayout invalid parameter, no 'userList'`);
23
- }
24
- }
25
- getLayoutMode() {
26
- return this.layoutMode;
27
- }
28
- setContext(context) {
29
- this.context = context;
30
- }
31
- destroy() {
32
- this.layout = null;
33
- this.context = null;
34
- }
35
- }
36
- exports.default = FloatStreamLayoutManager;
@@ -1,15 +0,0 @@
1
- import { TRTCStreamLayout, TRTCStreamLayoutMode } from "../types";
2
- import { ITRTCStreamLayoutManager, INativeStreamLayoutManager } from "./types";
3
- declare class GridStreamLayoutManager implements ITRTCStreamLayoutManager {
4
- private logPrefix;
5
- private layoutMode;
6
- private nativeStreamLayoutManager;
7
- private layout;
8
- private context;
9
- constructor(nativeStreamLayoutManager: INativeStreamLayoutManager, context?: Record<string, any>);
10
- setLayout(layout: TRTCStreamLayout): void;
11
- getLayoutMode(): TRTCStreamLayoutMode;
12
- setContext(context: Record<string, any>): void;
13
- destroy(): void;
14
- }
15
- export default GridStreamLayoutManager;
@@ -1,36 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const types_1 = require("../types");
7
- const logger_1 = __importDefault(require("../../../logger"));
8
- class GridStreamLayoutManager {
9
- constructor(nativeStreamLayoutManager, context) {
10
- this.logPrefix = "[TRTCGridStreamLayoutManager]";
11
- this.layoutMode = types_1.TRTCStreamLayoutMode.Grid;
12
- this.nativeStreamLayoutManager = nativeStreamLayoutManager;
13
- this.layout = null;
14
- this.context = context;
15
- }
16
- setLayout(layout) {
17
- this.layout = layout;
18
- if (layout.userList) {
19
- this.nativeStreamLayoutManager.setStreamLayout(layout.userList);
20
- }
21
- else {
22
- logger_1.default.error(`${this.logPrefix}setLayout invalid parameter, no 'userList'`);
23
- }
24
- }
25
- getLayoutMode() {
26
- return this.layoutMode;
27
- }
28
- setContext(context) {
29
- this.context = context;
30
- }
31
- destroy() {
32
- this.layout = null;
33
- this.context = null;
34
- }
35
- }
36
- exports.default = GridStreamLayoutManager;