trtc-electron-sdk 12.2.115-alpha.20 → 12.2.115-alpha.24

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.
@@ -3,7 +3,7 @@ export declare type TRTCMediaInfo = {
3
3
  id: string;
4
4
  rect: Rect;
5
5
  isSelected: boolean;
6
- zOrder?: number;
6
+ zOrder: number;
7
7
  origin: any;
8
8
  };
9
9
  declare class TRTCMediaMixingDesigner {
@@ -48,6 +48,7 @@ declare class TRTCMediaMixingDesigner {
48
48
  addMedia(media: TRTCMediaInfo): void;
49
49
  removeMedia(media: TRTCMediaInfo): void;
50
50
  updateMedia(media: TRTCMediaInfo): void;
51
+ removeAllMedia(): void;
51
52
  on(event: string, func: (...args: any[]) => void): void;
52
53
  off(event: string, func: (...args: any[]) => void): void;
53
54
  destroy(): void;
@@ -73,9 +73,23 @@ class TRTCMediaMixingDesigner {
73
73
  }
74
74
  }
75
75
  addMedia(media) {
76
- this.mediaList.unshift(media);
76
+ // sort by zOrder desc
77
+ const length = this.mediaList.length;
78
+ let insertIndex = -1;
79
+ for (let i = 0; i < length; i++) {
80
+ if (media.zOrder >= this.mediaList[i].zOrder) {
81
+ insertIndex = i;
82
+ break;
83
+ }
84
+ }
85
+ if (insertIndex >= 0) {
86
+ this.mediaList.splice(insertIndex, 0, media);
87
+ }
88
+ else {
89
+ this.mediaList.push(media);
90
+ }
77
91
  if (media.isSelected) {
78
- this.selectedMediaIndex = 0;
92
+ this.selectedMediaIndex = insertIndex >= 0 ? insertIndex : (this.mediaList.length - 1);
79
93
  this.updateOverlay();
80
94
  }
81
95
  }
@@ -90,15 +104,24 @@ class TRTCMediaMixingDesigner {
90
104
  }
91
105
  }
92
106
  updateMedia(media) {
93
- const targetIndex = this.mediaList.findIndex(item => item.id === media.id);
107
+ let targetIndex = this.mediaList.findIndex(item => item.id === media.id);
94
108
  if (targetIndex !== -1) {
109
+ const isZOrderChanged = media.zOrder !== this.mediaList[targetIndex].zOrder;
95
110
  this.mediaList[targetIndex] = Object.assign({}, this.mediaList[targetIndex], media);
111
+ if (isZOrderChanged) {
112
+ this.mediaList.sort((a, b) => b.zOrder - a.zOrder);
113
+ targetIndex = this.mediaList.findIndex(item => item.id === media.id);
114
+ }
96
115
  if (media.isSelected) {
97
116
  this.selectedMediaIndex = targetIndex;
98
117
  this.updateOverlay();
99
118
  }
100
119
  }
101
120
  }
