agora-electron-sdk 4.2.6 → 4.3.0-dev.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.
Files changed (172) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/js/Private/AgoraBase.js +139 -174
  3. package/js/Private/AgoraMediaBase.js +49 -20
  4. package/js/Private/AgoraMediaPlayerTypes.js +32 -23
  5. package/js/Private/IAgoraH265Transcoder.js +39 -0
  6. package/js/Private/IAgoraMediaStreamingSource.js +32 -32
  7. package/js/Private/IAgoraMusicContentCenter.js +19 -19
  8. package/js/Private/IAgoraRhythmPlayer.js +9 -9
  9. package/js/Private/IAgoraRtcEngine.js +12 -12
  10. package/js/Private/IAgoraSpatialAudio.js +3 -31
  11. package/js/Private/extension/IAgoraH265TranscoderExtension.js +2 -0
  12. package/js/Private/impl/AgoraMediaBaseImpl.js +26 -2
  13. package/js/Private/impl/IAgoraH265TranscoderImpl.js +119 -0
  14. package/js/Private/impl/IAgoraMediaEngineImpl.js +13 -13
  15. package/js/Private/impl/IAgoraMediaPlayerImpl.js +92 -74
  16. package/js/Private/impl/IAgoraMediaPlayerSourceImpl.js +12 -2
  17. package/js/Private/impl/IAgoraMediaRecorderImpl.js +2 -2
  18. package/js/Private/impl/IAgoraMusicContentCenterImpl.js +20 -20
  19. package/js/Private/impl/IAgoraRtcEngineExImpl.js +66 -84
  20. package/js/Private/impl/IAgoraRtcEngineImpl.js +456 -440
  21. package/js/Private/impl/IAgoraSpatialAudioImpl.js +157 -181
  22. package/js/Private/impl/IAudioDeviceManagerImpl.js +22 -22
  23. package/js/Private/internal/AgoraH265TranscoderInternal.js +86 -0
  24. package/js/Private/internal/AgoraMediaBaseInternal.js +34 -0
  25. package/js/Private/internal/IrisApiEngine.js +35 -20
  26. package/js/Private/internal/LocalSpatialAudioEngineInternal.js +0 -39
  27. package/js/Private/internal/MediaPlayerInternal.js +22 -21
  28. package/js/Private/internal/MusicContentCenterInternal.js +1 -4
  29. package/js/Private/internal/RtcEngineExInternal.js +101 -134
  30. package/js/Private/ti/AgoraMediaBase-ti.js +1 -1
  31. package/js/Private/ti/IAgoraH265Transcoder-ti.js +40 -0
  32. package/js/Private/ti/IAgoraMediaPlayerSource-ti.js +4 -2
  33. package/js/Private/ti/IAgoraMusicContentCenter-ti.js +5 -5
  34. package/js/Private/ti/IAgoraRtcEngine-ti.js +12 -11
  35. package/js/Renderer/AgoraView.js +28 -14
  36. package/js/Renderer/IRenderer.js +65 -17
  37. package/js/Renderer/IRendererManager.js +230 -0
  38. package/js/Renderer/RendererCache.js +170 -0
  39. package/js/Renderer/RendererManager.js +49 -460
  40. package/js/Renderer/WebGLRenderer/index.js +82 -234
  41. package/js/Renderer/YUVCanvasRenderer/index.js +27 -147
  42. package/js/Types.js +6 -6
  43. package/js/Utils.js +37 -88
  44. package/package.json +4 -3
  45. package/scripts/clean.js +12 -0
  46. package/scripts/synclib.js +8 -2
  47. package/ts/Private/AgoraBase.ts +225 -201
  48. package/ts/Private/AgoraMediaBase.ts +63 -25
  49. package/ts/Private/AgoraMediaPlayerTypes.ts +67 -24
  50. package/ts/Private/IAgoraH265Transcoder.ts +73 -0
  51. package/ts/Private/IAgoraLog.ts +1 -0
  52. package/ts/Private/IAgoraMediaEngine.ts +12 -7
  53. package/ts/Private/IAgoraMediaPlayer.ts +47 -21
  54. package/ts/Private/IAgoraMediaPlayerSource.ts +27 -6
  55. package/ts/Private/IAgoraMediaStreamingSource.ts +38 -37
  56. package/ts/Private/IAgoraMusicContentCenter.ts +20 -20
  57. package/ts/Private/IAgoraRhythmPlayer.ts +7 -6
  58. package/ts/Private/IAgoraRtcEngine.ts +407 -364
  59. package/ts/Private/IAgoraRtcEngineEx.ts +25 -61
  60. package/ts/Private/IAgoraSpatialAudio.ts +80 -191
  61. package/ts/Private/IAudioDeviceManager.ts +27 -14
  62. package/ts/Private/extension/IAgoraH265TranscoderExtension.ts +39 -0
  63. package/ts/Private/impl/AgoraMediaBaseImpl.ts +25 -1
  64. package/ts/Private/impl/IAgoraH265TranscoderImpl.ts +152 -0
  65. package/ts/Private/impl/IAgoraMediaEngineImpl.ts +13 -13
  66. package/ts/Private/impl/IAgoraMediaPlayerImpl.ts +110 -81
  67. package/ts/Private/impl/IAgoraMediaPlayerSourceImpl.ts +17 -2
  68. package/ts/Private/impl/IAgoraMediaRecorderImpl.ts +2 -2
  69. package/ts/Private/impl/IAgoraMusicContentCenterImpl.ts +21 -21
  70. package/ts/Private/impl/IAgoraRtcEngineExImpl.ts +71 -106
  71. package/ts/Private/impl/IAgoraRtcEngineImpl.ts +589 -572
  72. package/ts/Private/impl/IAgoraSpatialAudioImpl.ts +211 -218
  73. package/ts/Private/impl/IAudioDeviceManagerImpl.ts +22 -22
  74. package/ts/Private/internal/AgoraH265TranscoderInternal.ts +97 -0
  75. package/ts/Private/internal/AgoraMediaBaseInternal.ts +15 -0
  76. package/ts/Private/internal/IrisApiEngine.ts +42 -27
  77. package/ts/Private/internal/LocalSpatialAudioEngineInternal.ts +1 -86
  78. package/ts/Private/internal/MediaPlayerInternal.ts +20 -29
  79. package/ts/Private/internal/MusicContentCenterInternal.ts +1 -5
  80. package/ts/Private/internal/RtcEngineExInternal.ts +91 -204
  81. package/ts/Private/ti/AgoraMediaBase-ti.ts +1 -1
  82. package/ts/Private/ti/IAgoraH265Transcoder-ti.ts +16 -0
  83. package/ts/Private/ti/IAgoraMediaPlayerSource-ti.ts +4 -2
  84. package/ts/Private/ti/IAgoraMusicContentCenter-ti.ts +5 -5
  85. package/ts/Private/ti/IAgoraRtcEngine-ti.ts +12 -11
  86. package/ts/Renderer/AgoraView.ts +29 -19
  87. package/ts/Renderer/IRenderer.ts +71 -22
  88. package/ts/Renderer/IRendererManager.ts +273 -19
  89. package/ts/Renderer/RendererCache.ts +167 -0
  90. package/ts/Renderer/RendererManager.ts +62 -607
  91. package/ts/Renderer/WebGLRenderer/index.ts +117 -295
  92. package/ts/Renderer/YUVCanvasRenderer/index.ts +45 -198
  93. package/ts/Types.ts +17 -194
  94. package/ts/Utils.ts +36 -100
  95. package/types/Private/AgoraBase.d.ts +219 -200
  96. package/types/Private/AgoraBase.d.ts.map +1 -1
  97. package/types/Private/AgoraMediaBase.d.ts +63 -27
  98. package/types/Private/AgoraMediaBase.d.ts.map +1 -1
  99. package/types/Private/AgoraMediaPlayerTypes.d.ts +65 -24
  100. package/types/Private/AgoraMediaPlayerTypes.d.ts.map +1 -1
  101. package/types/Private/IAgoraH265Transcoder.d.ts +28 -0
  102. package/types/Private/IAgoraH265Transcoder.d.ts.map +1 -0
  103. package/types/Private/IAgoraLog.d.ts.map +1 -1
  104. package/types/Private/IAgoraMediaEngine.d.ts +11 -6
  105. package/types/Private/IAgoraMediaEngine.d.ts.map +1 -1
  106. package/types/Private/IAgoraMediaPlayer.d.ts +42 -20
  107. package/types/Private/IAgoraMediaPlayer.d.ts.map +1 -1
  108. package/types/Private/IAgoraMediaPlayerSource.d.ts +23 -6
  109. package/types/Private/IAgoraMediaPlayerSource.d.ts.map +1 -1
  110. package/types/Private/IAgoraMediaStreamingSource.d.ts.map +1 -1
  111. package/types/Private/IAgoraMusicContentCenter.d.ts +19 -19
  112. package/types/Private/IAgoraMusicContentCenter.d.ts.map +1 -1
  113. package/types/Private/IAgoraRhythmPlayer.d.ts +6 -6
  114. package/types/Private/IAgoraRhythmPlayer.d.ts.map +1 -1
  115. package/types/Private/IAgoraRtcEngine.d.ts +329 -293
  116. package/types/Private/IAgoraRtcEngine.d.ts.map +1 -1
  117. package/types/Private/IAgoraRtcEngineEx.d.ts +21 -53
  118. package/types/Private/IAgoraRtcEngineEx.d.ts.map +1 -1
  119. package/types/Private/IAgoraSpatialAudio.d.ts +56 -167
  120. package/types/Private/IAgoraSpatialAudio.d.ts.map +1 -1
  121. package/types/Private/IAudioDeviceManager.d.ts +27 -14
  122. package/types/Private/IAudioDeviceManager.d.ts.map +1 -1
  123. package/types/Private/extension/IAgoraH265TranscoderExtension.d.ts +24 -0
  124. package/types/Private/extension/IAgoraH265TranscoderExtension.d.ts.map +1 -0
  125. package/types/Private/impl/AgoraMediaBaseImpl.d.ts +5 -1
  126. package/types/Private/impl/AgoraMediaBaseImpl.d.ts.map +1 -1
  127. package/types/Private/impl/IAgoraH265TranscoderImpl.d.ts +15 -0
  128. package/types/Private/impl/IAgoraH265TranscoderImpl.d.ts.map +1 -0
  129. package/types/Private/impl/IAgoraMediaPlayerImpl.d.ts +6 -4
  130. package/types/Private/impl/IAgoraMediaPlayerImpl.d.ts.map +1 -1
  131. package/types/Private/impl/IAgoraMediaPlayerSourceImpl.d.ts.map +1 -1
  132. package/types/Private/impl/IAgoraRtcEngineExImpl.d.ts +2 -4
  133. package/types/Private/impl/IAgoraRtcEngineExImpl.d.ts.map +1 -1
  134. package/types/Private/impl/IAgoraRtcEngineImpl.d.ts +30 -25
  135. package/types/Private/impl/IAgoraRtcEngineImpl.d.ts.map +1 -1
  136. package/types/Private/impl/IAgoraSpatialAudioImpl.d.ts +20 -22
  137. package/types/Private/impl/IAgoraSpatialAudioImpl.d.ts.map +1 -1
  138. package/types/Private/internal/AgoraH265TranscoderInternal.d.ts +14 -0
  139. package/types/Private/internal/AgoraH265TranscoderInternal.d.ts.map +1 -0
  140. package/types/Private/internal/AgoraMediaBaseInternal.d.ts +8 -0
  141. package/types/Private/internal/AgoraMediaBaseInternal.d.ts.map +1 -0
  142. package/types/Private/internal/IrisApiEngine.d.ts +5 -2
  143. package/types/Private/internal/IrisApiEngine.d.ts.map +1 -1
  144. package/types/Private/internal/LocalSpatialAudioEngineInternal.d.ts +0 -15
  145. package/types/Private/internal/LocalSpatialAudioEngineInternal.d.ts.map +1 -1
  146. package/types/Private/internal/MediaPlayerInternal.d.ts.map +1 -1
  147. package/types/Private/internal/MusicContentCenterInternal.d.ts +0 -1
  148. package/types/Private/internal/MusicContentCenterInternal.d.ts.map +1 -1
  149. package/types/Private/internal/RtcEngineExInternal.d.ts +7 -13
  150. package/types/Private/internal/RtcEngineExInternal.d.ts.map +1 -1
  151. package/types/Private/ti/IAgoraH265Transcoder-ti.d.ts +8 -0
  152. package/types/Private/ti/IAgoraH265Transcoder-ti.d.ts.map +1 -0
  153. package/types/Private/ti/IAgoraMediaPlayerSource-ti.d.ts.map +1 -1
  154. package/types/Private/ti/IAgoraRtcEngine-ti.d.ts.map +1 -1
  155. package/types/Renderer/AgoraView.d.ts +4 -4
  156. package/types/Renderer/AgoraView.d.ts.map +1 -1
  157. package/types/Renderer/IRenderer.d.ts +11 -9
  158. package/types/Renderer/IRenderer.d.ts.map +1 -1
  159. package/types/Renderer/IRendererManager.d.ts +50 -12
  160. package/types/Renderer/IRendererManager.d.ts.map +1 -1
  161. package/types/Renderer/RendererCache.d.ts +36 -0
  162. package/types/Renderer/RendererCache.d.ts.map +1 -0
  163. package/types/Renderer/RendererManager.d.ts +13 -139
  164. package/types/Renderer/RendererManager.d.ts.map +1 -1
  165. package/types/Renderer/WebGLRenderer/index.d.ts +3 -18
  166. package/types/Renderer/WebGLRenderer/index.d.ts.map +1 -1
  167. package/types/Renderer/YUVCanvasRenderer/index.d.ts +4 -10
  168. package/types/Renderer/YUVCanvasRenderer/index.d.ts.map +1 -1
  169. package/types/Types.d.ts +11 -187
  170. package/types/Types.d.ts.map +1 -1
  171. package/types/Utils.d.ts +3 -20
  172. package/types/Utils.d.ts.map +1 -1
