trtc-electron-sdk 11.2.118-beta.2 → 11.3.502-alpha.0

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.
@@ -402,9 +402,9 @@ declare class TRTCLocalMediaTranscoder extends EventEmitter {
402
402
  removeImageSource(path: string): void;
403
403
  /**
404
404
  * 设置本地混流转码视频预览节点
405
- * @param el {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
405
+ * @param view {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
406
406
  */
407
- setMixedVideoRenderView(el: HTMLElement | null): void;
407
+ setMixedVideoRenderView(view: HTMLElement | null): void;
408
408
  private setMixedVideoFrameRenderCallback;
409
409
  private unsetMixedVideoFrameRenderCallback;
410
410
  private setEventCallback;
@@ -516,11 +516,11 @@ class TRTCLocalMediaTranscoder extends events_1.EventEmitter {
516
516
  }
517
517
  /**
518
518
  * 设置本地混流转码视频预览节点
519
- * @param el {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
519
+ * @param view {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
520
520
  */
521
- setMixedVideoRenderView(el) {
522
- if (el && el instanceof HTMLElement) {
523
- if (this.container === el) {
521
+ setMixedVideoRenderView(view) {
522
+ if (view && view instanceof HTMLElement) {
523
+ if (this.container === view) {
524
524
  return; // 重复在同一个 HTML 节点内渲染,不用处理,直接退出
525
525
  }
526
526
  else if (this.renderer) {
@@ -528,13 +528,25 @@ class TRTCLocalMediaTranscoder extends events_1.EventEmitter {
528
528
  this.renderer.destroy();
529
529
  this.renderer = null;
530
530
  // 重新记录渲染的 HTML 节点并创建渲染器
531
- this.container = el;
532
- this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container);
531
+ this.container = view;
532
+ this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container, {
533
+ type: Renderer_1.RenderType.WebGL,
534
+ onContextLost: () => {
535
+ this.container = view;
536
+ this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container, { type: Renderer_1.RenderType.Video });
537
+ },
538
+ });
533
539
  }
534
540
  else {
535
541
  // 第一次设置渲染的 HTML 节点,并创建渲染器,设置渲染回调
536
- this.container = el;
537
- this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container);
542
+ this.container = view;
543
+ this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container, {
544
+ type: Renderer_1.RenderType.WebGL,
545
+ onContextLost: () => {
546
+ this.container = view;
547
+ this.renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, this.container, { type: Renderer_1.RenderType.Video });
548
+ },
549
+ });
538
550
  this.setMixedVideoFrameRenderCallback();
539
551
  }
540
552
  }
@@ -19,6 +19,7 @@ declare class Canvas2dRenderer implements IRenderer {
19
19
  private _drawFrameBGRA;
20
20
  private _updateCanvasStyle;
21
21
  private _correctI420Data;
22
+ isValid(viewContainer: HTMLElement): boolean;
22
23
  destroy(): void;
23
24
  }
24
25
  export default Canvas2dRenderer;
@@ -41,9 +41,13 @@ class Canvas2dRenderer {
41
41
  }
42
42
  }
43
43
  unbind() {
44
+ var _a;
44
45
  if (this.viewWrapper && this.viewContainer && this.viewWrapper.parentElement === this.viewContainer) {
45
46
  this.viewContainer.removeChild(this.viewWrapper);
46
47
  }
48
+ else {
49
+ console.warn("trtc: Canvas2DRenderer unbind error: remove viewWrapper error", this.viewWrapper, this.viewContainer, (_a = this.viewContainer) === null || _a === void 0 ? void 0 : _a.parentElement);
50
+ }
47
51
  this.viewContainer = null;
48
52
  this.yuv = null;
49
53
  }
@@ -209,6 +213,10 @@ class Canvas2dRenderer {
209
213
  }
210
214
  return data;
211
215
  }
