trtc-electron-sdk 12.6.706-beta.0 → 12.7.706-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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;
@@ -373,6 +373,7 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
373
373
  * @returns {Promise<void>}
374
374
  */
375
375
  stopMediaMixingServer(): Promise<void>;
376
+ callExperimentalAPI(jsonStr: string): void;
376
377
  /**
377
378
  * 注册事件监听
378
379
  *
@@ -393,6 +394,8 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
393
394
  private setDisplayRect;
394
395
  private createDesigner;
395
396
  private destroyDesigner;
397
+ private createOrUpdateLayoutManager;
398
+ private destroyLayoutManager;
396
399
  private updateMixingVideoSize;
397
400
  private listenDesignerEvent;
398
401
  private unlistenDesignerEvent;
@@ -407,13 +410,15 @@ export declare class TRTCMediaMixingManager implements ITRTCMediaMixingManager {
407
410
  private findSelectedMediaSource;
408
411
  private unselectMediaSource;
409
412
  private handleCppCallbackEvent;
410
- private onMediaSourceAddedOrRemoved;
413
+ private onMediaSourceAdded;
414
+ private onMediaSourceRemoved;
411
415
  private onMediaSourceSizeChanged;
412
416
  private onPhoneMirrorSourceChanged;
413
417
  private onMediaServerState;
414
418
  private onMediaMixingServerLost;
415
419
  private onCallExperimentalAPIFinish;
416
420
  private recoverMediaMixingServer;
421
+ private onDevicePixelRatioChange;
417
422
  startCameraDeviceTest(windowID: number | Uint8Array, rect?: Rect): Promise<number>;
418
423
  stopCameraDeviceTest(): Promise<number>;
419
424
  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,9 +309,12 @@ 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
319
  if (this.resizeObserver && this.view) {
315
320
  this.resizeObserver.unobserve(this.view);
@@ -444,18 +449,29 @@ class TRTCMediaMixingManager {
444
449
  this.windowID = realWindowID;
445
450
  if (realWindowID !== 0 && viewOrRegion !== null) {
446
451
  if (viewOrRegion instanceof HTMLElement) {
447
- this.destroyDesigner();
448
- this.view = viewOrRegion;
449
- this.setDisplayRect();
450
- this.initResizeObserver();
451
- this.createDesigner();
452
+ if (this.view !== viewOrRegion) {
453
+ this.destroyDesigner();
454
+ this.view = viewOrRegion;
455
+ this.setDisplayRect();
456
+ this.initResizeObserver();
457
+ this.createDesigner();
458
+ }
459
+ else {
460
+ this.setDisplayRect();
461
+ if (!this.mediaMixingDesigner) {
462
+ this.createDesigner();
463
+ }
464
+ }
452
465
  }
453
466
  else {
454
467
  // Rect
468
+ this.destroyLayoutManager();
469
+ this.destroyDesigner();
455
470
  this.nodeMediaMixingPlugin.setDisplayParams(realWindowID, viewOrRegion);
456
471
  }
457
472
  }
458
473
  else {
474
+ this.destroyLayoutManager();
459
475
  this.destroyDesigner();
460
476
  this.nodeMediaMixingPlugin.setDisplayParams(realWindowID, { left: 0, right: 0, top: 0, bottom: 0 });
461
477
  }
@@ -469,7 +485,10 @@ class TRTCMediaMixingManager {
469
485
  logger_1.default.log(`${this.logPrefix}addMediaSource:`, mediaSource);
470
486
  const index = this.findMediaSourceIndex(mediaSource);
471
487
  if (index !== -1) {
472
- throw new Error("Media source already existed");
488
+ return Promise.reject({
489
+ code: types_1.TRTCMediaMixingErrorCode.InvalidParams,
490
+ message: "Media source already existed"
491
+ });
473
492
  }
474
493
  const newMediaSource = (0, utils_1.safelyParse)(JSON.stringify(mediaSource));
475
494
  if (newMediaSource.isSelected) {
@@ -487,6 +506,7 @@ class TRTCMediaMixingManager {
487
506
  id: `${newMediaSource.sourceType}__${newMediaSource.sourceId}`,
488
507
  rect: newMediaSource.rect,
489
508
  isSelected: newMediaSource.isSelected || false,
509
+ zOrder: newMediaSource.zOrder,
490
510
  origin: newMediaSource
491
511
  });
492
512
  this.sourceList.push(newMediaSource);
@@ -501,20 +521,15 @@ class TRTCMediaMixingManager {
501
521
  logger_1.default.log(`${this.logPrefix}removeMediaSource:`, mediaSource);
502
522
  const index = this.findMediaSourceIndex(mediaSource);
503
523
  if (index === -1) {
504
- throw new Error("Not existing media source to remove");
524
+ return Promise.reject({
525
+ code: types_1.TRTCMediaMixingErrorCode.NotFoundSource,
526
+ message: "Not existing media source to remove"
527
+ });
505
528
  }
506
529
  return new Promise((resolve, reject) => {
507
- var _a;
508
530
  const key = `${promiseKeys.removeMediaSource}-${mediaSource.sourceType}-${mediaSource.sourceId}`;
509
531
  this.promiseStore.addPromise(key, resolve, reject);
510
532
  this.nodeMediaMixingPlugin.removeMediaSource(mediaSource);
511
- (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeMedia({
512
- id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
513
- rect: mediaSource.rect,
514
- isSelected: mediaSource.isSelected || false,
515
- origin: (0, utils_1.safelyParse)(JSON.stringify(mediaSource))
516
- });
517
- this.sourceList.splice(index, 1);
518
533
  });
519
534
  }
520
535
  /**
@@ -528,7 +543,10 @@ class TRTCMediaMixingManager {
528
543
  logger_1.default.log(`${this.logPrefix}updateMediaSource:`, mediaSource);
529
544
  const index = this.findMediaSourceIndex(mediaSource);
530
545
  if (index === -1) {
531
- throw new Error("Not existing media source to update");
546
+ return Promise.reject({
547
+ code: types_1.TRTCMediaMixingErrorCode.NotFoundSource,
548
+ message: "Not existing media source to update"
549
+ });
532
550
  }
533
551
  const newMediaSource = Object.assign(Object.assign({}, this.sourceList[index]), (0, utils_1.safelyParse)(JSON.stringify(mediaSource)));
534
552
  if (mediaSource.isSelected) {
@@ -542,6 +560,7 @@ class TRTCMediaMixingManager {
542
560
  id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
543
561
  rect: mediaSource.rect,
544
562
  isSelected: mediaSource.isSelected || false,
563
+ zOrder: mediaSource.zOrder,
545
564
  origin: (0, utils_1.safelyParse)(JSON.stringify(mediaSource))
546
565
  });
547
566
  this.sourceList[index] = newMediaSource;
@@ -620,19 +639,34 @@ class TRTCMediaMixingManager {
620
639
  width: this.mixingVideoWidth,
621
640
  height: this.mixingVideoHeight
622
641
  });
623
- const result = yield this.nodeMediaMixingPlugin.updatePublishParams(params);
642
+ const result = yield this.nodeMediaMixingPlugin.updatePublishParams(Object.assign(Object.assign({}, params), { videoEncoderParams: {
643
+ videoResolution: 0,
644
+ resMode: 0,
645
+ videoFps: params.videoEncoderParams.videoFps,
646
+ videoBitrate: 0,
647
+ minVideoBitrate: 0,
648
+ enableAdjustRes: 0,
649
+ } }));
650
+ const encodeParamEx = {
651
+ videoWidth: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoWidth : this.mixingVideoHeight,
652
+ videoHeight: this.mixingVideoWidth > this.mixingVideoHeight ? this.mixingVideoHeight : this.mixingVideoWidth,
653
+ videoFps: params.videoEncoderParams.videoFps,
654
+ videoBitrate: params.videoEncoderParams.videoBitrate,
655
+ gop: 1,
656
+ resolutionMode: params.videoEncoderParams.resMode,
657
+ streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig,
658
+ };
624
659
  if (params.videoEncoderParams.colorRange !== undefined
625
660
  || params.videoEncoderParams.colorSpace !== undefined
626
661
  || params.videoEncoderParams.complexity !== undefined) {
627
- this.nodeMediaMixingPlugin.callExperimentalAPI(JSON.stringify({
628
- "api": "setVideoEncodeParamEx",
629
- "params": {
630
- "colorRange": params.videoEncoderParams.colorRange || trtc_define_1.TRTCVideoColorRange.TRTCVideoColorRange_Auto,
631
- "colorSpace": params.videoEncoderParams.colorSpace || trtc_define_1.TRTCVideoColorSpace.TRTCVideoColorSpace_Auto,
632
- "complexity": params.videoEncoderParams.complexity || trtc_define_1.TRTCVideoEncodeComplexity.TRTCVideoEncodeComplexity_Fastest,
633
- }
634
- }));
662
+ encodeParamEx.colorRange = params.videoEncoderParams.colorRange || trtc_define_1.TRTCVideoColorRange.TRTCVideoColorRange_Auto;
663
+ encodeParamEx.colorSpace = params.videoEncoderParams.colorSpace || trtc_define_1.TRTCVideoColorSpace.TRTCVideoColorSpace_Auto;
664
+ encodeParamEx.complexity = params.videoEncoderParams.complexity || trtc_define_1.TRTCVideoEncodeComplexity.TRTCVideoEncodeComplexity_Fastest;
635
665
  }
666
+ this.nodeMediaMixingPlugin.callExperimentalAPI(JSON.stringify({
667
+ api: 'setVideoEncodeParamEx',
668
+ params: encodeParamEx
669
+ }));
636
670
  return result;
637
671
  });
638
672
  }
@@ -709,7 +743,7 @@ class TRTCMediaMixingManager {
709
743
  * }
710
744
  */