@@ -1,30 +1,14 @@
1
- import { ErrorCodeType } from '../Private/AgoraBase';
2
- import { RenderModeType, VideoSourceType } from '../Private/AgoraMediaBase';
3
1
  import {
4
- AgoraElectronBridge,
5
- Channel,
6
- ChannelIdMap,
7
- FormatRendererVideoConfig,
8
2
  RENDER_MODE,
9
- RenderConfig,
10
- RenderMap,
11
- RendererVideoConfig,
12
- ShareVideoFrame,
13
- UidMap,
14
- VideoFrameCacheConfig,
3
+ RendererCacheContext,
4
+ RendererContext,
5
+ RendererType,
15
6
  } from '../Types';
16
- import {
17
- AgoraEnv,
18
- formatConfigByVideoSourceType,
19
- getDefaultRendererVideoConfig,
20
- logDebug,
21
- logError,
22
- logInfo,
23
- logWarn,
24
- } from '../Utils';
7
+ import { isSupportWebGL } from '../Utils';
25
8
 
26
9
  import { IRenderer } from './IRenderer';
27
10
  import { IRendererManager } from './IRendererManager';
11
+ import { RendererCache } from './RendererCache';
28
12
  import { WebGLFallback, WebGLRenderer } from './WebGLRenderer';