216
+ isValid(viewContainer) {
217
+ var _a;
218
+ return viewContainer === this.viewContainer && this.viewContainer === ((_a = this.viewWrapper) === null || _a === void 0 ? void 0 : _a.parentElement);
219
+ }
212
220
  destroy() {
213
221
  this.unbind();
214
222
  this.viewWrapper = null;
@@ -12,7 +12,11 @@ declare class Canvas3dRenderer implements IRenderer {
12
12
  private i420Width;
13
13
  private i420Height;
14
14
  private i420Rotation;
15
- constructor(pixelFormat: TRTCVideoPixelFormat, view: HTMLElement);
15
+ private onContextLost;
16
+ constructor(pixelFormat: TRTCVideoPixelFormat, view: HTMLElement, options: {
17
+ onContextLost: (() => void) | null;
18
+ });
19
+ private _handleContextLost;
16
20
  private _createCanvas3DRenderer;
17
21
  setContentMode(mode: TRTCVideoFillMode): void;
18
22
  private bind;
@@ -22,6 +26,7 @@ declare class Canvas3dRenderer implements IRenderer {
22
26
  private _drawFrameRGBA;
23
27
  private _drawFrameBGRA;
24
28
  private _updateCanvasStyle;
29
+ isValid(viewContainer: HTMLElement): boolean;
25
30
  destroy(): void;
26
31
  }
27
32
  export default Canvas3dRenderer;
@@ -11,9 +11,9 @@ const I420Canvas3DRenderer_1 = __importDefault(require("./I420Canvas3DRenderer")
11
11
  const UP_LIMIT_COUNT = 16;
12
12
  let currentCreatedCount = 0;
13
13
  class Canvas3dRenderer {
14
- constructor(pixelFormat, view) {
15
- this.i420Width = 0;
16
- this.i420Height = 0;
14
+ constructor(pixelFormat, view, options) {
15
+ this.i420Width = 640;
16
+ this.i420Height = 360;
17
17
  this.i420Rotation = 0;
18
18
  if (currentCreatedCount < UP_LIMIT_COUNT) {
19
19
  currentCreatedCount = currentCreatedCount + 1;
@@ -38,8 +38,15 @@ class Canvas3dRenderer {
38
38
  this.canvas = null;
39
39
  this.cacheCanvasOptions = {};
40
40
  this.canvas3DRenderer = null;
41
+ this.onContextLost = options.onContextLost || null;
42
+ this._handleContextLost = this._handleContextLost.bind(this);
41
43
  this.bind(view);
42
44
  }
45
+ _handleContextLost(e) {
46
+ console.warn("trtc: _handleContextLost:", e);
47
+ this.onContextLost && this.onContextLost();
48
+ this.destroy();
49
+ }
43
50
  _createCanvas3DRenderer() {
44
51
  if (this.canvas) {
45
52
  try {
@@ -69,31 +76,44 @@ class Canvas3dRenderer {
69
76
  this.canvas = document.createElement('canvas');
70
77
  this.viewWrapper.appendChild(this.canvas);
71
78
  this.viewContainer.appendChild(this.viewWrapper);
72
- // I420 WebGL 渲染有些特殊,视频宽高发生变化时,需要重新创建 canvas
73
- if (this.pixelFormat === trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420) {
74
- // 初始化时,i420Width i420Height 为 0,所以不会创建渲染器
75
- if (this.i420Width || this.i420Height) {
76
- this.canvas.width = this.i420Width;
77
- this.canvas.height = this.i420Height;
79
+ this.canvas.addEventListener("webglcontextlost", this._handleContextLost);
80
+ try {
81
+ // I420 WebGL 渲染有些特殊,视频宽高发生变化时,需要重新创建 canvas
82
+ if (this.pixelFormat === trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420) {
83
+ if (this.i420Width || this.i420Height) {
84
+ this.canvas.width = this.i420Width;
85
+ this.canvas.height = this.i420Height;
86
+ this.canvas3DRenderer = this._createCanvas3DRenderer();
87
+ }
88
+ }
89
+ else {
78
90
  this.canvas3DRenderer = this._createCanvas3DRenderer();
79
91
  }
80
92
  }
81
- else {
82
- this.canvas3DRenderer = this._createCanvas3DRenderer();
93
+ catch (e) {
94
+ this.canvas.removeEventListener("webglcontextlost", this._handleContextLost);
95
+ throw e;
83
96
  }
84
97
  }
85
98
  }
86
99
  unbind() {
87
- var _a;
100
+ var _a, _b, _c;
88
101
  (_a = this.canvas3DRenderer) === null || _a === void 0 ? void 0 : _a.destroy();
89
102
  this.canvas3DRenderer = null;
90
103
  if (this.canvas && this.viewWrapper && this.canvas.parentElement === this.viewWrapper) {
91
104
  this.viewWrapper.removeChild(this.canvas);
92
105
  }
106
+ else {
107
+ console.warn("trtc: Canvas3DRenderer unbind error: remove canvas error", this.canvas, this.viewWrapper);
108
+ }
109
+ (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener("webglcontextlost", this._handleContextLost);
93
110
  this.canvas = null;
94
111
  if (this.viewWrapper && this.viewContainer && this.viewWrapper.parentElement === this.viewContainer) {
95
112
  this.viewContainer.removeChild(this.viewWrapper);
96
113
  }
114
+ else {
115
+ console.warn("trtc: Canvas3DRenderer unbind error: remove viewWrapper error", this.viewWrapper, this.viewContainer, (_c = this.viewContainer) === null || _c === void 0 ? void 0 : _c.parentElement);
116
+ }
97
117
  this.viewContainer = null;
98
118
  }
99
119
  drawFrame(frameData) {
@@ -118,14 +138,21 @@ class Canvas3dRenderer {
118
138
  if (width <= 0 || height <= 0) {
119
139
  throw new Error(`wrong video parameter width:${width} or height:${height}`);
120
140
  }
121
- // I420 WebGL 渲染有些特殊,视频宽高发生变化时,需要重新创建 canvas
122
- if (width !== this.i420Width || height !== this.i420Height || rotation !== this.i420Rotation) {
123
- const tempViewContainer = this.viewContainer;
124
- this.unbind();
125
- this.i420Width = width;
126
- this.i420Height = height;
127
- this.i420Rotation = rotation;
128
- this.bind(tempViewContainer);
141
+ try {
142
+ // I420 WebGL 渲染有些特殊,视频宽高发生变化时,需要重新创建 canvas
143
+ if (width !== this.i420Width || height !== this.i420Height || rotation !== this.i420Rotation) {
144
+ const tempViewContainer = this.viewContainer;
145
+ this.unbind();
146
+ this.i420Width = width;
147
+ this.i420Height = height;
148
+ this.i420Rotation = rotation;
149
+ this.bind(tempViewContainer);
150
+ }
151
+ }
152
+ catch (e) {
153
+ this.onContextLost && this.onContextLost();
154
+ this.destroy();
155
+ throw new Error("re-create WebGL context failed");
129
156
  }
130
157
  if (this.viewWrapper && this.canvas3DRenderer) {
131
158
  this._updateCanvasStyle({
@@ -198,11 +225,16 @@ class Canvas3dRenderer {
198
225
  throw new Error('canvas element not exist');
199
226
  }
200
227
  }
228
+ isValid(viewContainer) {
229
+ var _a;
230
+ return viewContainer === this.viewContainer && this.viewContainer === ((_a = this.viewWrapper) === null || _a === void 0 ? void 0 : _a.parentElement);
231
+ }
201
232
  destroy() {
202
233
  if (this.viewWrapper) {
203
234
  this.unbind();
204
235
  this.viewWrapper = null;
205
236
  currentCreatedCount--;
237
+ this.onContextLost = null;
206
238
  }
207
239
  }
208
240
  }
@@ -3,6 +3,7 @@ import { TFrameData } from './types';
3
3
  export interface IRenderer {
4
4
  drawFrame(frameData: TFrameData): void;
5
5
  setContentMode(mode: TRTCVideoFillMode): void;
6
+ isValid(viewContainer: HTMLElement): boolean;
6
7
  destroy(): void;
7
8
  }
8
9
  export default IRenderer;
@@ -20,6 +20,7 @@ declare class VideoRenderer implements IRenderer {
20
20
  _drawFrameNonH264(frameData: TFrameData): Promise<void>;
21
21
  _getPixelFormat(): string;
22
22
  _updateVideoStyle(options: TCanvasImageSourceStyleOptions): void;
23
+ isValid(viewContainer: HTMLElement): boolean;
23
24
  destroy(): void;
24
25
  }
25
26
  export default VideoRenderer;
@@ -52,9 +52,13 @@ class VideoRenderer {
52
52
  }
53
53
  }
54
54
  unbind() {
55
+ var _a;
55
56
  if (this.viewWrapper && this.viewContainer && this.viewWrapper.parentElement === this.viewContainer) {
56
57
  this.viewContainer.removeChild(this.viewWrapper);
57
58
  }
59
+ else {
60
+ console.warn("trtc: Canvas3DRenderer unbind error: remove viewWrapper error", this.viewWrapper, this.viewContainer, (_a = this.viewContainer) === null || _a === void 0 ? void 0 : _a.parentElement);
61
+ }
58
62
  this.viewContainer = null;
59
63
  }
60
64
  drawFrame(frameData) {
@@ -140,6 +144,10 @@ class VideoRenderer {
140
144
  throw new Error('video element not exist');
141
145
  }
142
146
  }
147
+ isValid(viewContainer) {
148
+ var _a;
149
+ return viewContainer === this.viewContainer && this.viewContainer === ((_a = this.viewWrapper) === null || _a === void 0 ? void 0 : _a.parentElement);
150
+ }
143
151
  destroy() {
144
152
  this.unbind();
145
153
  this.viewWrapper = null;
@@ -1,5 +1,14 @@
1
1
  import { TRTCVideoPixelFormat } from '../trtc_define';
2
2
  import IRenderer from './IRenderer';
3
- export declare function createRenderer(pixelFormat: TRTCVideoPixelFormat, view: HTMLElement): IRenderer;
3
+ export declare enum RenderType {
4
+ WebGL = "WebGL",
5
+ Canvas2D = "Canvas2D",
6
+ Video = "Video"
7
+ }
8
+ export interface RendererOptions {
9
+ onContextLost?: () => void;
10
+ type?: RenderType;
11
+ }
12
+ export declare function createRenderer(pixelFormat: TRTCVideoPixelFormat, view: HTMLElement, options: RendererOptions): IRenderer;
4
13
  export * from './IRenderer';
5
14
  export * from './types';
@@ -17,17 +17,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.createRenderer = void 0;
20
+ exports.createRenderer = exports.RenderType = void 0;
21
21
  const Canvas3DRenderer_1 = __importDefault(require("./Canvas3DRenderer"));
22
22
  const Canvas2DRenderer_1 = __importDefault(require("./Canvas2DRenderer"));
23
23
  const VideoRenderer_1 = __importDefault(require("./VideoRenderer"));
24
24
  const util_1 = require("./util");
25
25
  const isWebGLSupported = (0, util_1.isSupportWebGL)();
26
- function createRenderer(pixelFormat, view) {
26
+ var RenderType;
27
+ (function (RenderType) {
28
+ RenderType["WebGL"] = "WebGL";
29
+ RenderType["Canvas2D"] = "Canvas2D";
30
+ RenderType["Video"] = "Video";
31
+ })(RenderType = exports.RenderType || (exports.RenderType = {}));
32
+ function createRenderer(pixelFormat, view, options) {
33
+ if (options && !options.type) {
34
+ options.type = RenderType.WebGL;
35
+ }
27
36
  let renderer = null;
28
- if (isWebGLSupported) {
37
+ if (isWebGLSupported && options.type === RenderType.WebGL) {
29
38
  try {
30
- renderer = new Canvas3DRenderer_1.default(pixelFormat, view);
39
+ renderer = new Canvas3DRenderer_1.default(pixelFormat, view, {
40
+ onContextLost: options.onContextLost || null,
41
+ });
31
42
  console.log('trtc: created WebGL render');
32
43
  }
33
44
  catch (err) {
@@ -37,7 +48,8 @@ function createRenderer(pixelFormat, view) {
37
48
  }
38
49
  if (!renderer) {
39
50
  // @ts-ignore
40
- if (window.VideoFrame && window.VideoDecoder) {
51
+ if (window.VideoFrame && window.VideoDecoder
52
+ && (options.type === RenderType.WebGL || options.type === RenderType.Video)) {
41
53
  // Electron 15+ 版本支持 WebCodec API
42
54
  renderer = new VideoRenderer_1.default(pixelFormat, view);
43
55
  console.log('trtc: created Video render');
package/liteav/trtc.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
3
  import { VodPlayer } from './vod_player';
4
- import { AudioMusicParam, Rect, TRTCAppScene, TRTCAudioEffectParam, TRTCAudioQuality, TRTCBeautyStyle, TRTCDeviceState, TRTCDeviceType, TRTCLogLevel, TRTCRenderParams, TRTCRoleType, TRTCSwitchRoomParam, TRTCVideoBufferType, TRTCVideoFillMode, TRTCVideoFrame, TRTCVideoPixelFormat, TRTCVideoRotation, TRTCVideoStreamType, TRTCWaterMarkSrcType, PluginInfo, TRTCAudioRecordingParams, TRTCScreenCaptureSourceInfo, TRTCScreenCaptureProperty, TRTCSpeedTestParams, TRTCRecordType, TRTCDeviceInfo, TRTCCameraCaptureParams, TRTCImageBuffer } from './trtc_define';
4
+ import { AudioMusicParam, Rect, TRTCAppScene, TRTCAudioEffectParam, TRTCAudioQuality, TRTCBeautyStyle, TRTCDeviceState, TRTCDeviceType, TRTCLogLevel, TRTCRenderParams, TRTCRoleType, TRTCSwitchRoomParam, TRTCVideoBufferType, TRTCVideoFillMode, TRTCVideoPixelFormat, TRTCVideoRotation, TRTCVideoStreamType, TRTCWaterMarkSrcType, PluginInfo, TRTCAudioRecordingParams, TRTCScreenCaptureSourceInfo, TRTCScreenCaptureProperty, TRTCSpeedTestParams, TRTCRecordType, TRTCDeviceInfo, TRTCCameraCaptureParams, TRTCImageBuffer, TRTCInitConfig } from './trtc_define';
5
5
  export * from './trtc_define';
6
6
  export * from './trtc_code';
7
7
  export * from './vod_player';
@@ -20,7 +20,6 @@ export * from './vod_player';
20
20
  declare class TRTCCloud extends EventEmitter {
21
21
  private rtcCloud;
22
22
  private videoRendererMap;
23
- private firstVideoFrameList;
24
23
  private playStreamType;
25
24
  private localFillMode;
26
25
  private remoteFillModeMap;
@@ -49,12 +48,12 @@ declare class TRTCCloud extends EventEmitter {
49
48
  private audioQuality;
50
49
  private bgmId;
51
50
  private playAudioEffectIdList;
52
- constructor();
51
+ constructor(config?: TRTCInitConfig);
53
52
  /**
54
53
  * 创建 TRTCCloud 对象单例
55
54
  * @returns {TRTCCloud}
56
55
  */
57
- static getTRTCShareInstance(): TRTCCloud;
56
+ static getTRTCShareInstance(config?: TRTCInitConfig): TRTCCloud;
58
57
  /**
59
58
  * 释放 TRTCCloud 对象并清理资源
60
59
  */
@@ -112,8 +111,9 @@ declare class TRTCCloud extends EventEmitter {
112
111
  * @event TRTCCallback#onWarning
113
112
  * @param {Number} warningCode - 警告码
114
113
  * @param {String} warningMsg - 警告信息
114
+ * @param {Any} extra - 补充信息
115
115
  */
116
- handleOnWarning(warningCode: number, warningMsg: string, extra: number): void;
116
+ handleOnWarning(warningCode: number, warningMsg: string, extra: any): void;
117
117
  /**
118
118
  * 已加入房间的回调
119
119
  *
@@ -2269,8 +2269,9 @@ declare class TRTCCloud extends EventEmitter {
2269
2269
  getKey(uid: string, type: TRTCVideoStreamType): string;
2270
2270
  setEnableRenderFrame(enable: boolean): void;
2271
2271
  private _getRendererMap;
2272
- _onRenderFrame(uid: string, type: TRTCVideoStreamType, width: number, height: number, timestamp: number, rotation: number, data: any): void;
2272
+ private _onRenderFrame;
2273
2273
  private _onRealRender;
2274
+ private _checkAndDeleteExistingRenderer;
2274
2275
  private _createVideoRenderer;
2275
2276
  private _initRenderer;
2276
2277
  private _destroyRenderer;
@@ -2283,14 +2284,15 @@ declare class TRTCCloud extends EventEmitter {
2283
2284
  * @private
2284
2285
  * @throws {Error}
2285
2286
  */
2286
- _writefile(path: string, data: any): void;
2287
- _writeLog(info: string): void;
2288
- _onUserRenderCallback(callback: (userid: string, streamType: TRTCVideoStreamType, videoframe: TRTCVideoFrame) => void, format: TRTCVideoPixelFormat, userid: string, streamType: TRTCVideoStreamType, width: number, height: number, timestamp: number, rotation: number, data: any): void;
2289
- _initImageData(width: number, height: number): void;
2290
- _YUV2RGBA(width: number, height: number, buffer: ArrayBufferLike): Uint8ClampedArray;
2291
- _BGRA2RGBA(data: ArrayBuffer, width: number, height: number): Uint8ClampedArray;
2292
- _RGBA2BGRA(data: ArrayBuffer, width: number, height: number): Uint8ClampedArray;
2293
- _isMacPlatform(): boolean;
2287
+ private _writefile;
2288
+ private _writeLog;
2289
+ private _onUserRenderCallback;
2290
+ private _initImageData;
2291
+ private _YUV2RGBA;
2292
+ private _BGRA2RGBA;
2293
+ private _RGBA2BGRA;
2294
+ private _isMacPlatform;
2295
+ private _setRemoteVideoBuffer;
2294
2296
  }
2295
2297
  export default TRTCCloud;
2296
2298
  export * from './LocalMediaTranscoder';
package/liteav/trtc.js CHANGED
@@ -130,9 +130,6 @@ const getComponentNO = function () {
130
130
  case 'TUIRoom':
131
131
  componentNO = '5';
132
132
  break;
133
- case 'TUIRoomKit':
134
- componentNO = '16';
135
- break;
136
133
  default:
137
134
  break;
138
135
  }
@@ -154,15 +151,14 @@ let oriRtcCloud = null;
154
151
  */
155
152
  class TRTCCloud extends events_1.EventEmitter {
156
153
  // 兼容 8.0 以下版本, 记录内部状态变量 --end
157
- constructor() {
154
+ constructor(config) {
158
155
  super();
159
156
  const componentNO = getComponentNO();
160
- oriRtcCloud = new trtc.NodeRTCCloud(pkg.version, componentNO);
157
+ oriRtcCloud = new trtc.NodeRTCCloud(Object.assign({ jsVersion: pkg.version, componentNO }, config));
161
158
  this.rtcCloud = Object.assign({}, oriRtcCloud, {
162
159
  onlineLog: undefined
163
160
  });
164
161
  this.videoRendererMap = new Map();
165
- this.firstVideoFrameList = [];
166
162
  this.playStreamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
167
163
  this.pixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
168
164
  this.pixelLength = 1.5;
@@ -187,7 +183,7 @@ class TRTCCloud extends events_1.EventEmitter {
187
183
  this.isScreenCapturing = false;
188
184
  this.isCaptureLocalVideoEnabled = false;
189
185
  this.videoProcessBufferType = trtc_define_1.TRTCVideoBufferType.TRTCVideoBufferType_Buffer;
190
- this.videoProcessPixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_RGBA32;
186
+ this.videoProcessPixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
191
187
  this.initEventHandler();
192
188
  console.log('trtc:constructor pixelFormat:' + this.pixelFormat + '|sdk version:' + pkg.version +
193
189
  '|native sdk version:' + this.rtcCloud.getSDKVersion());
@@ -206,9 +202,9 @@ class TRTCCloud extends events_1.EventEmitter {
206
202
  * 创建 TRTCCloud 对象单例
207
203
  * @returns {TRTCCloud}
208
204
  */
209
- static getTRTCShareInstance() {
205
+ static getTRTCShareInstance(config) {
210
206
  if (!trtcCloudInstance) {
211
- trtcCloudInstance = new TRTCCloud();
207
+ trtcCloudInstance = new TRTCCloud(config);
212
208
  }
213
209
  return trtcCloudInstance;
214
210
  }
@@ -255,7 +251,6 @@ class TRTCCloud extends events_1.EventEmitter {
255
251
  * 清理资源
256
252
  */
257
253
  destroy() {
258
- this.firstVideoFrameList = [];
259
254
  this.playAudioEffectIdList = [];
260
255
  this.remoteFillModeMap.clear();
261
256
  // this.destroyLocalMediaTranscoder();
@@ -478,6 +473,7 @@ class TRTCCloud extends events_1.EventEmitter {
478
473
  * @event TRTCCallback#onWarning
479
474
  * @param {Number} warningCode - 警告码
480
475
  * @param {String} warningMsg - 警告信息
476
+ * @param {Any} extra - 补充信息
481
477
  */
482
478
  handleOnWarning(warningCode, warningMsg, extra) {
483
479
  this.fire('onWarning', warningCode, warningMsg, extra);
@@ -525,7 +521,6 @@ class TRTCCloud extends events_1.EventEmitter {
525
521
  * @param {Number} reason - 离开房间原因,0:主动调用 exitRoom 退房;1:被服务器踢出当前房间;2:当前房间整个被解散。
526
522
  */
527
523
  handleOnExitRoom(reason) {
528
- this.firstVideoFrameList = [];
529
524
  this.fire('onExitRoom', reason);
530
525
  }
531
526
  /**
@@ -635,11 +630,6 @@ class TRTCCloud extends events_1.EventEmitter {
635
630
  */
636
631
  handleOnUserVideoAvailable(userId, available) {
637
632
  if (available == 0) {
638
- if (this._isMacPlatform()) {
639
- this.firstVideoFrameList = this.firstVideoFrameList.filter(function (item) {
640
- return !(userId === item.uid && item.type !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub);
641
- });
642
- }
643
633
  const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
644
634
  if (remoteUserVideoBuffers) {
645
635
  if (remoteUserVideoBuffers.big) {
@@ -666,11 +656,6 @@ class TRTCCloud extends events_1.EventEmitter {
666
656
  */
667
657
  handleOnUserSubStreamAvailable(userId, available) {
668
658
  if (available == 0) {
669
- if (this._isMacPlatform()) {
670
- this.firstVideoFrameList = this.firstVideoFrameList.filter(function (item) {
671
- return !(userId === item.uid && item.type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub);
672
- });
673
- }
674
659
  if (screenVideoBufferMap.has(userId)) {
675
660
  const targetVideoBuffer = screenVideoBufferMap.get(userId);
676
661
  if (targetVideoBuffer && targetVideoBuffer.buffer) {
@@ -707,6 +692,9 @@ class TRTCCloud extends events_1.EventEmitter {
707
692
  * @param {Number} height - 画面高度
708
693
  */
709
694
  handleOnFirstVideoFrame(userId, streamType, width, height) {
695
+ if (userId) {
696
+ this._setRemoteVideoBuffer(userId, streamType);
697
+ }
710
698
  this.fire('onFirstVideoFrame', userId, streamType, width, height);
711
699
  }
712
700
  /**
@@ -1808,9 +1796,6 @@ class TRTCCloud extends events_1.EventEmitter {
1808
1796
  const key = this.getKey(LOCAL_USER_VIDEO_ID, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
1809
1797
  this._destroyRenderer(key, null);
1810
1798
  this.rtcCloud.stopLocalPreview();
1811
- this.firstVideoFrameList = this.firstVideoFrameList.filter(function (item) {
1812
- return !('' === item.uid && item.type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
1813
- });
1814
1799
  if (localVideoBuffer.buffer) {
1815
1800
  this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, 0, 0, localVideoBuffer.pixelFormat, localVideoBuffer.id);
1816
1801
  localVideoBuffer.buffer = null;
@@ -1920,47 +1905,7 @@ class TRTCCloud extends events_1.EventEmitter {
1920
1905
  this._initRenderer(key, views);
1921
1906
  // view 为 null 时,可能启动了自定义渲染,所以 Buffer 还是要创建,否则自定义渲染就拿不到数据;
1922
1907
  // view 非 null 时,当然必须创建 Buffer
1923
- const videoBufferInfo = new trtc_define_1.VideoBufferInfo({
1924
- userId: userId,
1925
- id: (0, util_1.generateUniqueId)(),
1926
- streamType: streamType,
1927
- width: DEFAULT_VIDEO_WIDTH,
1928
- height: DEFAULT_VIDEO_HEIGHT,
1929
- pixelFormat: this.pixelFormat,
1930
- });
1931
- if (streamType !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
1932
- const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
1933
- if (!remoteUserVideoBuffers) {
1934
- // Buffer 不存在时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1935
- if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig) {
1936
- remoteVideoBufferMap.set(userId, { big: videoBufferInfo });
1937
- }
1938
- else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall) {
1939
- remoteVideoBufferMap.set(userId, { small: videoBufferInfo });
1940
- }
1941
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1942
- }
1943
- else {
1944
- if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && !remoteUserVideoBuffers.big) {
1945
- remoteUserVideoBuffers.big = videoBufferInfo;
1946
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1947
- }
1948
- else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && !remoteUserVideoBuffers.small) {
1949
- remoteUserVideoBuffers.small = videoBufferInfo;
1950
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1951
- }
1952
- }
1953
- }
1954
- else {
1955
- // 远端屏幕分享
1956
- // Buffer 为 null 时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1957
- let targetVideoBuffer = screenVideoBufferMap.get(userId);
1958
- if (!targetVideoBuffer || !targetVideoBuffer.buffer) {
1959
- targetVideoBuffer = videoBufferInfo;
1960
- this.rtcCloud.setSubVideoBuffer(targetVideoBuffer.userId, targetVideoBuffer.buffer, targetVideoBuffer.streamType, targetVideoBuffer.width, targetVideoBuffer.height, targetVideoBuffer.pixelFormat, targetVideoBuffer.id);
1961
- screenVideoBufferMap.set(userId, targetVideoBuffer);
1962
- }
1963
- }
1908
+ this._setRemoteVideoBuffer(userId, streamType);
1964
1909
  this.addRemoteVideoRenderCallback(userId);
1965
1910
  this.rtcCloud.startRemoteView(userId, streamType);
1966
1911
  }
@@ -2358,29 +2303,7 @@ class TRTCCloud extends events_1.EventEmitter {
2358
2303
  * - TRTCVideoStreamTypeSmall: 小画面视频流
2359
2304
  */
2360
2305
  setRemoteVideoStreamType(userId, streamType) {
2361
- const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
2362
- if (remoteUserVideoBuffers) {
2363
- const videoBufferInfo = new trtc_define_1.VideoBufferInfo({
2364
- userId: userId,
2365
- id: (0, util_1.generateUniqueId)(),
2366
- streamType: streamType,
2367
- width: DEFAULT_VIDEO_WIDTH,
2368
- height: DEFAULT_VIDEO_HEIGHT,
2369
- pixelFormat: this.pixelFormat,
2370
- });
2371
- if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && !remoteUserVideoBuffers.big) {
2372
- remoteUserVideoBuffers.big = videoBufferInfo;
2373
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
2374
- }
2375
- else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && !remoteUserVideoBuffers.small) {
2376
- remoteUserVideoBuffers.small = videoBufferInfo;
2377
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
2378
- }
2379
- else {
2380
- videoBufferInfo.buffer = null;
2381
- videoBufferInfo.id = 0;
2382
- }
2383
- }
2306
+ this._setRemoteVideoBuffer(userId, streamType);
2384
2307
  this.rtcCloud.setRemoteVideoStreamType(userId, streamType);
2385
2308
  }
2386
2309
  /**
@@ -3826,9 +3749,6 @@ class TRTCCloud extends events_1.EventEmitter {
3826
3749
  const key = this.getKey(CAMERA_DEVICE_TEST_VIEW, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
3827
3750
  this._destroyRenderer(key, null);
3828
3751
  this.rtcCloud.stopCameraDeviceTest();
3829
- this.firstVideoFrameList = this.firstVideoFrameList.filter(function (item) {
3830
- return !('' === item.uid && item.type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
3831
- });
3832
3752
  if (cameraTestVideoBuffer.buffer) {
3833
3753
  this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, 0, 0, cameraTestVideoBuffer.pixelFormat, cameraTestVideoBuffer.id);
3834
3754
  cameraTestVideoBuffer.buffer = null;
@@ -4041,7 +3961,6 @@ class TRTCCloud extends events_1.EventEmitter {
4041
3961
  * @ignore
4042
3962
  */
4043
3963
  initPluginManager(options) {
4044
- const defaultPixelFormat = !this._isMacPlatform() ? trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_RGBA32 : trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32;
4045
3964
  if (options) {
4046
3965
  if (options.bufferType && options.bufferType === trtc_define_1.TRTCVideoBufferType.TRTCVideoBufferType_Texture) {
4047
3966
  this.videoProcessBufferType = options.bufferType;
@@ -4053,12 +3972,12 @@ class TRTCCloud extends events_1.EventEmitter {
4053
3972
  this.videoProcessPixelFormat = options.pixelFormat;
4054
3973
  }
4055
3974
  else {
4056
- this.videoProcessPixelFormat = defaultPixelFormat;
3975
+ this.videoProcessPixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
4057
3976
  }
4058
3977
  }
4059
3978
  }
4060
3979
  else {
4061
- this.videoProcessPixelFormat = defaultPixelFormat;
3980
+ this.videoProcessPixelFormat = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
4062
3981
  this.videoProcessBufferType = trtc_define_1.TRTCVideoBufferType.TRTCVideoBufferType_Buffer;
4063
3982
  }
4064
3983
  this.rtcCloud.initializePluginManager(this.videoProcessPixelFormat, this.videoProcessBufferType);
@@ -4137,18 +4056,6 @@ class TRTCCloud extends events_1.EventEmitter {
4137
4056
  return this.videoRendererMap.get(key);
4138
4057
  }
4139
4058
  _onRenderFrame(uid, type, width, height, timestamp, rotation, data) {
4140
- // 由于 mac 监听自定义渲染回调后不会回调 onFirstVideoFrame ,所以在这里自己实现回调 onFirstVideoFrame
4141
- if (this._isMacPlatform()) {
4142
- setImmediate(() => {
4143
- const index = this.firstVideoFrameList.findIndex(function (item) {
4144
- return uid === item.uid && type === item.type;
4145
- });
4146
- if (index === -1) {
4147
- this.emit('onFirstVideoFrame', uid, type, width, height);
4148
- this.firstVideoFrameList.push({ uid: uid, type: type });
4149
- }
4150
- });
4151
- }
4152
4059
  if (uid.length == 0 && this.isCaptureLocalVideoEnabled) {
4153
4060
  this.fire(LOCAL_VIDEO_DATA, {
4154
4061
  uid: '', type, rotation, timestamp,
@@ -4242,12 +4149,33 @@ class TRTCCloud extends events_1.EventEmitter {
4242
4149
  });
4243
4150
  }
4244
4151
  else {
4245
- console.warn(`trtc: no video renderer for user: ${uid} streamType:${type}`);
4152
+ // 创建渲染器时 view 参数传了 null,只推流或者拉流,本地不渲染
4246
4153
  }
4247
4154
  }
4248
- _createVideoRenderer(view, key) {
4249
- view.innerHTML = ''; // 事先清空一下,避免画面叠加
4250
- const renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, view);
4155
+ _checkAndDeleteExistingRenderer(view, key) {
4156
+ this.videoRendererMap.forEach((rendererMap, existingKey) => {
4157
+ rendererMap.forEach((renderer, node, map) => {
4158
+ if (node === view && existingKey !== key) {
4159
+ try {
4160
+ console.warn(`trtc: existing video renderer for ${existingKey}, destroy and create for ${key}.`, view);
4161
+ renderer.destroy();
4162
+ map.delete(node);
4163
+ }
4164
+ catch (err) {
4165
+ console.error("trtc: _checkAndDeleteExistingRenderer destroy render error:", err);
4166
+ }
4167
+ }
4168
+ });
4169
+ });
4170
+ }
4171
+ _createVideoRenderer(view, key, options) {
4172
+ // 事先清空一下,避免画面叠加
4173
+ if (view.childElementCount > 0) {
4174
+ console.warn("trtc: clear HTML element content:", view);
4175
+ }
4176
+ this._checkAndDeleteExistingRenderer(view, key);
4177
+ view.innerHTML = '';
4178
+ const renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, view, options);
4251
4179
  if (key === this.getKey(LOCAL_USER_VIDEO_ID, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig)) {
4252
4180
  renderer.setContentMode(this.localFillMode);
4253
4181
  }
@@ -4260,30 +4188,55 @@ class TRTCCloud extends events_1.EventEmitter {
4260
4188
  return renderer;
4261
4189
  }
4262
4190
  _initRenderer(key, views) {
4191
+ const onContextLost = (key, view) => {
4192
+ const rendererMap = this.videoRendererMap.get(key);
4193
+ if (rendererMap) {
4194
+ const render = this._createVideoRenderer(view, key, { type: Renderer_1.RenderType.Video });
4195
+ rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.set(view, render);
4196
+ this.videoRendererMap.set(key, rendererMap);
4197
+ }
4198
+ };
4199
+ const validViews = views.filter(view => {
4200
+ const isValid = view && view instanceof HTMLElement;
4201
+ if (!isValid) {
4202
+ console.warn("trtc: create renderer failed due to invalid HTMLElement", view);
4203
+ }
4204
+ return isValid;
4205
+ });
4263
4206
  let rendererMap = this.videoRendererMap.get(key);
4264
4207
  if (rendererMap) {
4265
- rendererMap.forEach((value, key, map) => {
4266
- if (views.indexOf(key) === -1) {
4208
+ rendererMap.forEach((value, innerKey, map) => {
4209
+ if (validViews.indexOf(innerKey) === -1 || !value.isValid(innerKey)) {
4267
4210
  try {
4268
4211
  value.destroy();
4269
- map.delete(key);
4212
+ map.delete(innerKey);
4270
4213
  }
4271
4214
  catch (err) {
4272
4215
  console.error("trtc:_initRenderer destroy render error:", err);
4273
4216
  }
4274
4217
  }
4275
4218
  });
4276
- views.forEach((view) => {
4219
+ validViews.forEach((view) => {
4277
4220
  if (!(rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.has(view))) {
4278
- const renderer = this._createVideoRenderer(view, key);
4221
+ const renderer = this._createVideoRenderer(view, key, {
4222
+ type: Renderer_1.RenderType.WebGL,
4223
+ onContextLost: () => {
4224
+ onContextLost(key, view);
4225
+ },
4226
+ });
4279
4227
  rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.set(view, renderer);
4280
4228
  }
4281
4229
  });
4282
4230
  }
4283
4231
  else {
4284
4232
  rendererMap = new Map();
4285
- views.forEach((view) => {
4286
- const renderer = this._createVideoRenderer(view, key);
4233
+ validViews.forEach((view) => {
4234
+ const renderer = this._createVideoRenderer(view, key, {
4235
+ type: Renderer_1.RenderType.WebGL,
4236
+ onContextLost: () => {
4237
+ onContextLost(key, view);
4238
+ },
4239
+ });
4287
4240
  rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.set(view, renderer);
4288
4241
  });
4289
4242
  }
@@ -4440,6 +4393,57 @@ class TRTCCloud extends events_1.EventEmitter {
4440
4393
  _isMacPlatform() {
4441
4394
  return process.platform == 'darwin';
4442
4395
  }
4396
+ _setRemoteVideoBuffer(userId, streamType) {
4397
+ const videoBufferInfo = new trtc_define_1.VideoBufferInfo({
4398
+ userId: userId,
4399
+ id: (0, util_1.generateUniqueId)(),
4400
+ streamType: streamType,
4401
+ width: DEFAULT_VIDEO_WIDTH,
4402
+ height: DEFAULT_VIDEO_HEIGHT,
4403
+ pixelFormat: this.pixelFormat,
4404
+ });
4405
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
4406
+ let screenVideoBuffer = screenVideoBufferMap.get(userId);
4407
+ switch (streamType) {
4408
+ case trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig:
4409
+ if (!remoteUserVideoBuffers) {
4410
+ remoteVideoBufferMap.set(userId, { big: videoBufferInfo });
4411
+ }
4412
+ else if (!remoteUserVideoBuffers.big) {
4413
+ remoteUserVideoBuffers.big = videoBufferInfo;
4414
+ }
4415
+ else {
4416
+ videoBufferInfo.buffer = null;
4417
+ }
4418
+ videoBufferInfo.buffer && this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
4419
+ break;
4420
+ case trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall:
4421
+ if (!remoteUserVideoBuffers) {
4422
+ remoteVideoBufferMap.set(userId, { small: videoBufferInfo });
4423
+ }
4424
+ else if (!remoteUserVideoBuffers.small) {
4425
+ remoteUserVideoBuffers.small = videoBufferInfo;
4426
+ }
4427
+ else {
4428
+ videoBufferInfo.buffer = null;
4429
+ }
4430
+ videoBufferInfo.buffer && this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
4431
+ break;
4432
+ case trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub:
4433
+ if (!screenVideoBuffer) {
4434
+ screenVideoBuffer = videoBufferInfo;
4435
+ this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, screenVideoBuffer.width, screenVideoBuffer.height, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
4436
+ screenVideoBufferMap.set(userId, screenVideoBuffer);
4437
+ }
4438
+ else {
4439
+ videoBufferInfo.buffer = null;
4440
+ }
4441
+ break;
4442
+ default:
4443
+ videoBufferInfo.buffer = null;
4444
+ break;
4445
+ }
4446
+ }
4443
4447
  }
4444
4448
  class VideoRenderCallback {
4445
4449
  constructor() {
@@ -142,9 +142,9 @@ export declare class TRTCImageBuffer {
142
142
  * @param {TRTCImageBuffer} thumbBGRA - 缩略图内容
143
143
  * @param {TRTCImageBuffer} iconBGRA - 图标内容
144
144
  * @param {Boolean} isMinimizeWindow - 是否最小化窗口
145
- * @param {Number} width - 屏幕/窗口宽,单位:像素。目前仅支持微软 `Windows` 操作系统。
146
- * @param {Number} height - 屏幕/窗口高,单位:像素。目前仅支持微软 `Windows` 操作系统。
147
- * @param {Boolean} isMainScreen - 是否为主显示屏。目前仅支持微软 `Windows` 操作系统。
145
+ * @param {Number} width - 屏幕/窗口宽,单位:像素。
146
+ * @param {Number} height - 屏幕/窗口高,单位:像素。
147
+ * @param {Boolean} isMainScreen - 是否为主显示屏。
148
148
  *
149
149
  */
150
150
  export declare class TRTCScreenCaptureSourceInfo {
@@ -822,3 +822,16 @@ export declare class VideoBufferInfo {
822
822
  pixelFormat: TRTCVideoPixelFormat;
823
823
  });
824
824
  }
825
+ export interface TRTCInitConfig {
826
+ networkProxy?: {
827
+ host: string;
828
+ port: number;
829
+ username: string;
830
+ password: string;
831
+ config: {
832
+ supportHttps: boolean;
833
+ supportTcp: boolean;
834
+ supportUdp: boolean;
835
+ };
836
+ };
837
+ }
@@ -553,9 +553,9 @@ exports.TRTCImageBuffer = TRTCImageBuffer;
553
553
  * @param {TRTCImageBuffer} thumbBGRA - 缩略图内容
554
554
  * @param {TRTCImageBuffer} iconBGRA - 图标内容
555
555
  * @param {Boolean} isMinimizeWindow - 是否最小化窗口
556
- * @param {Number} width - 屏幕/窗口宽,单位:像素。目前仅支持微软 `Windows` 操作系统。
557
- * @param {Number} height - 屏幕/窗口高,单位:像素。目前仅支持微软 `Windows` 操作系统。
558
- * @param {Boolean} isMainScreen - 是否为主显示屏。目前仅支持微软 `Windows` 操作系统。
556
+ * @param {Number} width - 屏幕/窗口宽,单位:像素。
557
+ * @param {Number} height - 屏幕/窗口高,单位:像素。
558
+ * @param {Boolean} isMainScreen - 是否为主显示屏。
559
559
  *
560
560
  */
561
561
  class TRTCScreenCaptureSourceInfo {
@@ -1,4 +1,5 @@
1
1
  export declare function isNumber(args: any): boolean;
2
+ export declare function isString(args: any): boolean;
2
3
  export declare function isNull(args: any): boolean;
3
4
  export declare function isUndefined(args: any): boolean;
4
5
  export declare function isExist(args: any): boolean;
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isExist = exports.isUndefined = exports.isNull = exports.isNumber = void 0;
3
+ exports.isExist = exports.isUndefined = exports.isNull = exports.isString = exports.isNumber = void 0;
4
4
  function isNumber(args) {
5
5
  return typeof args === 'number';
6
6
  }
7
7
  exports.isNumber = isNumber;
8
+ function isString(args) {
9
+ return typeof args === 'string';
10
+ }
11
+ exports.isString = isString;
8
12
  function isNull(args) {
9
13
  return args === null;
10
14
  }
@@ -143,7 +143,12 @@ class VodPlayer extends events_1.EventEmitter {
143
143
  this.destroyRender();
144
144
  }
145
145
  view.innerHTML = ''; // 事先清空一下,避免画面叠加
146
- this.renderer = (0, Renderer_1.createRenderer)(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420, view);
146
+ this.renderer = (0, Renderer_1.createRenderer)(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420, view, {
147
+ type: Renderer_1.RenderType.WebGL,
148
+ onContextLost: () => {
149
+ this.renderer = (0, Renderer_1.createRenderer)(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420, view, { type: Renderer_1.RenderType.Video });
150
+ },
151
+ });
147
152
  }
148
153
  destroyRender() {
149
154
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trtc-electron-sdk",
3
- "version": "11.2.118-beta.2",
3
+ "version": "11.3.502-alpha.0",
4
4
  "description": "trtc electron sdk",
5
5
  "main": "./liteav/trtc.js",
6
6
  "types": "./liteav/trtc.d.ts",
@@ -15,7 +15,11 @@
15
15
  "semver": "^6.0.0",
16
16
  "signale": "^1.4.0",
17
17
  "yuv-buffer": "^1.0.0",
18
- "yuv-canvas": "^1.2.6"
18
+ "yuv-canvas": "^1.2.6",
19
+ "hpagent": "^1.2.0"
20
+ },
21
+ "peerDependencies": {
22
+ "electron": ">=4.0.0"
19
23
  },
20
24
  "devDependencies": {
21
25
  "@babel/cli": "^7.11.6",
@@ -35,6 +39,7 @@
35
39
  },
36
40
  "scripts": {
37
41
  "download": "node ./scripts/download.js",
42
+ "postdownload": "node ./scripts/postinstall.js",
38
43
  "install": "npm run download",
39
44
  "build": "npm run build:types && npm run build:js && npm run copy:types",
40
45
  "build:types": "rimraf ./types && tsc -p dtsconfig.json",
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
4
4
  const rimraf = require('rimraf');
5
5
  const signale = require('signale');
6
6
  const { exec } = require('child_process');
7
+ const { HttpsProxyAgent } = require('hpagent');
7
8
 
8
9
  const {
9
10
  readCliArgv,
@@ -11,6 +12,7 @@ const {
11
12
  detectOS,
12
13
  detectOwnVersion,
13
14
  detectOwnName,
15
+ readProxyUrlFromEnv,
14
16
  } = require('./utils');
15
17
  const { Platform } = require('./constant');
16
18
 
@@ -68,10 +70,24 @@ const main = () => {
68
70
  signale.info('Download Url =', downloadUrl, '\n');
69
71
 
70
72
  signale.pending('Downloading C++ addon Electron SDK...\n');
71
- download(downloadUrl, outputDir, {
73
+ const downloadOptions = {
72
74
  strip: 0,
73
75
  extract: true
74
- }).then(() => {
76
+ };
77
+ const proxyUrl = readProxyUrlFromEnv(downloadUrl);
78
+ if (proxyUrl) {
79
+ downloadOptions.agent = {
80
+ https: new HttpsProxyAgent({
81
+ keepAlive: true,
82
+ keepAliveMsecs: 1000,
83
+ maxSockets: 256,
84
+ maxFreeSockets: 256,
85
+ scheduling: 'lifo',
86
+ proxy: proxyUrl
87
+ })
88
+ }
89
+ }
90
+ download(downloadUrl, outputDir, downloadOptions).then(() => {
75
91
  signale.success(`Download finished - ${platform}`);
76
92
 
77
93
  fs.copySync(
@@ -126,9 +142,6 @@ const main = () => {
126
142
  );
127
143
  signale.success(`copy success! - mac ${anotherArch}`);
128
144
 
129
- // Mac 下完成文件下载后,执行该命令,同步文件到 Electron 目录下
130
- exec(`rsync -a ../../node_modules/trtc-electron-sdk/build/mac-framework/${archType}/ ../../node_modules/electron/dist/Electron.app/Contents/Frameworks`);
131
-
132
145
  rimraf.sync(outputDir);
133
146
  })
134
147
  .catch(err => {
@@ -180,4 +193,21 @@ const main = () => {
180
193
  });
181
194
  };
182
195
 
196
+
197
+ // function runScript(scriptPath, callback) {
198
+ // var invoked = false;
199
+ // var forkProcess = fork(scriptPath);
200
+ // forkProcess.on('error', function (err) {
201
+ // if (invoked) return;
202
+ // invoked = true;
203
+ // callback(err);
204
+ // });
205
+ // forkProcess.on('exit', function (code) {
206
+ // if (invoked) return;
207
+ // invoked = true;
208
+ // var err = code === 0 ? null : new Error('exit code ' + code);
209
+ // callback(err);
210
+ // });
211
+ // }
212
+
183
213
  main();
@@ -0,0 +1,40 @@
1
+ const { exec } = require('child_process');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const { arch, platform } = process;
5
+
6
+ function rsync() {
7
+ if (platform === 'darwin') {
8
+ const sourcePath = path.join(__dirname, `../../trtc-electron-sdk/build/mac-framework/${arch}/`);
9
+ const targetPath = path.join(__dirname, '../../electron/dist/Electron.app/Contents/Frameworks');
10
+ console.log(`sourcePath: ${sourcePath}`);
11
+ console.log(`targetPath: ${targetPath}`);
12
+
13
+ if (targetPath.indexOf("node_modules") === -1) {
14
+ // SDK 本身安装,不用同步动态库,直接退出
15
+ console.log(`trtc-electron-sdk self install do not need 'rsync'`);
16
+ return;
17
+ }
18
+
19
+ if (fs.existsSync(targetPath)) {
20
+ const command = `rsync -a ${sourcePath} ${targetPath}`;
21
+ console.log(command);
22
+ exec(command);
23
+ } else {
24
+ const errorMessage = `
25
+ 'trtc-electron-sdk' 安装未完成,请先确认 'Electron' 已安装,再执行 'npm install trtc-electron-sdk' 命令重新安装一次。
26
+ Failed to install trtc-electron-sdk correctly, please make sure that 'Electron' has been installed, then run 'npm install trtc-electron-sdk' command to try again.
27
+
28
+ more detail:
29
+ trtc-electron-sdk postinstall cwd: ${process.cwd()}
30
+ __dirname: ${__dirname}
31
+ sourcePath: ${sourcePath}
32
+ targetPath: ${targetPath}
33
+ `;
34
+ console.error(errorMessage);
35
+ // throw new Error(errorMessage);
36
+ }
37
+ }
38
+ }
39
+
40
+ rsync();
package/scripts/utils.js CHANGED
@@ -27,6 +27,13 @@ module.exports.readCliArgv = function() {
27
27
  return newArgv;
28
28
  };
29
29
 
30
+ module.exports.readProxyUrlFromEnv = function(downloadUrl) {
31
+ if (downloadUrl.indexOf('https') === 0) {
32
+ return process.env.https_proxy || ''
33
+ }
34
+ return process.env.http_proxy || '';
35
+ }
36
+
30
37
  module.exports.readArgvFromNpmEnv = function() {
31
38
  const result = {};
32
39
  if (process.env.npm_config_trtc_electron_arch) {