711
745
  setStreamLayout(layout) {
712
- var _a, _b;
746
+ var _a, _b, _c;
713
747
  logger_1.default.log(`${this.logPrefix}setStreamLayout:`, layout);
714
748
  if (this.paramsStore) {
715
749
  try {
@@ -719,22 +753,7 @@ class TRTCMediaMixingManager {
719
753
  this.paramsStore.streamLayout = undefined;
720
754
  }
721
755
  }
722
- const context = {
723
- container: this.view,
724
- mixingVideoSize: {
725
- width: this.mixingVideoWidth,
726
- height: this.mixingVideoHeight
727
- },
728
- mediaMixingDesigner: this.mediaMixingDesigner
729
- };
730
- if (!this.streamLayoutManager) {
731
- this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
732
- }
733
- else if (this.streamLayoutManager.getLayoutMode() !== layout.layoutMode) {
734
- this.streamLayoutManager.destroy();
735
- this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
736
- }
737
- let transferredUserList = layout.userList;
756
+ this.createOrUpdateLayoutManager(layout);
738
757
  if (this.view) {
739
758
  const viewRect = this.view.getBoundingClientRect();
740
759
  if ((_a = layout.userList) === null || _a === void 0 ? void 0 : _a.length) {
@@ -748,26 +767,13 @@ class TRTCMediaMixingManager {
748
767
  bottom: workingArea.bottom / viewRect.height,
749
768
  }, localUser.fillMode);
750
769
  }
751
- transferredUserList = layout.userList.map((user) => {
752
- if (user.rect) {
753
- return Object.assign(Object.assign({}, user), { rect: {
754
- left: user.rect.left * window.devicePixelRatio,
755
- right: user.rect.right * window.devicePixelRatio,
756
- top: user.rect.top * window.devicePixelRatio,
757
- bottom: user.rect.bottom * window.devicePixelRatio,
758
- } });
759
- }
760
- else {
761
- return user;
762
- }
763
- });
764
770
  logger_1.default.log(`${this.logPrefix}setStreamLayout transfer layout to pixel unit:`, JSON.stringify(layout));
765
771
  }
766
772
  }
767
773
  else {
768
774
  logger_1.default.warn(`${this.logPrefix}setStreamLayout: view is null, no container HTML element. User control the layout manually in device pixel unit.`);
769
775
  }
770
- this.streamLayoutManager.setLayout(Object.assign(Object.assign({}, layout), { userList: transferredUserList }));
776
+ (_c = this.streamLayoutManager) === null || _c === void 0 ? void 0 : _c.setLayout(layout);
771
777
  }