29
13
  import { YUVCanvasRenderer } from './YUVCanvasRenderer';
30
14
 
@@ -35,621 +19,92 @@ export class RendererManager extends IRendererManager {
35
19
  /**
36
20
  * @ignore
37
21
  */
38
- isRendering = false;
39
- renderFps: number;
40
- /**
41
- * @ignore
42
- */
43
- videoFrameUpdateInterval?: NodeJS.Timer;
44
- /**
45
- * @ignore
46
- */
47
- renderers: RenderMap;
48
- /**
49
- * @ignore
50
- */
51
- renderMode?: RENDER_MODE;
52
- /**
53
- * @ignore
54
- */
55
- msgBridge: AgoraElectronBridge;
56
- /**
57
- * @ignore
58
- */
59
- defaultRenderConfig: RendererVideoConfig;
60
-
61
- constructor() {
62
- super();
63
- this.renderFps = 15;
64
- this.renderers = new Map();
65
- this.setRenderMode();
66
- this.msgBridge = AgoraEnv.AgoraElectronBridge;
67
- this.defaultRenderConfig = {
68
- rendererOptions: {
69
- contentMode: RenderModeType.RenderModeFit,
70
- mirror: false,
71
- },
72
- };
73
- }
74
-
75
- /**
76
- * Sets the channel mode of the current audio file.
77
- * In a stereo music file, the left and right channels can store different audio data. According to your needs, you can set the channel mode to original mode, left channel mode, right channel mode, or mixed channel mode. For example, in the KTV scenario, the left channel of the music file stores the musical accompaniment, and the right channel stores the singing voice. If you only need to listen to the accompaniment, call this method to set the channel mode of the music file to left channel mode; if you need to listen to the accompaniment and the singing voice at the same time, call this method to set the channel mode to mixed channel mode.Call this method after calling open .This method only applies to stereo audio files.
78
- *
79
- * @param mode The channel mode. See AudioDualMonoMode .
80
- *
81
- * @returns
82
- * 0: Success.< 0: Failure.
83
- */
84
- public setRenderMode(mode?: RENDER_MODE) {
85
- if (mode === undefined) {
86
- this.renderMode = this.checkWebglEnv()
87
- ? RENDER_MODE.WEBGL
88
- : RENDER_MODE.SOFTWARE;
89
- return;
90
- }
91
-
92
- if (mode !== this.renderMode) {
93
- this.renderMode = mode;
94
- logInfo(
95
- 'setRenderMode: new render mode will take effect only if new view bind to render'
96
- );
97
- }
98
- }
99
-
100
- /**
101
- * @ignore
102
- */
103
- public setFPS(fps: number) {
104
- this.renderFps = fps;
105
- this.restartRender();
106
- }
107
-
108
- /**
109
- * @ignore
110
- */
111
- public setRenderOption(
112
- view: HTMLElement,
113
- contentMode = RenderModeType.RenderModeFit,
114
- mirror: boolean = false
115
- ): void {
116
- if (!view) {
117
- logError('setRenderOption: view not exist', view);
118
- }
119
- this.forEachStream(({ renders }) => {
120
- renders?.forEach((render) => {
121
- if (render.equalsElement(view)) {
122
- render.setRenderOption({ contentMode, mirror });
123
- }
124
- });
125
- });
126
- }
127
-
128
- /**
129
- * @ignore
130
- */
131
- public setRenderOptionByConfig(rendererConfig: RendererVideoConfig): number {
132
- const {
133
- uid,
134
- channelId,
135
- rendererOptions,
136
- videoSourceType,
137
- }: FormatRendererVideoConfig =
138
- getDefaultRendererVideoConfig(rendererConfig);
139
-
140
- const renderList = this.getRenderers({ uid, channelId, videoSourceType });
141
- renderList
142
- ? renderList
143
- .filter((renderItem) => {
144
- if (rendererConfig.view) {
145
- return renderItem.equalsElement(rendererConfig.view);
146
- } else {
147
- return true;
148
- }
149
- })
150
- .forEach((renderItem) => renderItem.setRenderOption(rendererOptions))
151
- : logWarn(
152
- `RenderStreamType: ${videoSourceType} channelId:${channelId} uid:${uid} have no render view, you need to call this api after setView`
153
- );
154
- return ErrorCodeType.ErrOk;
155
- }
156
-
157
- /**
158
- * @ignore
159
- */
160
- public checkWebglEnv(): boolean {
161
- let flag = false;
162
- const canvas: HTMLCanvasElement = document.createElement('canvas');
163
- try {
164
- const getContext = (
165
- contextNames = ['webgl2', 'webgl', 'experimental-webgl']
166
- ): WebGLRenderingContext | WebGLRenderingContext | null => {
167
- for (let i = 0; i < contextNames.length; i++) {
168
- const contextName = contextNames[i]!;
169
- const context = canvas?.getContext(contextName);
170
- if (context) {
171
- return context as WebGLRenderingContext | WebGLRenderingContext;
172
- }
173
- }
174
- return null;
175
- };
176
- let gl = getContext();
177
- flag = !!gl;
178
- gl?.getExtension('WEBGL_lose_context')?.loseContext();
179
- gl = null;
180
- logInfo('Your browser support webGL');
181
- } catch (e) {
182
- logWarn('Your browser may not support webGL');
183
- flag = false;
184
- }
185
- return flag;
186
- }
187
-
188
- /**
189
- * @ignore
190
- */
191
- public setupVideo(rendererVideoConfig: RendererVideoConfig): number {
192
- const formatConfig = getDefaultRendererVideoConfig(rendererVideoConfig);
193
-
194
- const { uid, channelId, videoSourceType, rendererOptions, view } =
195
- formatConfig;
22
+ private _rendererType: RendererType;
196
23
 
197
- if (!formatConfig.view) {
198
- logWarn('setupVideo->destroyRenderersByConfig, because of view is null');
199
- this.destroyRenderersByConfig(videoSourceType, channelId, uid);
200
- return -ErrorCodeType.ErrInvalidArgument;
24
+ public set rendererType(rendererType: RendererType) {
25
+ if (this._rendererType !== rendererType) {
26
+ this._rendererType = rendererType;
201
27
  }
202
-
203
- // ensure a render to RenderMap
204
- const render = this.bindHTMLElementToRender(formatConfig, view!);
205
-
206
- // render config
207
- render?.setRenderOption(rendererOptions);
208
-
209
- // enable iris videoFrame
210
- this.enableVideoFrameCache({
211
- uid,
212
- channelId,
213
- videoSourceType,
214
- });
215
-
216
- // enable render
217
- this.enableRender(true);
218
- return ErrorCodeType.ErrOk;
219
28
  }
220
29
 
221
- /**
222
- * @ignore
223
- */
224
- public setupLocalVideo(rendererConfig: RendererVideoConfig): number {
225
- const { videoSourceType } = rendererConfig;
226
- if (videoSourceType === VideoSourceType.VideoSourceRemote) {
227
- logError('setupLocalVideo videoSourceType error', videoSourceType);
228
- return -ErrorCodeType.ErrInvalidArgument;
229
- }
230
- this.setupVideo({ ...rendererConfig });
231
- return ErrorCodeType.ErrOk;
232
- }
233
-
234
- /**
235
- * @ignore
236
- */
237
- public setupRemoteVideo(rendererConfig: RendererVideoConfig): number {
238
- const { videoSourceType } = rendererConfig;
239
- if (videoSourceType !== VideoSourceType.VideoSourceRemote) {
240
- logError('setupRemoteVideo videoSourceType error', videoSourceType);
241
- return -ErrorCodeType.ErrInvalidArgument;
242
- }
243
- this.setupVideo({ ...rendererConfig });
244
- return ErrorCodeType.ErrOk;
245
- }
246
-
247
- /**
248
- * Destroys a video renderer object.
249
- *
250
- * @param view The HTMLElement object to be destroyed.
251
- */
252
- public destroyRendererByView(view: Element): void {
253
- const renders = this.renderers;
254
- renders.forEach((channelMap, videoSourceType) => {
255
- channelMap.forEach((uidMap, channelId) => {
256
- uidMap.forEach((renderConfig, uid) => {
257
- let hasRender = false;
258
- const remainRenders = renderConfig.renders?.filter((render) => {
259
- const isFilter = render.equalsElement(view);
260
-
261
- if (isFilter) {
262
- hasRender = true;
263
- render.unbind();
264
- }
265
- return !isFilter;
266
- });
267
- if (!hasRender) {
268
- return;
269
- }
270
-
271
- if (remainRenders?.length === 0 || !remainRenders) {
272
- this.disableVideoFrameCache({ uid, channelId, videoSourceType });
273
- }
274
- renderConfig.renders = remainRenders;
275
- });
276
- });
277
- });
278
- }
279
-
280
- /**
281
- * @ignore
282
- */
283
- public destroyRenderersByConfig(
284
- videoSourceType: VideoSourceType,
285
- channelId?: Channel,
286
- uid?: number
287
- ): void {
288
- const config = formatConfigByVideoSourceType(
289
- videoSourceType,
290
- channelId,
291
- uid
292
- );
293
- videoSourceType = config.videoSourceType;
294
- channelId = config.channelId;
295
- uid = config.uid;
296
-
297
- this.disableVideoFrameCache(config);
298
- const uidMap = this.renderers.get(videoSourceType)?.get(channelId);
299
- const renderMap = uidMap?.get(uid);
300
- if (!renderMap) {
301
- return;
302
- }
303
- renderMap.renders?.forEach((renderItem) => {
304
- renderItem.unbind();
305
- });
306
- renderMap.renders = [];
30
+ public get rendererType(): RendererType {
31
+ return this._rendererType;
307
32
  }
308
33
 
309
- /**
310
- * @ignore
311
- */
312
- public removeAllRenderer(): void {
313
- const renderMap = this.forEachStream(
314
- (renderConfig, videoFrameCacheConfig) => {
315
- this.disableVideoFrameCache(videoFrameCacheConfig);
316
- renderConfig.renders?.forEach((renderItem) => {
317
- renderItem.unbind();
318
- });
319
- renderConfig.renders = [];
320
- }
321
- );
322
- renderMap.clear();
323
- }
324
-
325
- /**
326
- * @ignore
327
- */
328
- public clear(): void {
329
- this.stopRender();
330
- this.removeAllRenderer();
331
- }
332
-
333
- /**
334
- * Enables/Disables the local video capture.
335
- * This method disables or re-enables the local video capture, and does not affect receiving the remote video stream.After calling enableVideo , the local video capture is enabled by default. You can call enableLocalVideo (false) to disable the local video capture. If you want to re-enable the local video capture, call enableLocalVideo(true).After the local video capturer is successfully disabled or re-enabled, the SDK triggers the onRemoteVideoStateChanged callback on the remote client.You can call this method either before or after joining a channel.This method enables the internal engine and is valid after leaving the channel.
336
- *
337
- * @param enabled Whether to enable the local video capture.true: (Default) Enable the local video capture.false: Disable the local video capture. Once the local video is disabled, the remote users cannot receive the video stream of the local user, while the local user can still receive the video streams of remote users. When set to false, this method does not require a local camera.
338
- *
339
- * @returns
340
- * 0: Success.< 0: Failure.
341
- */
342
- public enableRender(enabled = true): void {
343
- if (enabled && this.isRendering) {
344
- //is already _isRendering
345
- } else if (enabled && !this.isRendering) {
346
- this.startRenderer();
347
- } else {
348
- this.stopRender();
349
- }
34
+ constructor() {
35
+ super();
36
+ this._rendererType = isSupportWebGL()
37
+ ? RendererType.WEBGL
38
+ : RendererType.SOFTWARE;
350
39
  }
351
40
 
352
41
  /**
353
- * @ignore
42
+ * @deprecated Use rendererType instead
354
43
  */
355
- public startRenderer(): void {
356
- this.isRendering = true;
357
- const renderFunc = (
358
- rendererItem: RenderConfig,
359
- { videoSourceType, channelId, uid }: VideoFrameCacheConfig
360
- ) => {
361
- const { renders } = rendererItem;
362
- if (!renders || renders?.length === 0) {
363
- return;
364
- }
365
- let finalResult = this.msgBridge.GetVideoFrame(
366
- rendererItem.shareVideoFrame
367
- );
368
-
369
- switch (finalResult.ret) {
370
- case 0:
371
- // GET_VIDEO_FRAME_CACHE_RETURN_TYPE::OK = 0,
372
- // everything is ok
373
- break;
374
- case 1: {
375
- // GET_VIDEO_FRAME_CACHE_RETURN_TYPE::RESIZED
376
- const { width, height, yStride } = finalResult;
377
- const newShareVideoFrame = this.resizeShareVideoFrame(
378
- videoSourceType,
379
- channelId,
380
- uid,
381
- width,
382
- height,
383
- yStride
384
- );
385
- rendererItem.shareVideoFrame = newShareVideoFrame;
386
- finalResult = this.msgBridge.GetVideoFrame(newShareVideoFrame);
387
- break;
388
- }
389
- case 2:
390
- // GET_VIDEO_FRAME_CACHE_RETURN_TYPE::NO_CACHE
391
- // setupVideo/AgoraView render before initialize
392
- // this.enableVideoFrameCache({ videoSourceType, channelId, uid });
393
- break;
394
- default:
395
- break;
396
- }
397
- if (finalResult.ret !== 0) {
398
- logDebug('GetVideoFrame ret is', finalResult.ret, rendererItem);
399
- return;
400
- }
401
- if (!finalResult.isNewFrame) {
402
- logDebug('GetVideoFrame isNewFrame is false', rendererItem);
403
- return;
404
- }
405
- const renderVideoFrame = rendererItem.shareVideoFrame;
406
- if (renderVideoFrame.width > 0 && renderVideoFrame.height > 0) {
407
- renders.forEach((renderItem) => {
408
- renderItem.drawFrame(rendererItem.shareVideoFrame);
409
- });
410
- }
411
- };
412
- const render = () => {
413
- this.forEachStream(renderFunc);
414
- this.videoFrameUpdateInterval = setTimeout(render, 1000 / this.renderFps);
415
- };
416
- render();
44
+ public setRenderMode(mode: RENDER_MODE) {
45
+ this.rendererType = mode;
417
46
  }
418
47
 
419
48
  /**
420
- * @ignore
49
+ * @deprecated Use renderingFps instead
421
50
  */
422
- public stopRender(): void {
423
- this.isRendering = false;
424
- if (this.videoFrameUpdateInterval) {
425
- clearTimeout(this.videoFrameUpdateInterval);
426
- this.videoFrameUpdateInterval = undefined;
427
- }
51
+ public setFPS(fps: number) {
52
+ this.renderingFps = fps;
428
53
  }
429
54
 
430
55
  /**
431
- * @ignore
56
+ * @deprecated Use getRendererCache instead
432
57
  */
433
- public restartRender(): void {
434
- if (this.videoFrameUpdateInterval) {
435
- this.stopRender();
436
- this.startRenderer();
437
- logInfo(`restartRender: Fps: ${this.renderFps} restartInterval`);
438
- }
58
+ public getRender(context: RendererCacheContext): RendererCache | undefined {
59
+ return this.getRendererCache(context);
439
60
  }
440
61
 
441
- /**
442
- * @ignore
443
- */
444
- private createRenderer(
445
- renderMode?: RENDER_MODE,
446
- fallback?: WebGLFallback
62
+ protected override createRenderer(
63
+ context: RendererContext,
64
+ rendererType?: RendererType
447
65
  ): IRenderer {
448
- if (renderMode === RENDER_MODE.SOFTWARE) {
449
- return new YUVCanvasRenderer();
450
- } else {
451
- return new WebGLRenderer(fallback);
66
+ if (rendererType === undefined) {
67
+ rendererType = this.rendererType;
452
68
  }
453
- }
454
69
 
455
- /**
456
- * @ignore
457
- */
458
- private getRender({
459
- videoSourceType,
460
- channelId,
461
- uid,
462
- }: VideoFrameCacheConfig) {
463
- return this.renderers.get(videoSourceType)?.get(channelId)?.get(uid);
464
- }
465
-
466
- /**
467
- * @ignore
468
- */
469
- private getRenderers({
470
- videoSourceType,
471
- channelId,
472
- uid,
473
- }: VideoFrameCacheConfig): IRenderer[] {
474
- return this.getRender({ videoSourceType, channelId, uid })?.renders || [];
475
- }
476
-
477
- /**
478
- * @ignore
479
- */
480
- private bindHTMLElementToRender(
481
- config: FormatRendererVideoConfig,
482
- view: HTMLElement
483
- ): IRenderer | undefined {
484
- this.ensureRendererConfig(config);
485
- const renderers = this.getRenderers(config);
486
- const filterRenders =
487
- renderers?.filter((render) => render.equalsElement(view)) || [];
488
- const hasBeenAdd = filterRenders.length > 0;
489
- if (hasBeenAdd) {
490
- logWarn(
491
- 'bindHTMLElementToRender: this view has bind to render',
492
- filterRenders
493
- );
494
- return filterRenders[0];
495
- }
496
- const renderer = this.createRenderer(
497
- this.renderMode,
498
- this.handleWebGLFallback(config)
499
- );
500
- renderer.bind(view);
501
- renderers.push(renderer);
502
- return renderer;
503
- }
504
-
505
- /**
506
- * @ignore
507
- */
508
- private handleWebGLFallback =
509
- (config: FormatRendererVideoConfig) => (renderer: WebGLRenderer) => {
510
- const { contentMode, mirror } = renderer;
511
- const view = renderer.parentElement!;
512
- const renderers = this.getRenderers(config);
513
- const index = renderers.indexOf(renderer);
514
- renderer.unbind();
515
- const newRenderer = this.createRenderer(RENDER_MODE.SOFTWARE);
516
- newRenderer.bind(view);
517
- newRenderer.setRenderOption({ contentMode, mirror });
518
- renderers.splice(index, 1, newRenderer);
70
+ let renderer: IRenderer;
71
+ switch (rendererType) {
72
+ case RendererType.WEBGL:
73
+ renderer = new WebGLRenderer(
74
+ this.handleWebGLFallback(context).bind(this)
75
+ );
76
+ break;
77
+ case RendererType.SOFTWARE:
78
+ renderer = new YUVCanvasRenderer();
79
+ break;
80
+ default:
81
+ throw new Error('Unknown renderer type');
82
+ }
83
+
84
+ renderer.bind(context.view);
85
+ renderer.context = {
86
+ renderMode: context.renderMode,
87
+ mirrorMode: context.mirrorMode,
519
88
  };
520
-
521
- /**
522
- * @ignore
523
- */
524
- private forEachStream(
525
- callbackfn: (
526
- renderConfig: RenderConfig,
527
- videoFrameCacheConfig: VideoFrameCacheConfig,
528
- maps: {
529
- channelMap: ChannelIdMap;
530
- uidMap: UidMap;
531
- }
532
- ) => void
533
- ): RenderMap {
534
- const renders = this.renderers;
535
- renders.forEach((channelMap, videoSourceType) => {
536
- channelMap.forEach((uidMap, channelId) => {
537
- uidMap.forEach((renderConfig, uid) => {
538
- callbackfn(
539
- renderConfig,
540
- { videoSourceType, channelId, uid },
541
- { channelMap, uidMap }
542
- );
543
- });
544
- });
545
- });
546
- return renders;
547
- }
548
-
549
- /**
550
- * @ignore
551
- */
552
- private enableVideoFrameCache(
553
- videoFrameCacheConfig: VideoFrameCacheConfig
554
- ): void {
555
- logDebug(`enableVideoFrameCache ${JSON.stringify(videoFrameCacheConfig)}`);
556
- this.msgBridge.EnableVideoFrameCache(videoFrameCacheConfig);
89
+ return renderer;
557
90
  }
558
91
 
559
- /**
560
- * @ignore
561
- */
562
- private disableVideoFrameCache(
563
- videoFrameCacheConfig: VideoFrameCacheConfig
564
- ): void {
565
- logDebug(`disableVideoFrameCache ${JSON.stringify(videoFrameCacheConfig)}`);
566
- this.msgBridge.DisableVideoFrameCache(videoFrameCacheConfig);
92
+ public override doRendering(rendererCache: RendererCache): void {
93
+ rendererCache.draw();
567
94
  }
568
95
 
569
- /**
570
- * @ignore
571
- */
572
- private ensureRendererConfig(config: VideoFrameCacheConfig):
573
- | Map<
574
- number,
575
- {
576
- shareVideoFrame: ShareVideoFrame;
577
- renders: IRenderer[];
578
- }
579
- >
580
- | undefined {
581
- const { videoSourceType, uid, channelId } = config;
582
- const emptyRenderConfig = {
583
- renders: [],
584
- shareVideoFrame: this.resizeShareVideoFrame(
585
- videoSourceType,
586
- channelId,
587
- uid
588
- ),
589
- };
590
- const emptyUidMap = new Map([[uid, emptyRenderConfig]]);
591
- const emptyChannelMap = new Map([[channelId, emptyUidMap]]);
592
-
593
- const renderers = this.renderers;
594
- const videoSourceMap = renderers.get(videoSourceType);
595
- if (!videoSourceMap) {
596
- renderers.set(videoSourceType, emptyChannelMap);
597
- return emptyUidMap;
598
- }
599
- const channelMap = videoSourceMap.get(channelId);
600
- if (!channelMap) {
601
- videoSourceMap.set(channelId, emptyUidMap);
602
- return emptyUidMap;
603
- }
604
- const renderConfig = channelMap?.get(uid);
605
- if (!renderConfig) {
606
- channelMap?.set(uid, emptyRenderConfig);
607
- logWarn(
608
- `ensureRendererMap uid map for channelId:${channelId} uid:${uid}`
96
+ private handleWebGLFallback(context: RendererContext): WebGLFallback {
97
+ return (renderer: WebGLRenderer) => {
98
+ const {
99
+ context: { renderMode, mirrorMode },
100
+ } = renderer;
101
+ const renderers = this.getRenderers(context);
102
+ renderer.unbind();
103
+ const newRenderer = this.createRenderer(
104
+ { ...context, renderMode, mirrorMode },
105
+ RendererType.SOFTWARE
609
106
  );
610
- return emptyUidMap;
611
- }
612
- return channelMap;
613
- }
614
-
615
- /**
616
- * @ignore
617
- */
618
- private resizeShareVideoFrame(
619
- videoSourceType: VideoSourceType,
620
- channelId: string,
621
- uid: number,
622
- width = 0,
623
- height = 0,
624
- yStride = 0
625
- ): ShareVideoFrame {
626
- return {
627
- videoSourceType,
628
- channelId,
629
- uid,
630
- yBuffer: Buffer.alloc(yStride * height),
631
- uBuffer: Buffer.alloc((yStride * height) / 4),
632
- vBuffer: Buffer.alloc((yStride * height) / 4),
633
- width,
634
- height,
635
- yStride,
107
+ renderers.splice(renderers.indexOf(renderer), 1, newRenderer);
636
108
  };
637
109
  }
638
-
639
- /**
640
- * @ignore
641
- */
642
- public updateVideoFrameCacheInMap(
643
- config: VideoFrameCacheConfig,
644
- shareVideoFrame: ShareVideoFrame
645
- ): void {
646
- let rendererConfigMap = this.ensureRendererConfig(config);
647
- rendererConfigMap
648
- ? Object.assign(rendererConfigMap.get(config.uid) ?? {}, {
649
- shareVideoFrame,
650
- })
651
- : logWarn(
652
- `updateVideoFrameCacheInMap videoSourceType:${config.videoSourceType} channelId:${config.channelId} uid:${config.uid} rendererConfigMap is null`
653
- );
654
- }
655
110
  }