121
+ removeAllMedia() {
122
+ this.mediaList = [];
123
+ this.selectedMediaIndex = -1;
124
+ }
102
125
  on(event, func) {
103
126
  var _a;
104
127
  (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.on(event, func);
@@ -0,0 +1,12 @@
1
+ declare class DevicePixelRatioObserver {
2
+ private mediaQueryString;
3
+ private mediaQuery;
4
+ private eventEmitter;
5
+ constructor();
6
+ destroy(): void;
7
+ on(event: string, func: (...args: any[]) => void): void;
8
+ off(event: string, func: (...args: any[]) => void): void;
9
+ private onPixelRatioChanged;
10
+ }
11
+ declare const devicePixelRationObserver: DevicePixelRatioObserver;
12
+ export default devicePixelRationObserver;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const events_1 = require("events");
4
+ class DevicePixelRatioObserver {
5
+ constructor() {
6
+ this.mediaQueryString = `(resolution: ${window.devicePixelRatio}dppx)`;
7
+ this.mediaQuery = window.matchMedia(this.mediaQueryString);
8
+ this.eventEmitter = new events_1.EventEmitter();
9
+ this.onPixelRatioChanged = this.onPixelRatioChanged.bind(this);
10
+ this.mediaQuery.addEventListener('change', this.onPixelRatioChanged);
11
+ }
12
+ destroy() {
13
+ var _a;
14
+ (_a = this.mediaQuery) === null || _a === void 0 ? void 0 : _a.removeEventListener('change', this.onPixelRatioChanged);
15
+ this.mediaQuery = null;
16
+ this.eventEmitter = null;
17
+ }
18
+ on(event, func) {
19
+ var _a;
20
+ (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.on(event, func);
21
+ }
22
+ off(event, func) {
23
+ var _a;
24
+ (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.off(event, func);
25
+ }
26
+ onPixelRatioChanged() {
27
+ var _a;
28
+ (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit('change');
29
+ }
30
+ }
31
+ const devicePixelRationObserver = new DevicePixelRatioObserver();
32
+ exports.default = devicePixelRationObserver;
@@ -234,6 +234,7 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
234
234
  * @returns {Promise<void>}
235
235
  */
236
236
  removeMediaSource(mediaSource: TRTCMediaSource): Promise<void>;
237
+ private syncRemoveMediaSource;
237
238
  /**
238
239
  * 更新本地混流媒体源
239
240
  * @param mediaSource {TRTCMediaSource} - 媒体源信息
@@ -373,6 +374,7 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
373
374
  * @returns {Promise<void>}
374
375
  */
375
376
  stopMediaMixingServer(): Promise<void>;
377
+ callExperimentalAPI(jsonStr: string): void;
376
378
  /**
377
379
  * 注册事件监听
378
380
  *
@@ -387,13 +389,14 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
387
389
  * @param func {Function} - 事件回调函数
388
390
  */
389
391
  off(event: TRTCMediaMixingEvent, func: (...args: any[]) => void): void;
390
- private initResizeObserver;
392
+ private createResizeObserver;
393
+ private destroyResizeObserver;
391
394
  private onPreviewAreaResize;
392
395
  private onVisibilityChange;
393
396
  private setDisplayRect;
394
397
  private createDesigner;
395
398
  private destroyDesigner;
396
- private createorUpdateLayoutManager;
399
+ private createOrUpdateLayoutManager;
397
400
  private destroyLayoutManager;
398
401
  private updateMixingVideoSize;
399
402
  private listenDesignerEvent;
@@ -409,13 +412,15 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
409
412
  private findSelectedMediaSource;
410
413
  private unselectMediaSource;
411
414
  private handleCppCallbackEvent;
412
- private onMediaSourceAddedOrRemoved;
415
+ private onMediaSourceAdded;
416
+ private onMediaSourceRemoved;
413
417
  private onMediaSourceSizeChanged;
414
418
  private onPhoneMirrorSourceChanged;
415
419
  private onMediaServerState;
416
420
  private onMediaMixingServerLost;
417
421
  private onCallExperimentalAPIFinish;
418
422
  private recoverMediaMixingServer;
423
+ private onDevicePixelRatioChange;
419
424
  startCameraDeviceTest(windowID: number | Uint8Array, rect?: Rect): Promise<number>;
420
425
  stopCameraDeviceTest(): Promise<number>;
421
426
  setCameraTestRenderMirror(mirror: boolean): void;
@@ -15,11 +15,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.TRTCMediaMixingManager = exports.TRTCMediaMixingEvent = void 0;
16
16
  const events_1 = require("events");
17
17
  const trtc_define_1 = require("../../trtc_define");
18
+ const types_1 = require("./types");
18
19
  const utils_1 = require("../../utils");
19
20
  const constant_1 = require("../../constant");
20
21
  const index_1 = __importDefault(require("../../MediaMixingDesigner/index"));
21
22
  const StreamLayout_1 = require("./StreamLayout");
22
23
  const PromiseStore_1 = __importDefault(require("../../base/PromiseStore"));
24
+ const DevicePixelRatioObserver_1 = __importDefault(require("../../base/DevicePixelRatioObserver"));
23
25
  const logger_1 = __importDefault(require("../../logger"));
24
26
  const NodeTRTCEngine = require('../../../build/Release/trtc_electron_sdk.node');
25
27
  /**
@@ -307,14 +309,15 @@ class TRTCMediaMixingManager {
307
309
  this.onPreviewAreaResize = this.onPreviewAreaResize.bind(this);
308
310
  this.onVisibilityChange = this.onVisibilityChange.bind(this);
309
311
  document.addEventListener('visibilitychange', this.onVisibilityChange);
312
+ this.onDevicePixelRatioChange = this.onDevicePixelRatioChange.bind(this);
313
+ DevicePixelRatioObserver_1.default.on('change', this.onDevicePixelRatioChange);
310
314
  }
311
315
  destroy() {
312
316
  return __awaiter(this, void 0, void 0, function* () {
317
+ DevicePixelRatioObserver_1.default.off('change', this.onDevicePixelRatioChange);
313
318
  document.removeEventListener('visibilitychange', this.onVisibilityChange);
314
- if (this.resizeObserver && this.view) {
315
- this.resizeObserver.unobserve(this.view);
316
- this.resizeObserver.disconnect();
317
- }
319
+ this.destroyResizeObserver();
320
+ this.destroyLayoutManager();
318
321
  this.view = null;
319
322
  this.windowID = 0;
320
323
  this.destroyDesigner();
@@ -448,7 +451,7 @@ class TRTCMediaMixingManager {
448
451
  this.destroyDesigner();
449
452
  this.view = viewOrRegion;
450
453
  this.setDisplayRect();
451
- this.initResizeObserver();
454
+ this.createResizeObserver();
452
455
  this.createDesigner();
453
456
  }
454
457
  else {
@@ -466,8 +469,10 @@ class TRTCMediaMixingManager {
466
469
  }
467
470
  }
468
471
  else {
472
+ this.destroyResizeObserver();
469
473
  this.destroyLayoutManager();
470
474
  this.destroyDesigner();
475
+ this.view = null;
471
476
  this.nodeMediaMixingPlugin.setDisplayParams(realWindowID, { left: 0, right: 0, top: 0, bottom: 0 });
472
477
  }
473
478
  }
@@ -480,7 +485,10 @@ class TRTCMediaMixingManager {
480
485
  logger_1.default.log(`${this.logPrefix}addMediaSource:`, mediaSource);
481
486
  const index = this.findMediaSourceIndex(mediaSource);
482
487
  if (index !== -1) {
483
- throw new Error("Media source already existed");
488
+ return Promise.reject({
489
+ code: types_1.TRTCMediaMixingErrorCode.InvalidParams,
490
+ message: "Media source already existed"
491
+ });
484
492
  }
485
493
  const newMediaSource = (0, utils_1.safelyParse)(JSON.stringify(mediaSource));
486
494
  if (newMediaSource.isSelected) {
@@ -498,6 +506,7 @@ class TRTCMediaMixingManager {
498
506
  id: `${newMediaSource.sourceType}__${newMediaSource.sourceId}`,
499
507
  rect: newMediaSource.rect,
500
508
  isSelected: newMediaSource.isSelected || false,
509
+ zOrder: newMediaSource.zOrder,
501
510
  origin: newMediaSource
502
511
  });
503
512
  this.sourceList.push(newMediaSource);
@@ -509,24 +518,46 @@ class TRTCMediaMixingManager {
509
518
  * @returns {Promise<void>}
510
519
  */
511
520
  removeMediaSource(mediaSource) {
521
+ var _a;
512
522
  logger_1.default.log(`${this.logPrefix}removeMediaSource:`, mediaSource);
513
523
  const index = this.findMediaSourceIndex(mediaSource);
514
524
  if (index === -1) {
515
- throw new Error("Not existing media source to remove");
525
+ return Promise.reject({
526
+ code: types_1.TRTCMediaMixingErrorCode.NotFoundSource,
527
+ message: "Not existing media source to remove"
528
+ });
516
529
  }
517
- return new Promise((resolve, reject) => {
518
- var _a;
519
- const key = `${promiseKeys.removeMediaSource}-${mediaSource.sourceType}-${mediaSource.sourceId}`;
520
- this.promiseStore.addPromise(key, resolve, reject);
530
+ else {
531
+ const mediaSourceToDelete = this.sourceList[index];
532
+ if ((_a = mediaSourceToDelete === null || mediaSourceToDelete === void 0 ? void 0 : mediaSourceToDelete.control) === null || _a === void 0 ? void 0 : _a.isAddFailed) {
533
+ this.syncRemoveMediaSource(mediaSource, index);
534
+ return Promise.resolve();
535
+ }
536
+ else {
537
+ return new Promise((resolve, reject) => {
538
+ const key = `${promiseKeys.removeMediaSource}-${mediaSource.sourceType}-${mediaSource.sourceId}`;
539
+ this.promiseStore.addPromise(key, resolve, reject);
540
+ this.syncRemoveMediaSource(mediaSource, index);
541
+ });
542
+ }
543
+ }
544
+ }
545
+ syncRemoveMediaSource(mediaSource, index) {
546
+ var _a;
547
+ try {
521
548
  this.nodeMediaMixingPlugin.removeMediaSource(mediaSource);
522
549
  (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeMedia({
523
550
  id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
524
551
  rect: mediaSource.rect,
525
552
  isSelected: mediaSource.isSelected || false,
553
+ zOrder: mediaSource.zOrder,
526
554
  origin: (0, utils_1.safelyParse)(JSON.stringify(mediaSource))
527
555
  });
528
556
  this.sourceList.splice(index, 1);
529
- });
557
+ }
558
+ catch (error) {
559
+ logger_1.default.warn(`${this.logPrefix}removeMediaSource exception:`, error);
560
+ }
530
561
  }
531
562
  /**
532
563
  * 更新本地混流媒体源
@@ -539,7 +570,10 @@ class TRTCMediaMixingManager {
539
570
  logger_1.default.log(`${this.logPrefix}updateMediaSource:`, mediaSource);
540
571
  const index = this.findMediaSourceIndex(mediaSource);
541
572
  if (index === -1) {
542
- throw new Error("Not existing media source to update");
573
+ return Promise.reject({
574
+ code: types_1.TRTCMediaMixingErrorCode.NotFoundSource,
575
+ message: "Not existing media source to update"
576
+ });
543
577
  }
544
578
  const newMediaSource = Object.assign(Object.assign({}, this.sourceList[index]), (0, utils_1.safelyParse)(JSON.stringify(mediaSource)));
545
579
  if (mediaSource.isSelected) {
@@ -553,6 +587,7 @@ class TRTCMediaMixingManager {
553
587
  id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
554
588
  rect: mediaSource.rect,
555
589
  isSelected: mediaSource.isSelected || false,
590
+ zOrder: mediaSource.zOrder,
556
591
  origin: (0, utils_1.safelyParse)(JSON.stringify(mediaSource))
557
592
  });
558
593
  this.sourceList[index] = newMediaSource;
@@ -639,30 +674,26 @@ class TRTCMediaMixingManager {
639
674
  minVideoBitrate: 0,
640
675
  enableAdjustRes: 0,
641
676
  } }));
642
- this.nodeMediaMixingPlugin.callExperimentalAPI(JSON.stringify({
643
- api: 'setVideoEncodeParamEx',
644
- params: {
645
- videoWidth: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoWidth : this.mixingVideoHeight,
646
- videoHeight: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoHeight : this.mixingVideoWidth,
647
- videoFps: params.videoEncoderParams.videoFps,
648
- videoBitrate: params.videoEncoderParams.videoBitrate,
649
- gop: 1,
650
- resolutionMode: params.videoEncoderParams.resMode,
651
- streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig,
652
- }
653
- }));
677
+ const encodeParamEx = {
678
+ videoWidth: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoWidth : this.mixingVideoHeight,
679
+ videoHeight: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoHeight : this.mixingVideoWidth,
680
+ videoFps: params.videoEncoderParams.videoFps,
681
+ videoBitrate: params.videoEncoderParams.videoBitrate,
682
+ gop: 1,
683
+ resolutionMode: params.videoEncoderParams.resMode,
684
+ streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig,
685
+ };
654
686
  if (params.videoEncoderParams.colorRange !== undefined
655
687
  || params.videoEncoderParams.colorSpace !== undefined
656
688
  || params.videoEncoderParams.complexity !== undefined) {
657
- this.nodeMediaMixingPlugin.callExperimentalAPI(JSON.stringify({
658
- "api": "setVideoEncodeParamEx",
659
- "params": {
660
- "colorRange": params.videoEncoderParams.colorRange || trtc_define_1.TRTCVideoColorRange.TRTCVideoColorRange_Auto,
661
- "colorSpace": params.videoEncoderParams.colorSpace || trtc_define_1.TRTCVideoColorSpace.TRTCVideoColorSpace_Auto,
662
- "complexity": params.videoEncoderParams.complexity || trtc_define_1.TRTCVideoEncodeComplexity.TRTCVideoEncodeComplexity_Fastest,
663
- }
664
- }));
689
+ encodeParamEx.colorRange = params.videoEncoderParams.colorRange || trtc_define_1.TRTCVideoColorRange.TRTCVideoColorRange_Auto;
690
+ encodeParamEx.colorSpace = params.videoEncoderParams.colorSpace || trtc_define_1.TRTCVideoColorSpace.TRTCVideoColorSpace_Auto;
691
+ encodeParamEx.complexity = params.videoEncoderParams.complexity || trtc_define_1.TRTCVideoEncodeComplexity.TRTCVideoEncodeComplexity_Fastest;
665
692
  }
693
+ this.nodeMediaMixingPlugin.callExperimentalAPI(JSON.stringify({
694
+ api: 'setVideoEncodeParamEx',
695
+ params: encodeParamEx
696
+ }));
666
697
  return result;
667
698
  });
668
699
  }
@@ -740,7 +771,7 @@ class TRTCMediaMixingManager {
740
771
  */
741
772
  setStreamLayout(layout) {
742
773
  var _a, _b, _c;
743
- logger_1.default.log(`${this.logPrefix}setStreamLayout:`, layout);
774
+ logger_1.default.debug(`${this.logPrefix}setStreamLayout:`, JSON.stringify(layout));
744
775
  if (this.paramsStore) {
745
776
  try {
746
777
  this.paramsStore.streamLayout = JSON.parse(JSON.stringify(layout));
@@ -749,9 +780,8 @@ class TRTCMediaMixingManager {
749
780
  this.paramsStore.streamLayout = undefined;
750
781
  }
751
782
  }
752
- this.createorUpdateLayoutManager(layout);
753
- let transferredUserList = layout.userList;
754
783
  if (this.view) {
784
+ this.createOrUpdateLayoutManager(layout);
755
785
  const viewRect = this.view.getBoundingClientRect();
756
786
  if ((_a = layout.userList) === null || _a === void 0 ? void 0 : _a.length) {
757
787
  const localUser = layout.userList.filter(user => user.userId === constant_1.LOCAL_USER_ID)[0];
@@ -764,26 +794,12 @@ class TRTCMediaMixingManager {
764
794
  bottom: workingArea.bottom / viewRect.height,
765
795
  }, localUser.fillMode);
766
796
  }
767
- transferredUserList = layout.userList.map((user) => {
768
- if (user.rect) {
769
- return Object.assign(Object.assign({}, user), { rect: {
770
- left: user.rect.left * window.devicePixelRatio,
771
- right: user.rect.right * window.devicePixelRatio,
772
- top: user.rect.top * window.devicePixelRatio,
773
- bottom: user.rect.bottom * window.devicePixelRatio,
774
- } });
775
- }
776
- else {
777
- return user;
778
- }
779
- });
780
- logger_1.default.log(`${this.logPrefix}setStreamLayout transfer layout to pixel unit:`, JSON.stringify(layout));
781
797
  }
782
798
  }
783
799
  else {
784
800
  logger_1.default.warn(`${this.logPrefix}setStreamLayout: view is null, no container HTML element. User control the layout manually in device pixel unit.`);
785
801
  }
786
- (_c = this.streamLayoutManager) === null || _c === void 0 ? void 0 : _c.setLayout(Object.assign(Object.assign({}, layout), { userList: transferredUserList }));
802
+ (_c = this.streamLayoutManager) === null || _c === void 0 ? void 0 : _c.setLayout(layout);
787
803
  }
788
804
  /**
789
805
  * @private
@@ -846,6 +862,10 @@ class TRTCMediaMixingManager {
846
862
  });
847
863
  });
848
864
  }
865
+ callExperimentalAPI(jsonStr) {
866
+ logger_1.default.debug(`${this.logPrefix}callExperimentalAPI:${jsonStr}`);
867
+ this.nodeMediaMixingPlugin.callExperimentalAPI(jsonStr);
868
+ }
849
869
  /**
850
870
  * 注册事件监听
851
871
  *
@@ -866,12 +886,20 @@ class TRTCMediaMixingManager {
866
886
  var _a;
867
887
  (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.off(event, func);
868
888
  }
869
- initResizeObserver() {
889
+ createResizeObserver() {
870
890
  if (this.view) {
871
891
  this.resizeObserver = new ResizeObserver(this.onPreviewAreaResize);
872
892
  this.resizeObserver.observe(this.view);
873
893
  }
874
894
  }
895
+ destroyResizeObserver() {
896
+ if (this.resizeObserver) {
897
+ if (this.view) {
898
+ this.resizeObserver.unobserve(this.view);
899
+ }
900
+ this.resizeObserver.disconnect();
901
+ }
902
+ }
875
903
  onPreviewAreaResize(entries) {
876
904
  logger_1.default.log(`${this.logPrefix}onPreviewAreaResize:`, entries);
877
905
  for (const entry of entries) {
@@ -899,6 +927,7 @@ class TRTCMediaMixingManager {
899
927
  top: clientRect.top * window.devicePixelRatio,
900
928
  bottom: clientRect.bottom * window.devicePixelRatio,
901
929
  };
930
+ logger_1.default.debug(`${this.logPrefix}setDisplayRect:`, this.windowID, rect);
902
931
  this.nodeMediaMixingPlugin.setDisplayParams(this.windowID, rect);
903
932
  }
904
933
  }
@@ -919,6 +948,7 @@ class TRTCMediaMixingManager {
919
948
  id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
920
949
  rect: mediaSource.rect,
921
950
  isSelected: mediaSource.isSelected || false,
951
+ zOrder: mediaSource.zOrder,
922
952
  origin: mediaSource
923
953
  });
924
954
  }));
@@ -933,7 +963,7 @@ class TRTCMediaMixingManager {
933
963
  this.mediaMixingDesigner = null;
934
964
  }
935
965
  }
936
- createorUpdateLayoutManager(layout) {
966
+ createOrUpdateLayoutManager(layout) {
937
967
  const context = {
938
968
  container: this.view,
939
969
  mixingVideoSize: {
@@ -1052,6 +1082,7 @@ class TRTCMediaMixingManager {
1052
1082
  id: `${this.sourceList[index].sourceType}__${this.sourceList[index].sourceId}`,
1053
1083
  rect: this.sourceList[index].rect,
1054
1084
  isSelected: this.sourceList[index].isSelected || false,
1085
+ zOrder: this.sourceList[index].zOrder,
1055
1086
  origin: (0, utils_1.safelyParse)(JSON.stringify(this.sourceList[index]))
1056
1087
  });
1057
1088
  });
@@ -1063,8 +1094,10 @@ class TRTCMediaMixingManager {
1063
1094
  // To do: 待完善
1064
1095
  switch (key) {
1065
1096
  case "onMediaSourceAdded":
1097
+ this.onMediaSourceAdded(data);
1098
+ break;
1066
1099
  case "onMediaSourceRemoved":
1067
- this.onMediaSourceAddedOrRemoved(key, data);
1100
+ this.onMediaSourceRemoved(data);
1068
1101
  break;
1069
1102
  case TRTCMediaMixingEvent.onMediaSourceSizeChanged:
1070
1103
  this.onMediaSourceSizeChanged(data);
@@ -1083,16 +1116,43 @@ class TRTCMediaMixingManager {
1083
1116
  break;
1084
1117
  }
1085
1118
  }
1086
- onMediaSourceAddedOrRemoved(key, data) {
1119
+ onMediaSourceAdded(data) {
1087
1120
  var _a;
1088
- let promiseKey;
1089
- if (key === "onMediaSourceAdded") {
1090
- promiseKey = `${promiseKeys.addMediaSource}-${data.sourceType}-${data.sourceId}`;
1121
+ const promiseKey = `${promiseKeys.addMediaSource}-${data.sourceType}-${data.sourceId}`;
1122
+ let flag = false;
1123
+ if (data.errCode === 0) {
1124
+ flag = this.promiseStore.resolvePromise(promiseKey, undefined);
1091
1125
  }
1092
1126
  else {
1093
- // 'onMediaSourceRemoved'
1094
- promiseKey = `${promiseKeys.removeMediaSource}-${data.sourceType}-${data.sourceId}`;
1127
+ const newSourceIndex = this.findMediaSourceIndex({
1128
+ sourceId: data.sourceId,
1129
+ sourceType: data.sourceType,
1130
+ });
1131
+ if (newSourceIndex !== -1) {
1132
+ const newMediaSource = this.sourceList[newSourceIndex];
1133
+ if (!newMediaSource.control) {
1134
+ newMediaSource.control = {};
1135
+ }
1136
+ newMediaSource.control.isAddFailed = true;
1137
+ }
1138
+ flag = this.promiseStore.rejectPromise(promiseKey, {
1139
+ code: data.errCode,
1140
+ message: data.errMsg,
1141
+ });
1095
1142
  }
1143
+ if (data.errCode !== 0 && !flag) {
1144
+ // event triggered internally, not by method invoked by user
1145
+ const index = this.findMediaSourceIndex(data);
1146
+ let mediaSource = undefined;
1147
+ if (index !== -1) {
1148
+ mediaSource = Object.assign({}, this.sourceList[index]);
1149
+ }
1150
+ (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit(TRTCMediaMixingEvent.onError, data.errCode, data.errMsg, mediaSource);
1151
+ }
1152
+ }
1153
+ onMediaSourceRemoved(data) {
1154
+ var _a;
1155
+ const promiseKey = `${promiseKeys.removeMediaSource}-${data.sourceType}-${data.sourceId}`;
1096
1156
  let flag = false;
1097
1157
  if (data.errCode === 0) {
1098
1158
  flag = this.promiseStore.resolvePromise(promiseKey, undefined);
@@ -1183,14 +1243,15 @@ class TRTCMediaMixingManager {
1183
1243
  });
1184
1244
  }
1185
1245
  onMediaMixingServerLost() {
1186
- var _a;
1246
+ var _a, _b;
1187
1247
  return __awaiter(this, void 0, void 0, function* () {
1188
1248
  if (this.autoControlServer) {
1189
1249
  yield this.recoverMediaMixingServer();
1190
1250
  }
1191
1251
  else {
1192
1252
  this.sourceList = [];
1193
- (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit(TRTCMediaMixingEvent.onMediaMixingServerLost);
1253
+ (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeAllMedia();
1254
+ (_b = this.eventEmitter) === null || _b === void 0 ? void 0 : _b.emit(TRTCMediaMixingEvent.onMediaMixingServerLost);
1194
1255
  }
1195
1256
  });
1196
1257
  }
@@ -1209,14 +1270,7 @@ class TRTCMediaMixingManager {
1209
1270
  this.setStreamLayout(this.paramsStore.streamLayout);
1210
1271
  }
1211
1272
  this.sourceList.forEach((item) => {
1212
- var _a;
1213
1273
  this.nodeMediaMixingPlugin.addMediaSource(item);
1214
- (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.addMedia({
1215
- id: `${item.sourceType}__${item.sourceId}`,
1216
- rect: item.rect,
1217
- isSelected: item.isSelected || false,
1218
- origin: item
1219
- });
1220
1274
  });
1221
1275
  if (((_b = this.trtcParamsStore) === null || _b === void 0 ? void 0 : _b.enterRoomParams) && ((_c = this.trtcParamsStore) === null || _c === void 0 ? void 0 : _c.enterRoomScene)) {
1222
1276
  this.nodeTRTCCloud.enterRoom(this.trtcParamsStore.enterRoomParams, this.trtcParamsStore.enterRoomScene);
@@ -1228,6 +1282,10 @@ class TRTCMediaMixingManager {
1228
1282
  }
1229
1283
  });
1230
1284
  }
1285
+ onDevicePixelRatioChange() {
1286
+ logger_1.default.debug(`${this.logPrefix}onDevicePixelRatioChange:`, window.devicePixelRatio);
1287
+ this.setDisplayRect();
1288
+ }
1231
1289
  // ****** 这一部分接口暴露不合理,暂时不对暴露在 API 文档上 **************/
1232
1290
  startCameraDeviceTest(windowID, rect) {
1233
1291
  var _a;
@@ -27,5 +27,6 @@ declare class BaseStreamLayoutManager implements ITRTCStreamLayoutManager {
27
27
  private onResize;
28
28
  private setResizeObserver;
29
29
  private updateDisplayArea;
30
+ private onDevicePixelRatioChange;
30
31
  }
31
32
  export default BaseStreamLayoutManager;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const types_1 = require("../types");
7
+ const DevicePixelRatioObserver_1 = __importDefault(require("../../../base/DevicePixelRatioObserver"));
7
8
  const utils_1 = require("../../../utils");
8
9
  const logger_1 = __importDefault(require("../../../logger"));
9
10
  class BaseStreamLayoutManager {
@@ -33,6 +34,8 @@ class BaseStreamLayoutManager {
33
34
  else {
34
35
  logger_1.default.warn(`${this.logPrefix}constructor failed, no context.container.`);
35
36
  }
37
+ this.onDevicePixelRatioChange = (0, utils_1.debounce)(this.onDevicePixelRatioChange.bind(this), 100);
38
+ DevicePixelRatioObserver_1.default.on('change', this.onDevicePixelRatioChange);
36
39
  }
37
40
  setLayout(layout) {
38
41
  this.layout = layout;
@@ -58,6 +61,7 @@ class BaseStreamLayoutManager {
58
61
  this.resizeObserver.disconnect();
59
62
  this.resizeObserver = null;
60
63
  }
64
+ DevicePixelRatioObserver_1.default.off('change', this.onDevicePixelRatioChange);
61
65
  }
62
66
  refreshLayout() {
63
67
  logger_1.default.warn(`${this.logPrefix}refreshLayout should be implemented by sub-class.`);
@@ -102,5 +106,9 @@ class BaseStreamLayoutManager {
102
106
  logger_1.default.warn(`${this.logPrefix}updateDisplayArea failed, no container.`);
103
107
  }
104
108
  }
109
+ onDevicePixelRatioChange() {
110
+ logger_1.default.debug(`${this.logPrefix}onDevicePixelRatioChange:`, window.devicePixelRatio);
111
+ this.refreshLayout();
112
+ }
105
113
  }
106
114
  exports.default = BaseStreamLayoutManager;
@@ -23,7 +23,24 @@ class CustomStreamLayoutManager extends BaseStreamLayoutManager_1.default {
23
23
  refreshLayout() {
24
24
  var _a;
25
25
  if (this.layout.userList) {
26
- this.nativeStreamLayoutManager.setStreamLayout(this.layout.userList);
26
+ let transferredUserList = this.layout.userList;
27
+ if (this.container) {
28
+ transferredUserList = this.layout.userList.map((user) => {
29
+ if (user.rect) {
30
+ return Object.assign(Object.assign({}, user), { rect: {
31
+ left: Math.round(user.rect.left * window.devicePixelRatio),
32
+ right: Math.round(user.rect.right * window.devicePixelRatio),
33
+ top: Math.round(user.rect.top * window.devicePixelRatio),
34
+ bottom: Math.round(user.rect.bottom * window.devicePixelRatio),
35
+ } });
36
+ }
37
+ else {
38
+ return user;
39
+ }
40
+ });
41
+ }
42
+ logger_1.default.debug(`${this.logPrefix}refreshLayout:`, JSON.stringify(transferredUserList));
43
+ this.nativeStreamLayoutManager.setStreamLayout(transferredUserList);
27
44
  }
28
45
  else if (this.layout.size && this.layout.streams) {
29
46
  const userList = this.convertRelativeToAbsolute(this.layout);
@@ -29,6 +29,7 @@ class NoneStreamLayoutManager extends BaseStreamLayoutManager_1.default {
29
29
  bottom: workingArea.bottom / this.displayArea.height / window.devicePixelRatio,
30
30
  }, this.layout.userList[0].fillMode);
31
31
  }
32
+ logger_1.default.debug(`${this.logPrefix}refreshLayout:`, JSON.stringify(this.layout.userList));
32
33
  (_b = this.nativeStreamLayoutManager) === null || _b === void 0 ? void 0 : _b.setStreamLayout(this.layout.userList);
33
34
  }
34
35
  else {
@@ -59,12 +60,12 @@ class NoneStreamLayoutManager extends BaseStreamLayoutManager_1.default {
59
60
  this.layout.userList = [{
60
61
  userId: '',
61
62
  rect: {
62
- left: previewLeft,
63
- top: previewTop,
64
- right: previewRight,
65
- bottom: previewBottom,
63
+ left: Math.round(previewLeft),
64
+ top: Math.round(previewTop),
65
+ right: Math.round(previewRight),
66
+ bottom: Math.round(previewBottom),
66
67
  },
67
- fillMode: trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fit,
68
+ fillMode: trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fill,
68
69
  zOrder: 0
69
70
  }];
70
71
  }
package/liteav/trtc.d.ts CHANGED
@@ -20,6 +20,7 @@ declare class TRTCCloud extends EventEmitter {
20
20
  private logger;
21
21
  private id;
22
22
  private static isIPCMode;
23
+ private static ipcModeReferenceCount;
23
24
  private static sharedTRTCCloudInstance;
24
25
  private static subInstances;
25
26
  private stateStore;
@@ -1983,7 +1984,7 @@ declare class TRTCCloud extends EventEmitter {
1983
1984
  * true // enable highlight
1984
1985
  * );
1985
1986
  */
1986
- selectScreenCaptureTarget(source: TRTCScreenCaptureSourceInfo | number, captureRect: Rect | string, property: TRTCScreenCaptureProperty | string, deprecatedCaptureRect?: Rect, captureMouse?: boolean, highlightWindow?: boolean): any;
1987
+ selectScreenCaptureTarget(source: TRTCScreenCaptureSourceInfo | number, captureRect: Rect | string, property: TRTCScreenCaptureProperty | string, deprecatedCaptureRect?: Rect, captureMouse?: boolean, highlightWindow?: boolean): void;
1987
1988
  /**
1988
1989
  * 启动屏幕分享,支持选择使用主路或辅路进行屏幕分享。
1989
1990
  *
package/liteav/trtc.js CHANGED
@@ -174,9 +174,11 @@ class TRTCCloud extends events_1.EventEmitter {
174
174
  const newConfig = Object.assign({ jsVersion: pkg.version, componentNO }, config);
175
175
  if (!TRTCCloud.isIPCMode) {
176
176
  this.rtcCloud = new NodeTRTCEngine.NodeTRTCCloud(newConfig);
177
+ TRTCCloud.ipcModeReferenceCount = 0;
177
178
  }
178
179
  else {
179
180
  this.rtcCloud = new NodeTRTCEngine.NodeRemoteTRTCCloud(newConfig);
181
+ TRTCCloud.ipcModeReferenceCount = 1;
180
182
  }
181
183
  this.stateStore = new Map();
182
184
  this.videoRendererMap = new Map();
@@ -308,6 +310,7 @@ class TRTCCloud extends events_1.EventEmitter {
308
310
  return null;
309
311
  }
310
312
  if (TRTCCloud.isIPCMode) {
313
+ TRTCCloud.ipcModeReferenceCount = TRTCCloud.ipcModeReferenceCount + 1;
311
314
  return TRTCCloud.sharedTRTCCloudInstance;
312
315
  }
313
316
  return new TRTCCloud(config);
@@ -348,6 +351,12 @@ class TRTCCloud extends events_1.EventEmitter {
348
351
  */
349
352
  destroy() {
350
353
  var _a, _b;
354
+ if (TRTCCloud.isIPCMode) {
355
+ TRTCCloud.ipcModeReferenceCount = TRTCCloud.ipcModeReferenceCount - 1;
356
+ if (TRTCCloud.ipcModeReferenceCount > 0) {
357
+ return;
358
+ }
359
+ }
351
360
  if (this === TRTCCloud.sharedTRTCCloudInstance) {
352
361
  if (TRTCCloud.subInstances) {
353
362
  TRTCCloud.subInstances.forEach(sub => {
@@ -5188,6 +5197,9 @@ class TRTCCloud extends events_1.EventEmitter {
5188
5197
  return process.platform == 'darwin';
5189
5198
  }
5190
5199
  _setRemoteVideoBuffer(userId, streamType) {
5200
+ if (TRTCCloud.isIPCMode) {
5201
+ return;
5202
+ }
5191
5203
  const videoBufferInfo = new trtc_define_1.VideoBufferInfo({
5192
5204
  userId: userId,
5193
5205
  id: (0, util_1.generateUniqueId)(),
@@ -5261,7 +5273,7 @@ class TRTCCloud extends events_1.EventEmitter {
5261
5273
  }
5262
5274
  }
5263
5275
  catch (error) {
5264
- this.logger.warn(`callExperimentalAPI invalid JSON parameter`, error);
5276
+ this.logger.warn(`callExperimentalAPI invalid JSON parameter`, error, jsonStr);
5265
5277
  }
5266
5278
  }
5267
5279
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trtc-electron-sdk",
3
- "version": "12.2.115-alpha.20",
3
+ "version": "12.2.115-alpha.24",
4
4
  "description": "trtc electron sdk",
5
5
  "main": "./liteav/index.js",
6
6
  "types": "./liteav/index.d.ts",