772
778
  /**
773
779
  * @private
@@ -830,6 +836,10 @@ class TRTCMediaMixingManager {
830
836
  });
831
837
  });
832
838
  }
839
+ callExperimentalAPI(jsonStr) {
840
+ logger_1.default.debug(`${this.logPrefix}callExperimentalAPI:${jsonStr}`);
841
+ this.nodeMediaMixingPlugin.callExperimentalAPI(jsonStr);
842
+ }
833
843
  /**
834
844
  * 注册事件监听
835
845
  *
@@ -896,6 +906,18 @@ class TRTCMediaMixingManager {
896
906
  canExceedContainer: true,
897
907
  });
898
908
  this.listenDesignerEvent();
909
+ if (this.sourceList.length >= 1) {
910
+ this.sourceList.forEach((mediaSource => {
911
+ var _a;
912
+ (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.addMedia({
913
+ id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
914
+ rect: mediaSource.rect,
915
+ isSelected: mediaSource.isSelected || false,
916
+ zOrder: mediaSource.zOrder,
917
+ origin: mediaSource
918
+ });
919
+ }));
920
+ }
899
921
  }
900
922
  }
901
923
  destroyDesigner() {
@@ -906,6 +928,29 @@ class TRTCMediaMixingManager {
906
928
  this.mediaMixingDesigner = null;
907
929
  }
908
930
  }
931
+ createOrUpdateLayoutManager(layout) {
932
+ const context = {
933
+ container: this.view,
934
+ mixingVideoSize: {
935
+ width: this.mixingVideoWidth,
936
+ height: this.mixingVideoHeight
937
+ },
938
+ mediaMixingDesigner: this.mediaMixingDesigner
939
+ };
940
+ if (!this.streamLayoutManager) {
941
+ this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
942
+ }
943
+ else if (this.streamLayoutManager.getLayoutMode() !== layout.layoutMode) {
944
+ this.streamLayoutManager.destroy();
945
+ this.streamLayoutManager = StreamLayout_1.StreamLayoutFactory.create(layout.layoutMode, this.nodeMediaMixingPlugin, context);
946
+ }
947
+ }
948
+ destroyLayoutManager() {
949
+ if (this.streamLayoutManager) {
950
+ this.streamLayoutManager.destroy();
951
+ this.streamLayoutManager = null;
952
+ }
953
+ }
909
954
  updateMixingVideoSize(params) {
910
955
  if (resolutionMap.has(params.videoResolution)) {
911
956
  const { width, height } = resolutionMap.get(params.videoResolution);
@@ -1002,6 +1047,7 @@ class TRTCMediaMixingManager {
1002
1047
  id: `${this.sourceList[index].sourceType}__${this.sourceList[index].sourceId}`,
1003
1048
  rect: this.sourceList[index].rect,
1004
1049
  isSelected: this.sourceList[index].isSelected || false,
1050
+ zOrder: this.sourceList[index].zOrder,
1005
1051
  origin: (0, utils_1.safelyParse)(JSON.stringify(this.sourceList[index]))
1006
1052
  });
1007
1053
  });
@@ -1013,8 +1059,10 @@ class TRTCMediaMixingManager {
1013
1059
  // To do: 待完善
1014
1060
  switch (key) {
1015
1061
  case "onMediaSourceAdded":
1062
+ this.onMediaSourceAdded(data);
1063
+ break;
1016
1064
  case "onMediaSourceRemoved":
1017
- this.onMediaSourceAddedOrRemoved(key, data);
1065
+ this.onMediaSourceRemoved(data);
1018
1066
  break;
1019
1067
  case TRTCMediaMixingEvent.onMediaSourceSizeChanged:
1020
1068
  this.onMediaSourceSizeChanged(data);
@@ -1033,18 +1081,64 @@ class TRTCMediaMixingManager {
1033
1081
  break;
1034
1082
  }
1035
1083
  }
1036
- onMediaSourceAddedOrRemoved(key, data) {
1037
- var _a;
1038
- let promiseKey;
1039
- if (key === "onMediaSourceAdded") {
1040
- promiseKey = `${promiseKeys.addMediaSource}-${data.sourceType}-${data.sourceId}`;
1084
+ onMediaSourceAdded(data) {
1085
+ var _a, _b;
1086
+ const promiseKey = `${promiseKeys.addMediaSource}-${data.sourceType}-${data.sourceId}`;
1087
+ let flag = false;
1088
+ if (data.errCode === 0) {
1089
+ flag = this.promiseStore.resolvePromise(promiseKey, undefined);
1041
1090
  }
1042
1091
  else {
1043
- // 'onMediaSourceRemoved'
1044
- promiseKey = `${promiseKeys.removeMediaSource}-${data.sourceType}-${data.sourceId}`;
1092
+ const newSourceIndex = this.findMediaSourceIndex({
1093
+ sourceId: data.sourceId,
1094
+ sourceType: data.sourceType,
1095
+ });
1096
+ if (newSourceIndex !== -1) {
1097
+ const newMediaSource = this.sourceList[newSourceIndex];
1098
+ (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeMedia({
1099
+ id: `${newMediaSource.sourceType}__${newMediaSource.sourceId}`,
1100
+ rect: newMediaSource.rect,
1101
+ isSelected: newMediaSource.isSelected || false,
1102
+ zOrder: newMediaSource.zOrder,
1103
+ origin: newMediaSource
1104
+ });
1105
+ this.sourceList.splice(newSourceIndex, 1);
1106
+ }
1107
+ flag = this.promiseStore.rejectPromise(promiseKey, {
1108
+ code: data.errCode,
1109
+ message: data.errMsg,
1110
+ });
1111
+ }
1112
+ if (data.errCode !== 0 && !flag) {
1113
+ // event triggered internally, not by method invoked by user
1114
+ const index = this.findMediaSourceIndex(data);
1115
+ let mediaSource = undefined;
1116
+ if (index !== -1) {
1117
+ mediaSource = Object.assign({}, this.sourceList[index]);
1118
+ }
1119
+ (_b = this.eventEmitter) === null || _b === void 0 ? void 0 : _b.emit(TRTCMediaMixingEvent.onError, data.errCode, data.errMsg, mediaSource);
1045
1120
  }
1121
+ }
1122
+ onMediaSourceRemoved(data) {
1123
+ var _a, _b;
1124
+ const promiseKey = `${promiseKeys.removeMediaSource}-${data.sourceType}-${data.sourceId}`;
1046
1125
  let flag = false;
1047
1126
  if (data.errCode === 0) {
1127
+ const sourceIndex = this.findMediaSourceIndex({
1128
+ sourceId: data.sourceId,
1129
+ sourceType: data.sourceType
1130
+ });
1131
+ if (sourceIndex !== -1) {
1132
+ const mediaSource = this.sourceList[sourceIndex];
1133
+ (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeMedia({
1134
+ id: `${mediaSource.sourceType}__${mediaSource.sourceId}`,
1135
+ rect: mediaSource.rect,
1136
+ isSelected: mediaSource.isSelected || false,
1137
+ zOrder: mediaSource.zOrder,
1138
+ origin: (0, utils_1.safelyParse)(JSON.stringify(mediaSource))
1139
+ });
1140
+ this.sourceList.splice(sourceIndex, 1);
1141
+ }
1048
1142
  flag = this.promiseStore.resolvePromise(promiseKey, undefined);
1049
1143
  }
1050
1144
  else {
@@ -1060,7 +1154,7 @@ class TRTCMediaMixingManager {
1060
1154
  if (index !== -1) {
1061
1155
  mediaSource = Object.assign({}, this.sourceList[index]);
1062
1156
  }
1063
- (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit(TRTCMediaMixingEvent.onError, data.errCode, data.errMsg, mediaSource);
1157
+ (_b = this.eventEmitter) === null || _b === void 0 ? void 0 : _b.emit(TRTCMediaMixingEvent.onError, data.errCode, data.errMsg, mediaSource);
1064
1158
  }
1065
1159
  }
1066
1160
  onMediaSourceSizeChanged(data) {
@@ -1133,14 +1227,15 @@ class TRTCMediaMixingManager {
1133
1227
  });
1134
1228
  }
1135
1229
  onMediaMixingServerLost() {
1136
- var _a;
1230
+ var _a, _b;
1137
1231
  return __awaiter(this, void 0, void 0, function* () {
1138
1232
  if (this.autoControlServer) {
1139
1233
  yield this.recoverMediaMixingServer();
1140
1234
  }
1141
1235
  else {
1142
1236
  this.sourceList = [];
1143
- (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit(TRTCMediaMixingEvent.onMediaMixingServerLost);
1237
+ (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.removeAllMedia();
1238
+ (_b = this.eventEmitter) === null || _b === void 0 ? void 0 : _b.emit(TRTCMediaMixingEvent.onMediaMixingServerLost);
1144
1239
  }
1145
1240
  });
1146
1241
  }
@@ -1159,14 +1254,7 @@ class TRTCMediaMixingManager {
1159
1254
  this.setStreamLayout(this.paramsStore.streamLayout);
1160
1255
  }
1161
1256
  this.sourceList.forEach((item) => {
1162
- var _a;
1163
1257
  this.nodeMediaMixingPlugin.addMediaSource(item);
1164
- (_a = this.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.addMedia({
1165
- id: `${item.sourceType}__${item.sourceId}`,
1166
- rect: item.rect,
1167
- isSelected: item.isSelected || false,
1168
- origin: item
1169
- });
1170
1258
  });
1171
1259
  if (((_b = this.trtcParamsStore) === null || _b === void 0 ? void 0 : _b.enterRoomParams) && ((_c = this.trtcParamsStore) === null || _c === void 0 ? void 0 : _c.enterRoomScene)) {
1172
1260
  this.nodeTRTCCloud.enterRoom(this.trtcParamsStore.enterRoomParams, this.trtcParamsStore.enterRoomScene);
@@ -1178,6 +1266,10 @@ class TRTCMediaMixingManager {
1178
1266
  }
1179
1267
  });
1180
1268
  }
1269
+ onDevicePixelRatioChange() {
1270
+ logger_1.default.debug(`${this.logPrefix}onDevicePixelRatioChange:`, window.devicePixelRatio);
1271
+ this.setDisplayRect();
1272
+ }
1181
1273
  // ****** 这一部分接口暴露不合理,暂时不对暴露在 API 文档上 **************/
