trtc-electron-sdk 11.3.502-beta.4 → 11.3.502-beta.5
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.
- package/liteav/LocalMediaTranscoder/index.d.ts +2 -2
- package/liteav/LocalMediaTranscoder/index.js +20 -8
- package/liteav/Renderer/Canvas3DRenderer/index.d.ts +5 -1
- package/liteav/Renderer/Canvas3DRenderer/index.js +43 -21
- package/liteav/Renderer/index.d.ts +10 -1
- package/liteav/Renderer/index.js +17 -5
- package/liteav/trtc.d.ts +1 -0
- package/liteav/trtc.js +51 -8
- package/liteav/vod_player.js +6 -1
- package/package.json +1 -1
|
@@ -402,9 +402,9 @@ declare class TRTCLocalMediaTranscoder extends EventEmitter {
|
|
|
402
402
|
removeImageSource(path: string): void;
|
|
403
403
|
/**
|
|
404
404
|
* 设置本地混流转码视频预览节点
|
|
405
|
-
* @param
|
|
405
|
+
* @param view {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
|
|
406
406
|
*/
|
|
407
|
-
setMixedVideoRenderView(
|
|
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
|
|
519
|
+
* @param view {HTMLElement | null} - 如果传入的是 HTML 元素,必须是块元素;传入 null 时,会停止视频预览
|
|
520
520
|
*/
|
|
521
|
-
setMixedVideoRenderView(
|
|
522
|
-
if (
|
|
523
|
-
if (this.container ===
|
|
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 =
|
|
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 =
|
|
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
|
}
|
|
@@ -12,7 +12,11 @@ declare class Canvas3dRenderer implements IRenderer {
|
|
|
12
12
|
private i420Width;
|
|
13
13
|
private i420Height;
|
|
14
14
|
private i420Rotation;
|
|
15
|
-
|
|
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;
|
|
@@ -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 =
|
|
16
|
-
this.i420Height =
|
|
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,22 +76,28 @@ class Canvas3dRenderer {
|
|
|
69
76
|
this.canvas = document.createElement('canvas');
|
|
70
77
|
this.viewWrapper.appendChild(this.canvas);
|
|
71
78
|
this.viewContainer.appendChild(this.viewWrapper);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
if (this.
|
|
76
|
-
this.
|
|
77
|
-
|
|
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
|
-
|
|
82
|
-
this.
|
|
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, _b;
|
|
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) {
|
|
@@ -93,12 +106,13 @@ class Canvas3dRenderer {
|
|
|
93
106
|
else {
|
|
94
107
|
console.warn("trtc: Canvas3DRenderer unbind error: remove canvas error", this.canvas, this.viewWrapper);
|
|
95
108
|
}
|
|
109
|
+
(_b = this.canvas) === null || _b === void 0 ? void 0 : _b.removeEventListener("webglcontextlost", this._handleContextLost);
|
|
96
110
|
this.canvas = null;
|
|
97
111
|
if (this.viewWrapper && this.viewContainer && this.viewWrapper.parentElement === this.viewContainer) {
|
|
98
112
|
this.viewContainer.removeChild(this.viewWrapper);
|
|
99
113
|
}
|
|
100
114
|
else {
|
|
101
|
-
console.warn("trtc: Canvas3DRenderer unbind error: remove viewWrapper error", this.viewWrapper, this.viewContainer, (
|
|
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);
|
|
102
116
|
}
|
|
103
117
|
this.viewContainer = null;
|
|
104
118
|
}
|
|
@@ -124,14 +138,21 @@ class Canvas3dRenderer {
|
|
|
124
138
|
if (width <= 0 || height <= 0) {
|
|
125
139
|
throw new Error(`wrong video parameter width:${width} or height:${height}`);
|
|
126
140
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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");
|
|
135
156
|
}
|
|
136
157
|
if (this.viewWrapper && this.canvas3DRenderer) {
|
|
137
158
|
this._updateCanvasStyle({
|
|
@@ -213,6 +234,7 @@ class Canvas3dRenderer {
|
|
|
213
234
|
this.unbind();
|
|
214
235
|
this.viewWrapper = null;
|
|
215
236
|
currentCreatedCount--;
|
|
237
|
+
this.onContextLost = null;
|
|
216
238
|
}
|
|
217
239
|
}
|
|
218
240
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { TRTCVideoPixelFormat } from '../trtc_define';
|
|
2
2
|
import IRenderer from './IRenderer';
|
|
3
|
-
export declare
|
|
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';
|
package/liteav/Renderer/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
@@ -2271,6 +2271,7 @@ declare class TRTCCloud extends EventEmitter {
|
|
|
2271
2271
|
private _getRendererMap;
|
|
2272
2272
|
private _onRenderFrame;
|
|
2273
2273
|
private _onRealRender;
|
|
2274
|
+
private _checkAndDeleteExistingRenderer;
|
|
2274
2275
|
private _createVideoRenderer;
|
|
2275
2276
|
private _initRenderer;
|
|
2276
2277
|
private _destroyRenderer;
|
package/liteav/trtc.js
CHANGED
|
@@ -4152,12 +4152,30 @@ class TRTCCloud extends events_1.EventEmitter {
|
|
|
4152
4152
|
// 创建渲染器时 view 参数传了 null,只推流或者拉流,本地不渲染
|
|
4153
4153
|
}
|
|
4154
4154
|
}
|
|
4155
|
-
|
|
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
|
+
// 事先清空一下,避免画面叠加
|
|
4156
4173
|
if (view.childElementCount > 0) {
|
|
4157
4174
|
console.warn("trtc: clear HTML element content:", view);
|
|
4158
4175
|
}
|
|
4159
|
-
view
|
|
4160
|
-
|
|
4176
|
+
this._checkAndDeleteExistingRenderer(view, key);
|
|
4177
|
+
view.innerHTML = '';
|
|
4178
|
+
const renderer = (0, Renderer_1.createRenderer)(this.pixelFormat, view, options);
|
|
4161
4179
|
if (key === this.getKey(LOCAL_USER_VIDEO_ID, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig)) {
|
|
4162
4180
|
renderer.setContentMode(this.localFillMode);
|
|
4163
4181
|
}
|
|
@@ -4170,10 +4188,25 @@ class TRTCCloud extends events_1.EventEmitter {
|
|
|
4170
4188
|
return renderer;
|
|
4171
4189
|
}
|
|
4172
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
|
+
});
|
|
4173
4206
|
let rendererMap = this.videoRendererMap.get(key);
|
|
4174
4207
|
if (rendererMap) {
|
|
4175
4208
|
rendererMap.forEach((value, innerKey, map) => {
|
|
4176
|
-
if (
|
|
4209
|
+
if (validViews.indexOf(innerKey) === -1 || !value.isValid(innerKey)) {
|
|
4177
4210
|
try {
|
|
4178
4211
|
value.destroy();
|
|
4179
4212
|
map.delete(innerKey);
|
|
@@ -4183,17 +4216,27 @@ class TRTCCloud extends events_1.EventEmitter {
|
|
|
4183
4216
|
}
|
|
4184
4217
|
}
|
|
4185
4218
|
});
|
|
4186
|
-
|
|
4219
|
+
validViews.forEach((view) => {
|
|
4187
4220
|
if (!(rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.has(view))) {
|
|
4188
|
-
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
|
+
});
|
|
4189
4227
|
rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.set(view, renderer);
|
|
4190
4228
|
}
|
|
4191
4229
|
});
|
|
4192
4230
|
}
|
|
4193
4231
|
else {
|
|
4194
4232
|
rendererMap = new Map();
|
|
4195
|
-
|
|
4196
|
-
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
|
+
});
|
|
4197
4240
|
rendererMap === null || rendererMap === void 0 ? void 0 : rendererMap.set(view, renderer);
|
|
4198
4241
|
});
|
|
4199
4242
|
}
|
package/liteav/vod_player.js
CHANGED
|
@@ -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 {
|