1182
1274
  startCameraDeviceTest(windowID, rect) {
1183
1275
  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,23 @@ 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: user.rect.left * window.devicePixelRatio,
32
+ right: user.rect.right * window.devicePixelRatio,
33
+ top: user.rect.top * window.devicePixelRatio,
34
+ bottom: user.rect.bottom * window.devicePixelRatio,
35
+ } });
36
+ }
37
+ else {
38
+ return user;
39
+ }
40
+ });
41
+ }
42
+ this.nativeStreamLayoutManager.setStreamLayout(transferredUserList);
27
43
  }
28
44
  else if (this.layout.size && this.layout.streams) {
29
45
  const userList = this.convertRelativeToAbsolute(this.layout);
@@ -17,13 +17,22 @@ class NoneStreamLayoutManager extends BaseStreamLayoutManager_1.default {
17
17
  this.refreshLayout();
18
18
  }
19
19
  refreshLayout() {
20
- var _a;
20
+ var _a, _b;
21
21
  if (this.context && this.layout.userList) {
22
22
  this.centerLiveOwner();
23
- (_a = this.nativeStreamLayoutManager) === null || _a === void 0 ? void 0 : _a.setStreamLayout(this.layout.userList);
23
+ if (this.layout.userList.length === 1 && this.layout.userList[0].rect && this.displayArea.width !== 0 && this.displayArea.height !== 0 && window.devicePixelRatio !== 0) {
24
+ const workingArea = this.layout.userList[0].rect;
25
+ (_a = this.context.mediaMixingDesigner) === null || _a === void 0 ? void 0 : _a.setWorkingArea({
26
+ left: workingArea.left / this.displayArea.width / window.devicePixelRatio,
27
+ top: workingArea.top / this.displayArea.height / window.devicePixelRatio,
28
+ right: workingArea.right / this.displayArea.width / window.devicePixelRatio,
29
+ bottom: workingArea.bottom / this.displayArea.height / window.devicePixelRatio,
30
+ }, this.layout.userList[0].fillMode);
31
+ }
32
+ (_b = this.nativeStreamLayoutManager) === null || _b === void 0 ? void 0 : _b.setStreamLayout(this.layout.userList);
24
33
  }
25
34
  else {
26
- logger_1.default.error(`${this.logPrefix}setLayout context is null or no user`);
35
+ logger_1.default.error(`${this.logPrefix}refreshLayout context is null or no user`);
27
36
  }
28
37
  }
29
38
  centerLiveOwner() {
package/liteav/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export * from './trtc_define';
2
2
  export * from './trtc_code';
3
- export * from './vod_player';
4
3
  export * from './extensions/DeviceManager';
5
4
  export * from './extensions/AudioEffectManager';
6
5
  export * from './extensions/MediaMixingManager';
package/liteav/index.js CHANGED
@@ -15,7 +15,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  __exportStar(require("./trtc_define"), exports);
17
17
  __exportStar(require("./trtc_code"), exports);
18
- __exportStar(require("./vod_player"), exports);
19
18
  __exportStar(require("./extensions/DeviceManager"), exports);
20
19
  __exportStar(require("./extensions/AudioEffectManager"), exports);
21
20
  __exportStar(require("./extensions/MediaMixingManager"), exports);
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;
@@ -36,7 +37,6 @@ declare class TRTCCloud extends EventEmitter {
36
37
  private enableRenderFrame;
37
38
  private screenCaptureStreamType;
38
39
  private isScreenCapturing;
39
- private vodPlayers;
40
40
  private localMediaTranscoder;
41
41
  private isCaptureLocalVideoEnabled;
42
42
  private videoProcessBufferType;
@@ -98,11 +98,11 @@ declare class TRTCCloud extends EventEmitter {
98
98
  * rtcCloud.startLocalAudio(); // 主实例开启麦克风采集
99
99
  *
100
100
  * const childRtcCloud = rtcCloud.createSubCloud();
101
- * childRtcCloud.startSystemAudioLoopback(); // 子实例开启系统音采集
101
+ * childRtcCloud?.startSystemAudioLoopback(); // 子实例开启系统音采集
102
102
  *
103
- * @returns {TRTCCloud}
103
+ * @returns {TRTCCloud|null}
104
104
  */
105
- createSubCloud(config?: TRTCInitConfig): TRTCCloud;
105
+ createSubCloud(config?: TRTCInitConfig): TRTCCloud | null;
106
106
  /**
107
107
  * 获取 TRTC 配置对象
108
108
  *
@@ -2027,7 +2027,7 @@ declare class TRTCCloud extends EventEmitter {
2027
2027
  * true // enable highlight
2028
2028
  * );
2029
2029
  */
2030
- selectScreenCaptureTarget(source: TRTCScreenCaptureSourceInfo | number, captureRect: Rect | string, property: TRTCScreenCaptureProperty | string, deprecatedCaptureRect?: Rect, captureMouse?: boolean, highlightWindow?: boolean): any;
2030
+ selectScreenCaptureTarget(source: TRTCScreenCaptureSourceInfo | number, captureRect: Rect | string, property: TRTCScreenCaptureProperty | string, deprecatedCaptureRect?: Rect, captureMouse?: boolean, highlightWindow?: boolean): void;
2031
2031
  /**
2032
2032
  * 启动屏幕分享,支持选择使用主路或辅路进行屏幕分享。
2033
2033
  *
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();
@@ -212,7 +214,6 @@ class TRTCCloud extends events_1.EventEmitter {
212
214
  //VideoCallback 本地和远程
213
215
  this.localVideoCallback = null;
214
216
  this.remoteVideoCallback = new Map();
215
- this.vodPlayers = {};
216
217
  secMethods(this);
217
218
  // 视频渲染共享buffer
218
219
  this.remoteVideoBufferMap = new Map();
@@ -306,16 +307,18 @@ class TRTCCloud extends events_1.EventEmitter {
306
307
  * rtcCloud.startLocalAudio(); // 主实例开启麦克风采集
307
308
  *
308
309
  * const childRtcCloud = rtcCloud.createSubCloud();
309
- * childRtcCloud.startSystemAudioLoopback(); // 子实例开启系统音采集
310
+ * childRtcCloud?.startSystemAudioLoopback(); // 子实例开启系统音采集
310
311
  *
311
- * @returns {TRTCCloud}
312
+ * @returns {TRTCCloud|null}
312
313
  */
313
314
  createSubCloud(config) {
314
315
  if (this !== TRTCCloud.sharedTRTCCloudInstance) {
315
- throw new Error("createSubCloud() can only be called on the main instance created by getTRTCShareInstance().");
316
+ this.logger.warn("createSubCloud() can only be called on the main instance created by getTRTCShareInstance().");
317
+ return null;
316
318
  }
317
319
  if (TRTCCloud.isIPCMode) {
318
- throw new Error("createSubCloud() is not supported when `isIPCMode` is true.");
320
+ TRTCCloud.ipcModeReferenceCount = TRTCCloud.ipcModeReferenceCount + 1;
321
+ return TRTCCloud.sharedTRTCCloudInstance;
319
322
  }
320
323
  return new TRTCCloud(config);
321
324
  }
@@ -355,6 +358,12 @@ class TRTCCloud extends events_1.EventEmitter {
355
358
  */
356
359
  destroy() {
357
360
  var _a, _b;
361
+ if (TRTCCloud.isIPCMode) {
362
+ TRTCCloud.ipcModeReferenceCount = TRTCCloud.ipcModeReferenceCount - 1;
363
+ if (TRTCCloud.ipcModeReferenceCount > 0) {
364
+ return;
365
+ }
366
+ }
358
367
  if (this === TRTCCloud.sharedTRTCCloudInstance) {
359
368
  if (TRTCCloud.subInstances) {
360
369
  TRTCCloud.subInstances.forEach(sub => {
@@ -4875,28 +4884,6 @@ class TRTCCloud extends events_1.EventEmitter {
4875
4884
  //----------------------------------//
4876
4885
  // plugin API -- end
4877
4886
  //----------------------------------//
4878
- //----------------------------------//
4879
- // Vod API -- start
4880
- //----------------------------------//
4881
- // createVodPlayer(mediaFilePath: string, repeat: boolean) {
4882
- // const nativeVodPlayer = this.rtcCloud.createVodPlayer(mediaFilePath, repeat);
4883
- // if (nativeVodPlayer) {
4884
- // const vodPlayer = new VodPlayer(nativeVodPlayer, mediaFilePath, repeat);
4885
- // vodPlayer.setVodPlayerRenderCallback();
4886
- // vodPlayer.setVodEventCallback();
4887
- // this.vodPlayers[vodPlayer.key] = vodPlayer;
4888
- // return vodPlayer;
4889
- // }
4890
- // return null;
4891
- // }
4892
- // destroyVodPlayer(vodPlayer: VodPlayer) {
4893
- // vodPlayer.destroyRender();
4894
- // this.rtcCloud.destroyVodPlayer(vodPlayer.key);
4895
- // delete this.vodPlayers[vodPlayer.key];
4896
- // }
4897
- //----------------------------------//
4898
- // Vod API -- end
4899
- //----------------------------------//
4900
4887
  _getKey(uid, type) {
4901
4888
  return String(uid) + '_' + String(type);
4902
4889
  }
@@ -5253,6 +5240,9 @@ class TRTCCloud extends events_1.EventEmitter {
5253
5240
  return process.platform == 'darwin';
5254
5241
  }
5255
5242
  _setRemoteVideoBuffer(userId, streamType) {
5243
+ if (TRTCCloud.isIPCMode) {
5244
+ return;
5245
+ }
5256
5246
  const videoBufferInfo = new trtc_define_1.VideoBufferInfo({
5257
5247
  userId: userId,
5258
5248
  id: (0, util_1.generateUniqueId)(),
@@ -5326,7 +5316,7 @@ class TRTCCloud extends events_1.EventEmitter {
5326
5316
  }
5327
5317
  }
5328
5318
  catch (error) {
5329
- this.logger.warn(`callExperimentalAPI invalid JSON parameter`, error);
5319
+ this.logger.warn(`callExperimentalAPI invalid JSON parameter`, error, jsonStr);
5330
5320
  }
5331
5321
  }
5332
5322
  /**
@@ -25,7 +25,8 @@ export declare enum TRTCVideoResolution {
25
25
  TRTCVideoResolution_640_360 = 108,
26
26
  TRTCVideoResolution_960_540 = 110,
27
27
  TRTCVideoResolution_1280_720 = 112,
28
- TRTCVideoResolution_1920_1080 = 114
28
+ TRTCVideoResolution_1920_1080 = 114,
29
+ TRTCVideoResolution_2560_1440 = 116
29
30
  }
30
31
  export declare enum TRTCVideoResolutionMode {
31
32
  TRTCVideoResolutionModeLandscape = 0,
@@ -22,52 +22,48 @@ const util_1 = require("./Renderer/util");
22
22
  * @enum {Number}
23
23
  */
24
24
  const TRTCVideoResolution_HACK_JSDOC = {
25
- /// 宽高比1:1
26
- /** [C] 建议码率80kbps */
25
+ /** 宽高比 1:1;分辨率 120x120;建议码率(VideoCall)80kbps; 建议码率(LIVE)120kbps。 */
27
26
  TRTCVideoResolution_120_120: 1,
28
- /** [C] 建议码率100kbps */
27
+ /** 宽高比 1:1 分辨率 160x160;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps。 */
29
28
  TRTCVideoResolution_160_160: 3,
30
- /** [C] 建议码率200kbps */
29
+ /** 宽高比 1:1;分辨率 270x270;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps。 */
31
30
  TRTCVideoResolution_270_270: 5,
32
- /** [C] 建议码率350kbps */
31
+ /** 宽高比 1:1;分辨率 480x480;建议码率(VideoCall)350kbps; 建议码率(LIVE)500kbps。 */
33
32
  TRTCVideoResolution_480_480: 7,
34
- /// 宽高比4:3
35
- /** [C] 建议码率100kbps */
33
+ /** 宽高比4:3;分辨率 160x120;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps。 */
36
34
  TRTCVideoResolution_160_120: 50,
37
- /** [C] 建议码率150kbps */
35
+ /** 宽高比 4:3;分辨率 240x180;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps。 */
38
36
  TRTCVideoResolution_240_180: 52,
39
- /** [C] 建议码率200kbps */
37
+ /** 宽高比 4:3;分辨率 280x210;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps。 */
40
38
  TRTCVideoResolution_280_210: 54,
41
- /** [C] 建议码率250kbps */
39
+ /** 宽高比 4:3;分辨率 320x240;建议码率(VideoCall)250kbps; 建议码率(LIVE)375kbps。 */
42
40
  TRTCVideoResolution_320_240: 56,
43
- /** [C] 建议码率300kbps */
41
+ /** 宽高比 4:3;分辨率 400x300;建议码率(VideoCall)300kbps; 建议码率(LIVE)450kbps。 */
44
42
  TRTCVideoResolution_400_300: 58,
45
- /** [C] 建议码率400kbps */
43
+ /** 宽高比 4:3;分辨率 480x360;建议码率(VideoCall)400kbps; 建议码率(LIVE)600kbps。 */
46
44
  TRTCVideoResolution_480_360: 60,
47
- /** [C] 建议码率600kbps */
45
+ /** 宽高比 4:3;分辨率 640x480;建议码率(VideoCall)600kbps; 建议码率(LIVE)900kbps。 */
48
46
  TRTCVideoResolution_640_480: 62,
49
- /** [C] 建议码率1000kbps */
47
+ /** 宽高比 4:3;分辨率 960x720;建议码率(VideoCall)1000kbps; 建议码率(LIVE)1500kbps。 */
50
48
  TRTCVideoResolution_960_720: 64,
51
- /// 宽高比16:9
52
- /** [C] 建议码率150kbps */
49
+ /** 宽高比 16:9;分辨率 160x90;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps。*/
53
50
  TRTCVideoResolution_160_90: 100,
54
- /** [C] 建议码率200kbps */
51
+ /** 宽高比 16:9;分辨率 256x144;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps。 */
55
52
  TRTCVideoResolution_256_144: 102,
56
- /** [C] 建议码率250kbps */
53
+ /** 宽高比 16:9;分辨率 320x180;建议码率(VideoCall)250kbps; 建议码率(LIVE)400kbps。 */
57
54
  TRTCVideoResolution_320_180: 104,
58
- /** [C] 建议码率350kbps */
55
+ /**宽高比 16:9;分辨率 480x270;建议码率(VideoCall)350kbps; 建议码率(LIVE)550kbps。 */
59
56
  TRTCVideoResolution_480_270: 106,
60
- /** [C] 建议码率550kbps */
57
+ /** 宽高比 16:9;分辨率 640x360;建议码率(VideoCall)500kbps; 建议码率(LIVE)900kbps。 */
61
58
  TRTCVideoResolution_640_360: 108,
62
- /** [C] 建议码率850kbps */
59
+ /** 宽高比 16:9;分辨率 960x540;建议码率(VideoCall)850kbps; 建议码率(LIVE)1300kbps。 */
63
60
  TRTCVideoResolution_960_540: 110,
64
- /**
65
- * [C] 摄像头采集 - 建议码率1200kbps<br>
66
- * [S] 屏幕分享 - 建议码率 低清:1000kbps 高清:1600kbps
67
- */
61
+ /** 宽高比 16:9;分辨率 1280x720;建议码率(VideoCall)1200kbps; 建议码率(LIVE)1800kbps。 */
68
62
  TRTCVideoResolution_1280_720: 112,
69
- /** [S] 屏幕分享 - 建议码率2000kbps */
63
+ /** 宽高比 16:9;分辨率 1920x1080;建议码率(VideoCall)2000kbps; 建议码率(LIVE)3000kbps。 */
70
64
  TRTCVideoResolution_1920_1080: 114,
65
+ /** 宽高比 16:9;分辨率 2560x1440;建议码率(VideoCall)4000kbps; 建议码率(LIVE)6000kbps。 */
66
+ TRTCVideoResolution_2560_1440: 116,
71
67
  };
72
68
  var TRTCVideoResolution;
73
69
  (function (TRTCVideoResolution) {
@@ -91,6 +87,7 @@ var TRTCVideoResolution;
91
87
  TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_540"] = 110] = "TRTCVideoResolution_960_540";
92
88
  TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1280_720"] = 112] = "TRTCVideoResolution_1280_720";
93
89
  TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1920_1080"] = 114] = "TRTCVideoResolution_1920_1080";
90
+ TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_2560_1440"] = 116] = "TRTCVideoResolution_2560_1440";
94
91
  })(TRTCVideoResolution = exports.TRTCVideoResolution || (exports.TRTCVideoResolution = {}));
95
92
  /**
96
93
  * 视频分辨率模式
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trtc-electron-sdk",
3
- "version": "12.6.706-beta.0",
3
+ "version": "12.7.706-beta.1",
4
4
  "description": "trtc electron sdk",
5
5
  "main": "./liteav/index.js",
6
6
  "types": "./liteav/index.d.ts",
@@ -1,46 +0,0 @@
1
- /// <reference types="node" />
2
- import { EventEmitter } from 'events';
3
- import { TRTCVideoRotation } from './trtc_define';
4
- export declare enum PlayerEvents {
5
- onVodPlayerStarted = "onVodPlayerStarted",
6
- onVodPlayerProgress = "onVodPlayerProgress",
7
- onVodPlayerPaused = "onVodPlayerPaused",
8
- onVodPlayerResumed = "onVodPlayerResumed",
9
- onVodPlayerStoped = "onVodPlayerStoped",
10
- onVodPlayerError = "onVodPlayerError"
11
- }
12
- export declare class VodPlayer extends EventEmitter {
13
- private renderer;
14
- private nativeVodPlayer;
15
- private mediaFilePath;
16
- private repeat;
17
- private view;
18
- private isStarted;
19
- private pixelLength;
20
- private pixelFormat;
21
- private vodPlayerVideoBuffer;
22
- constructor(mediaFilePath: string, repeat: boolean);
23
- setVodPlayerView(view: HTMLElement): void;
24
- start(): void;
25
- pause(): void;
26
- resume(): void;
27
- stop(): void;
28
- seek(msPos: number): void;
29
- getDuration(): number;
30
- getWidth(): number;
31
- getHeight(): number;
32
- mute(mute: boolean): void;
33
- setVolume(volume: number): void;
34
- attachTRTC(): void;
35
- detachTRTC(): void;
36
- publishVideo(): void;
37
- publishAudio(): void;
38
- unpublishVideo(): void;
39
- unpublishAudio(): void;
40
- setVodPlayerDataCallback(): void;
41
- setVodPlayerEventCallback(): void;
42
- _renderVodVideoFrame(data: any, width: number, height: number, timestamp: number, rotation: TRTCVideoRotation): void;
43
- handleVideoSizeChange(userId: string, streamType: number, width: number, height: number): void;
44
- _initRender(view: HTMLElement): void;
45
- destroyRender(): void;
46
- }
@@ -1,194 +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
- exports.VodPlayer = exports.PlayerEvents = void 0;
7
- const events_1 = require("events");
8
- const Renderer_1 = require("./Renderer");
9
- const trtc_define_1 = require("./trtc_define");
10
- const logger_1 = __importDefault(require("./logger"));
11
- const util_1 = require("./Renderer/util");
12
- const NodeTRTCEngine = require('../build/Release/trtc_electron_sdk.node');
13
- const DEFAULT_VIDEO_WIDTH = 640;
14
- const DEFAULT_VIDEO_HEIGHT = 360;
15
- var PlayerEvents;
16
- (function (PlayerEvents) {
17
- PlayerEvents["onVodPlayerStarted"] = "onVodPlayerStarted";
18
- PlayerEvents["onVodPlayerProgress"] = "onVodPlayerProgress";
19
- PlayerEvents["onVodPlayerPaused"] = "onVodPlayerPaused";
20
- PlayerEvents["onVodPlayerResumed"] = "onVodPlayerResumed";
21
- PlayerEvents["onVodPlayerStoped"] = "onVodPlayerStoped";
22
- PlayerEvents["onVodPlayerError"] = "onVodPlayerError";
23
- })(PlayerEvents = exports.PlayerEvents || (exports.PlayerEvents = {}));
24
- class VodPlayer extends events_1.EventEmitter {
25
- constructor(mediaFilePath, repeat) {
26
- super();
27
- this.nativeVodPlayer = new NodeTRTCEngine.NodeVodPlayer(mediaFilePath, repeat);
28
- this.mediaFilePath = mediaFilePath;
29
- this.repeat = repeat;
30
- this.view = null;
31
- this.isStarted = false;
32
- this.vodPlayerVideoBuffer = new trtc_define_1.VideoBufferInfo();
33
- this.pixelLength = 1.5;
34
- this.pixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
35
- this.setVodPlayerEventCallback();
36
- }
37
- setVodPlayerView(view) {
38
- this.view = view;
39
- this._initRender(this.view);
40
- }
41
- start() {
42
- this.nativeVodPlayer.streamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
43
- this.vodPlayerVideoBuffer.buffer = (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength);
44
- this.nativeVodPlayer.id = (0, util_1.generateUniqueId)();
45
- this.nativeVodPlayer.pixelFormat = this.pixelFormat;
46
- this.nativeVodPlayer.width = DEFAULT_VIDEO_WIDTH;
47
- this.nativeVodPlayer.height = DEFAULT_VIDEO_HEIGHT;
48
- this.nativeVodPlayer.setVideoBuffer('', this.vodPlayerVideoBuffer.buffer, this.nativeVodPlayer.streamType, this.nativeVodPlayer.width, this.nativeVodPlayer.height, this.nativeVodPlayer.pixelFormat, this.nativeVodPlayer.id);
49
- this.setVodPlayerDataCallback();
50
- if (!this.isStarted) {
51
- this.nativeVodPlayer.start();
52
- }
53
- this.isStarted = true;
54
- }
55
- pause() {
56
- this.nativeVodPlayer.pause();
57
- }
58
- resume() {
59
- this.nativeVodPlayer.resume();
60
- }
61
- stop() {
62
- this.isStarted = false;
63
- this.nativeVodPlayer.stop();
64
- if (this.vodPlayerVideoBuffer.buffer) {
65
- this.nativeVodPlayer.setVideoBuffer('', this.vodPlayerVideoBuffer.buffer, this.nativeVodPlayer.streamType, 0, 0, this.nativeVodPlayer.pixelFormat, 0);
66
- this.vodPlayerVideoBuffer.buffer = null;
67
- this.vodPlayerVideoBuffer.id = 0;
68
- }
69
- }
70
- seek(msPos) {
71
- this.nativeVodPlayer.seek(msPos);
72
- }
73
- getDuration() {
74
- return this.nativeVodPlayer.getDuration();
75
- }
76
- getWidth() {
77
- return this.nativeVodPlayer.getWidth();
78
- }
79
- getHeight() {
80
- return this.nativeVodPlayer.getHeight();
81
- }
82
- mute(mute) {
83
- this.nativeVodPlayer.mute(mute);
84
- }
85
- setVolume(volume) {
86
- this.nativeVodPlayer.setVolume(volume);
87
- }
88
- attachTRTC() {
89
- this.nativeVodPlayer.attachTRTC();
90
- }
91
- detachTRTC() {
92
- this.nativeVodPlayer.detachTRTC();
93
- }
94
- publishVideo() {
95
- this.nativeVodPlayer.publishVideo();
96
- }
97
- publishAudio() {
98
- this.nativeVodPlayer.publishAudio();
99
- }
100
- unpublishVideo() {
101
- this.nativeVodPlayer.unpublishVideo();
102
- }
103
- unpublishAudio() {
104
- this.nativeVodPlayer.unpublishAudio();
105
- }
106
- setVodPlayerDataCallback() {
107
- this.nativeVodPlayer.setDataCallback((args) => {
108
- const [id, type, width, height, timestamp, rotation, valid, bufferId] = args;
109
- if (valid === true) {
110
- this._renderVodVideoFrame(this.vodPlayerVideoBuffer.buffer, width, height, timestamp, rotation);
111
- }
112
- else {
113
- this.handleVideoSizeChange(id, type, width, height);
114
- }
115
- });
116
- }
117
- setVodPlayerEventCallback() {
118
- this.nativeVodPlayer.setEventCallback((args) => {
119
- const key = args[0];
120
- const data = args[1];
121
- switch (key) {
122
- case 'onVodPlayerStarted':
123
- this.emit(key, data.msLength);
124
- break;
125
- case 'onVodPlayerProgress':
126
- this.emit(key, data.msPos);
127
- break;
128
- case 'onVodPlayerPaused':
129
- this.emit(key);
130
- break;
131
- case 'onVodPlayerResumed':
132
- this.emit(key);
133
- break;
134
- case 'onVodPlayerStoped':
135
- this.emit(key, data.reason);
136
- break;
137
- case 'onVodPlayerError':
138
- this.emit(key, data.error);
139
- break;
140
- default:
141
- break;
142
- }
143
- });
144
- }
145
- _renderVodVideoFrame(data, width, height, timestamp, rotation) {
146
- if (!this.renderer || !this.view) {
147
- return;
148
- }
149
- if (data) {
150
- const newData = data.slice(0); // Electron 12 及以下版本,来自底层的帧数据必须复制一次,否则 WebGL 渲染阶段会奔溃
151
- const realRotation = rotation * 90; //ratation是0, 1, 2, 3. 绘制内部使用0, 90, 180, 270
152
- this.renderer.drawFrame({
153
- data: newData,
154
- width,
155
- height,
156
- timestamp,
157
- rotation: realRotation,
158
- isNeedRotate: false,
159
- });
160
- }
161
- }
162
- handleVideoSizeChange(userId, streamType, width, height) {
163
- if (this.vodPlayerVideoBuffer.width !== width || this.vodPlayerVideoBuffer.height !== height) {
164
- this.vodPlayerVideoBuffer.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength);
165
- this.vodPlayerVideoBuffer.id = (0, util_1.generateUniqueId)();
166
- this.vodPlayerVideoBuffer.width = width;
167
- this.vodPlayerVideoBuffer.height = height;
168
- this.vodPlayerVideoBuffer.pixelFormat = this.pixelFormat;
169
- this.nativeVodPlayer.setVideoBuffer(userId, this.vodPlayerVideoBuffer.buffer, streamType, width, height, this.vodPlayerVideoBuffer.pixelFormat, this.vodPlayerVideoBuffer.id);
170
- }
171
- }
172
- _initRender(view) {
173
- if (this.renderer) {
174
- this.destroyRender();
175
- }
176
- view.innerHTML = ''; // 事先清空一下,避免画面叠加
177
- this.renderer = (0, Renderer_1.createRenderer)(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420, view, {
178
- type: Renderer_1.RenderType.Video,
179
- onContextLost: () => {
180
- this.renderer = (0, Renderer_1.createRenderer)(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420, view, { type: Renderer_1.RenderType.Canvas2D });
181
- },
182
- });
183
- }
184
- destroyRender() {
185
- try {
186
- this.renderer.destroy();
187
- this.renderer = null;
188
- }
189
- catch (err) {
190
- logger_1.default.error('[VodPlayer]destroyRender failed:', err);
191
- }
192
- }
193
- }
194
- exports.VodPlayer = VodPlayer;