trtc-electron-sdk 10.3.8-beta.2 → 10.3.8-beta.21

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/trtc.js CHANGED
@@ -19,9 +19,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  const events_1 = require("events");
21
21
  const Render_1 = __importDefault(require("./Render"));
22
- const util_1 = require("./Render/util");
23
22
  // @ts-ignore
24
23
  const yuv_buffer_1 = __importDefault(require("yuv-buffer"));
24
+ const util_1 = require("./Render/util");
25
25
  // @ts-ignore
26
26
  const YCbCr_1 = __importDefault(require("yuv-canvas/src/YCbCr"));
27
27
  const trtc_define_1 = require("./trtc_define");
@@ -33,9 +33,10 @@ __exportStar(require("./trtc_code"), exports);
33
33
  const CUSTOM_VIDEO_DATA = 'onVideoData';
34
34
  const CAMERA_DEVICE_TEST_VIEW = 'camera_device_test_view';
35
35
  const CAMERA_DEVICE_TEST_ID = 'camera_device_test';
36
- const DEFAULT_VIDEO_WIDTH = 640;
37
- const DEFAULT_VIDEO_HEIGHT = 360;
36
+ const DEFAULT_VIDEO_WIDTH = 8;
37
+ const DEFAULT_VIDEO_HEIGHT = 8;
38
38
  const localVideoBuffer = {
39
+ id: 0,
39
40
  userId: '',
40
41
  buffer: null,
41
42
  streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig,
@@ -44,6 +45,7 @@ const localVideoBuffer = {
44
45
  pixelFormat: trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420,
45
46
  };
46
47
  const screenVideoBuffer = {
48
+ id: 0,
47
49
  userId: '',
48
50
  buffer: null,
49
51
  streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub,
@@ -52,6 +54,7 @@ const screenVideoBuffer = {
52
54
  pixelFormat: trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420,
53
55
  };
54
56
  const cameraTestVideoBuffer = {
57
+ id: 0,
55
58
  userId: CAMERA_DEVICE_TEST_ID,
56
59
  buffer: null,
57
60
  streamType: trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig,
@@ -108,6 +111,38 @@ let formatLogParams = function (params) {
108
111
  }
109
112
  return logParamsStr;
110
113
  };
114
+ const getComponentNO = function () {
115
+ var _a;
116
+ let componentName = '';
117
+ // @ts-ignore
118
+ if (global.__TRTCElectron && global.__TRTCElectron.componentName) {
119
+ // @ts-ignore
120
+ componentName = global.__TRTCElectron.componentName;
121
+ }
122
+ else {
123
+ const jsonStr = (_a = global.localStorage) === null || _a === void 0 ? void 0 : _a.getItem('__TRTCElectron');
124
+ if (jsonStr) {
125
+ try {
126
+ const jsonObj = JSON.parse(jsonStr);
127
+ if (jsonObj.componentName && typeof jsonObj.componentName === 'string') {
128
+ componentName = jsonObj.componentName;
129
+ }
130
+ }
131
+ catch (error) {
132
+ console.warn('trtc: localstorage TRTCElectron parse error.', error);
133
+ }
134
+ }
135
+ }
136
+ let componentNO = '';
137
+ switch (componentName) {
138
+ case 'TUIRoom':
139
+ componentNO = '5';
140
+ break;
141
+ default:
142
+ break;
143
+ }
144
+ return componentNO;
145
+ };
111
146
  let trtcCloudInstance = null;
112
147
  let oriRtcCloud = null;
113
148
  const renderModePixelFormatMap = new Map();
@@ -134,7 +169,8 @@ renderModePixelFormatMap.set(8, trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixe
134
169
  class TRTCCloud extends events_1.EventEmitter {
135
170
  constructor() {
136
171
  super();
137
- oriRtcCloud = new trtc.NodeRTCCloud(pkg.version);
172
+ const componentNO = getComponentNO();
173
+ oriRtcCloud = new trtc.NodeRTCCloud(pkg.version, componentNO);
138
174
  this.rtcCloud = Object.assign({}, oriRtcCloud, {
139
175
  onlineLog: undefined
140
176
  });
@@ -193,7 +229,17 @@ class TRTCCloud extends events_1.EventEmitter {
193
229
  }
194
230
  }
195
231
  /**
196
- * 获取配置对象, 可用来打开 debug 模式
232
+ * 获取 TRTC 配置对象
233
+ *
234
+ * 可以通过 TRTC 配置对象 {@link TRTCConfig} 打开 debug 模式
235
+ *
236
+ * @example
237
+ * // Enable 'debug' mode
238
+ * const TRTCCloud = require('trtc-electron-sdk');
239
+ * const rtcCloud = new TRTCCloud();
240
+ * rtcCloud.getConfigObject().setDebugMode(true);
241
+ *
242
+ * @returns {TRTCConfig}
197
243
  */
198
244
  getConfigObject() {
199
245
  return util_1.config;
@@ -377,8 +423,6 @@ class TRTCCloud extends events_1.EventEmitter {
377
423
  case 'onSystemAudioLoopbackError':
378
424
  this.handleOnSystemAudioLoopbackError(int32_1);
379
425
  break;
380
- case 'onVideoSizeChange':
381
- this.handleOnVideoSizeChange(string_1, int32_1, int32_2, int32_3);
382
426
  default:
383
427
  break;
384
428
  }
@@ -563,11 +607,11 @@ class TRTCCloud extends events_1.EventEmitter {
563
607
  /**
564
608
  * 3.3 用户是否开启摄像头视频
565
609
  *
566
- * 当您收到 onUserVideoAvailable(userId, YES) 通知时,代表该路画面已经有可用的视频数据帧到达。
610
+ * 当您收到 onUserVideoAvailable(userId, 1) 通知时,代表该路画面已经有可用的视频数据帧到达。
567
611
  * 之后,您需要调用 [startRemoteView()]{@link TRTCCloud#startRemoteView} 接口加载该用户的远程画面。
568
612
  * 再之后,您还会收到名为 onFirstVideoFrame(userId) 的首帧画面渲染回调。
569
613
  *
570
- * 当您收到了 onUserVideoAvailable(userId, NO) 通知时,代表该路远程画面已经被关闭,这可能是
614
+ * 当您收到了 onUserVideoAvailable(userId, 0) 通知时,代表该路远程画面已经被关闭,这可能是
571
615
  * 由于该用户调用了 [muteLocalVideo()]{@link TRTCCloud#muteLocalVideo} 或 [stopLocalPreview()]{@link TRTCCloud#stopLocalPreview} 所致。
572
616
  *
573
617
  * @event TRTCCallback#onUserVideoAvailable
@@ -581,10 +625,16 @@ class TRTCCloud extends events_1.EventEmitter {
581
625
  return !(userId === item.uid && item.type !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub);
582
626
  });
583
627
  }
584
- const videoBufferInfo = remoteVideoBufferMap.get(userId);
585
- if (videoBufferInfo) {
586
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, 0, 0, videoBufferInfo.pixelFormat);
587
- videoBufferInfo.buffer = null;
628
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
629
+ if (remoteUserVideoBuffers) {
630
+ if (remoteUserVideoBuffers.big) {
631
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.big.buffer, remoteUserVideoBuffers.big.streamType, 0, 0, remoteUserVideoBuffers.big.pixelFormat, remoteUserVideoBuffers.big.id);
632
+ remoteUserVideoBuffers.big.buffer = null;
633
+ }
634
+ if (remoteUserVideoBuffers.small) {
635
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.small.buffer, remoteUserVideoBuffers.small.streamType, 0, 0, remoteUserVideoBuffers.small.pixelFormat, remoteUserVideoBuffers.small.id);
636
+ remoteUserVideoBuffers.small.buffer = null;
637
+ }
588
638
  remoteVideoBufferMap.delete(userId);
589
639
  }
590
640
  }
@@ -593,7 +643,7 @@ class TRTCCloud extends events_1.EventEmitter {
593
643
  /**
594
644
  * 3.4 用户是否开启了辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)
595
645
  *
596
- * 注意:显示辅路画面使用的函数是 [startRemoteSubStreamView()]{@link TRTCCloud#startRemoteSubStreamView} 而非 [startRemoteView()]{@link TRTCCloud#startRemoteView}。
646
+ * 注意:显示辅路画面使用的函数是[startRemoteView()]{@link TRTCCloud#startRemoteView}, 从 8.0 版本开始已不再推荐使用 [startRemoteSubStreamView()]{@link TRTCCloud#startRemoteSubStreamView}。
597
647
  *
598
648
  * @event TRTCCallback#onUserSubStreamAvailable
599
649
  * @param {String} userId - 用户标识
@@ -607,8 +657,9 @@ class TRTCCloud extends events_1.EventEmitter {
607
657
  });
608
658
  }
609
659
  if (screenVideoBuffer.buffer && screenVideoBuffer.userId === userId) {
610
- this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat);
660
+ this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
611
661
  screenVideoBuffer.buffer = null;
662
+ screenVideoBuffer.id = 0;
612
663
  screenVideoBuffer.userId = '';
613
664
  }
614
665
  }
@@ -1039,16 +1090,19 @@ class TRTCCloud extends events_1.EventEmitter {
1039
1090
  * @event TRTCCallback#onScreenCaptureStarted
1040
1091
  */
1041
1092
  handleOnScreenCaptureStarted() {
1093
+ console.debug('trtc:onScreenCaptureStarted');
1042
1094
  this.isScreenCapturing = true;
1043
- // 只有在 Buffer 为 null 时才新建,否则只能在 onVideoSizeChange 事件中重新申请 Buffer
1095
+ // 只有在 Buffer 为 null 时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1044
1096
  if (!screenVideoBuffer.buffer) {
1045
1097
  screenVideoBuffer.userId = '';
1046
1098
  screenVideoBuffer.streamType = this.screenCaptureStreamType;
1047
1099
  screenVideoBuffer.buffer = (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength, screenVideoBuffer.userId, screenVideoBuffer.streamType);
1100
+ screenVideoBuffer.id = (0, util_1.generateUniqueId)();
1048
1101
  screenVideoBuffer.pixelFormat = this.pixelformate;
1049
1102
  screenVideoBuffer.width = DEFAULT_VIDEO_WIDTH;
1050
1103
  screenVideoBuffer.height = DEFAULT_VIDEO_HEIGHT;
1051
- this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, screenVideoBuffer.width, screenVideoBuffer.height, screenVideoBuffer.pixelFormat);
1104
+ this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, screenVideoBuffer.width, screenVideoBuffer.height, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1105
+ console.debug('trtc:onScreenCaptureStarted alloc add screenVideoBuffer', screenVideoBuffer);
1052
1106
  }
1053
1107
  this.fire('onScreenCaptureStarted');
1054
1108
  }
@@ -1077,10 +1131,13 @@ class TRTCCloud extends events_1.EventEmitter {
1077
1131
  * @param {Number} reason - 停止原因,0:表示用户主动停止;1:表示屏幕分享窗口被关闭
1078
1132
  */
1079
1133
  handleOnScreenCaptureStopped(reason) {
1134
+ console.debug('trtc:onScreenCaptureStopped', reason);
1080
1135
  if (this.isScreenCapturing) {
1081
1136
  if (screenVideoBuffer.buffer) {
1082
- this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat);
1137
+ this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1083
1138
  screenVideoBuffer.buffer = null;
1139
+ screenVideoBuffer.id = 0;
1140
+ console.debug('trtc:onScreenCaptureStopped delete screenVideoBuffer', screenVideoBuffer);
1084
1141
  }
1085
1142
  this.isScreenCapturing = false;
1086
1143
  }
@@ -1173,31 +1230,46 @@ class TRTCCloud extends events_1.EventEmitter {
1173
1230
  handleOnSystemAudioLoopbackError(errCode) {
1174
1231
  this.fire('onSystemAudioLoopbackError', errCode);
1175
1232
  }
1176
- handleOnVideoSizeChange(userId, streamType, width, height) {
1233
+ handleVideoSizeChange(userId, streamType, width, height) {
1234
+ console.debug('trtc:handleVideoSizeChange', userId, streamType, width, height);
1177
1235
  if (userId && userId !== CAMERA_DEVICE_TEST_ID) {
1178
1236
  if (streamType !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
1179
- const videoBufferInfo = remoteVideoBufferMap.get(userId);
1180
- if (videoBufferInfo) {
1181
- if (videoBufferInfo.width !== width || videoBufferInfo.height !== height) {
1182
- videoBufferInfo.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, userId, streamType);
1183
- videoBufferInfo.width = width;
1184
- videoBufferInfo.height = height;
1185
- videoBufferInfo.pixelFormat = this.pixelformate;
1186
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, streamType, width, height, videoBufferInfo.pixelFormat);
1237
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
1238
+ if (remoteUserVideoBuffers) {
1239
+ if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && remoteUserVideoBuffers.big) {
1240
+ if (remoteUserVideoBuffers.big.width !== width || remoteUserVideoBuffers.big.height !== height) {
1241
+ remoteUserVideoBuffers.big.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, userId, streamType);
1242
+ remoteUserVideoBuffers.big.id = (0, util_1.generateUniqueId)();
1243
+ remoteUserVideoBuffers.big.width = width;
1244
+ remoteUserVideoBuffers.big.height = height;
1245
+ remoteUserVideoBuffers.big.pixelFormat = this.pixelformate;
1246
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.big.buffer, streamType, width, height, remoteUserVideoBuffers.big.pixelFormat, remoteUserVideoBuffers.big.id);
1247
+ }
1248
+ }
1249
+ else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && remoteUserVideoBuffers.small) {
1250
+ if (remoteUserVideoBuffers.small.width !== width || remoteUserVideoBuffers.small.height !== height) {
1251
+ remoteUserVideoBuffers.small.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, userId, streamType);
1252
+ remoteUserVideoBuffers.small.id = (0, util_1.generateUniqueId)();
1253
+ remoteUserVideoBuffers.small.width = width;
1254
+ remoteUserVideoBuffers.small.height = height;
1255
+ remoteUserVideoBuffers.small.pixelFormat = this.pixelformate;
1256
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.small.buffer, streamType, width, height, remoteUserVideoBuffers.small.pixelFormat, remoteUserVideoBuffers.small.id);
1257
+ }
1187
1258
  }
1188
1259
  }
1189
1260
  else {
1190
- console.error(`trtc:onVideoSizeChange error: ${userId} ${streamType} buffer not exist`);
1261
+ console.error(`trtc:handleVideoSizeChange error: ${userId} ${streamType} buffer not exist`);
1191
1262
  }
1192
1263
  }
1193
1264
  else {
1194
1265
  // 远端用户屏幕分享
1195
1266
  if (screenVideoBuffer.width !== width || screenVideoBuffer.height !== height) {
1196
1267
  screenVideoBuffer.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, userId, streamType);
1268
+ screenVideoBuffer.id = (0, util_1.generateUniqueId)();
1197
1269
  screenVideoBuffer.width = width;
1198
1270
  screenVideoBuffer.height = height;
1199
1271
  screenVideoBuffer.pixelFormat = this.pixelformate;
1200
- this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, streamType, width, height, screenVideoBuffer.pixelFormat);
1272
+ this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, streamType, width, height, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1201
1273
  }
1202
1274
  }
1203
1275
  }
@@ -1207,10 +1279,11 @@ class TRTCCloud extends events_1.EventEmitter {
1207
1279
  // 本地屏幕分享
1208
1280
  if (screenVideoBuffer.width !== width || screenVideoBuffer.height !== height) {
1209
1281
  screenVideoBuffer.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, screenVideoBuffer.userId, streamType);
1282
+ screenVideoBuffer.id = (0, util_1.generateUniqueId)();
1210
1283
  screenVideoBuffer.width = width;
1211
1284
  screenVideoBuffer.height = height;
1212
1285
  screenVideoBuffer.pixelFormat = this.pixelformate;
1213
- this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, width, height, screenVideoBuffer.pixelFormat);
1286
+ this.rtcCloud.setSubVideoBuffer('', screenVideoBuffer.buffer, screenVideoBuffer.streamType, width, height, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1214
1287
  }
1215
1288
  }
1216
1289
  else {
@@ -1218,20 +1291,22 @@ class TRTCCloud extends events_1.EventEmitter {
1218
1291
  // 摄像头检测
1219
1292
  if (cameraTestVideoBuffer.width !== width || cameraTestVideoBuffer.height !== height) {
1220
1293
  cameraTestVideoBuffer.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, cameraTestVideoBuffer.userId, streamType);
1294
+ cameraTestVideoBuffer.id = (0, util_1.generateUniqueId)();
1221
1295
  cameraTestVideoBuffer.width = width;
1222
1296
  cameraTestVideoBuffer.height = height;
1223
1297
  cameraTestVideoBuffer.pixelFormat = this.pixelformate;
1224
- this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, width, height, cameraTestVideoBuffer.pixelFormat);
1298
+ this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, width, height, cameraTestVideoBuffer.pixelFormat, cameraTestVideoBuffer.id);
1225
1299
  }
1226
1300
  }
1227
1301
  else {
1228
1302
  // 本地摄像头
1229
1303
  if (localVideoBuffer.width !== width || localVideoBuffer.height !== height) {
1230
1304
  localVideoBuffer.buffer = (0, util_1.allocBuffer)(width * height * this.pixelLength, localVideoBuffer.userId, streamType);
1305
+ localVideoBuffer.id = (0, util_1.generateUniqueId)();
1231
1306
  localVideoBuffer.width = width;
1232
1307
  localVideoBuffer.height = height;
1233
1308
  localVideoBuffer.pixelFormat = this.pixelformate;
1234
- this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, width, height, localVideoBuffer.pixelFormat);
1309
+ this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, width, height, localVideoBuffer.pixelFormat, localVideoBuffer.id);
1235
1310
  }
1236
1311
  }
1237
1312
  }
@@ -1306,22 +1381,31 @@ class TRTCCloud extends events_1.EventEmitter {
1306
1381
  this._destroyRender(key, null);
1307
1382
  });
1308
1383
  remoteVideoBufferMap.forEach((value, key) => {
1309
- this.rtcCloud.setRemoteVideoBuffer(key, value.buffer, value.streamType, 0, 0, value.pixelFormat);
1310
- value.buffer = null;
1384
+ if (value.big) {
1385
+ this.rtcCloud.setRemoteVideoBuffer(key, value.big.buffer, value.big.streamType, 0, 0, value.big.pixelFormat, value.big.id);
1386
+ value.big.buffer = null;
1387
+ }
1388
+ if (value.small) {
1389
+ this.rtcCloud.setRemoteVideoBuffer(key, value.small.buffer, value.small.streamType, 0, 0, value.small.pixelFormat, value.small.id);
1390
+ value.small.buffer = null;
1391
+ }
1311
1392
  });
1312
1393
  remoteVideoBufferMap.clear();
1313
1394
  if (localVideoBuffer.buffer) {
1314
- this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, 0, 0, localVideoBuffer.pixelFormat);
1395
+ this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, 0, 0, localVideoBuffer.pixelFormat, localVideoBuffer.id);
1315
1396
  localVideoBuffer.buffer = null;
1397
+ localVideoBuffer.id = 0;
1316
1398
  }
1317
1399
  if (screenVideoBuffer.buffer) {
1318
- this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat);
1400
+ this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1319
1401
  screenVideoBuffer.buffer = null;
1402
+ screenVideoBuffer.id = 0;
1320
1403
  screenVideoBuffer.userId = '';
1321
1404
  }
1322
1405
  if (cameraTestVideoBuffer.buffer) {
1323
- this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, 0, 0, cameraTestVideoBuffer.pixelFormat);
1406
+ this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, 0, 0, cameraTestVideoBuffer.pixelFormat, cameraTestVideoBuffer.id);
1324
1407
  cameraTestVideoBuffer.buffer = null;
1408
+ cameraTestVideoBuffer.id = 0;
1325
1409
  }
1326
1410
  this.rtcCloud.exitRoom();
1327
1411
  }
@@ -1334,7 +1418,7 @@ class TRTCCloud extends events_1.EventEmitter {
1334
1418
  *
1335
1419
  * @param {TRTCSwitchRoomParam} params 房间切换参数,请参考 {@link TRTCSwitchRoomParam}
1336
1420
  *
1337
- * 接口调用结果会通过 TRTCCloudListener 中的 onSwitchRoom(errCode, errMsg) 回调通知给您。
1421
+ * 接口调用结果会通过 onSwitchRoom(errCode, errMsg) 事件回调通知给您。
1338
1422
  */
1339
1423
  switchRoom(params) {
1340
1424
  this.rtcCloud.switchRoom(params.roomId, params.strRoomId, params.userSig, params.privateMapKey);
@@ -1367,13 +1451,13 @@ class TRTCCloud extends events_1.EventEmitter {
1367
1451
  * <pre>
1368
1452
  * 房间 001 房间 002
1369
1453
  * ------------- ------------
1370
- * 跨房连麦前:| 主播 A | | 主播 B |
1454
+ * 跨房连麦前: | 主播 A | | 主播 B |
1371
1455
  * | 观众 U V W | | 观众 X Y Z |
1372
1456
  * ------------- ------------
1373
1457
  *
1374
1458
  * 房间 001 房间 002
1375
1459
  * ------------- ------------
1376
- * 跨房连麦后:| 主播 A B | | 主播 B A |
1460
+ * 跨房连麦后: | 主播 A B | | 主播 B A |
1377
1461
  * | 观众 U V W | | 观众 X Y Z |
1378
1462
  * ------------- ------------
1379
1463
  * </pre>
@@ -1510,6 +1594,8 @@ class TRTCCloud extends events_1.EventEmitter {
1510
1594
  *
1511
1595
  * 参考文档:[云端混流转码](https://cloud.tencent.com/document/product/647/16827)。
1512
1596
  *
1597
+ * 注意:混流转码为收费功能,调用接口将产生云端混流转码费用,详见 [云端混流转码计费说明](https://cloud.tencent.com/document/product/647/49446)。
1598
+ *
1513
1599
  * @note 关于云端混流的注意事项:
1514
1600
  * - 云端转码会引入一定的 CDN 观看延时,大概会增加1 - 2秒。
1515
1601
  * - 调用该函数的用户,会将连麦中的多路画面混合到自己当前这路画面中。
@@ -1531,7 +1617,7 @@ class TRTCCloud extends events_1.EventEmitter {
1531
1617
  * @param {String} config.streamId - 输出到 CDN 上的直播流 ID
1532
1618
  * @param {TRTCMixUser[]} config.mixUsersArray - 每一路子画面的位置信息
1533
1619
  * @param {String} config.mixUsersArray[].userId - 参与混流的 userId
1534
- * @param {String} config.mixUsersArray[].roomId - 参与混流的 roomId,跨房流传入的实际 roomId,当前房间流传入 roomId = null
1620
+ * @param {String} config.mixUsersArray[].roomId - 参与混流的 roomId,跨房流传入的实际 roomId。当前房间流,请传入空字符串(roomId = '')。
1535
1621
  * @param {Rect} config.mixUsersArray[].rect - 图层位置坐标以及大小,左上角为坐标原点(0,0) (绝对像素值)
1536
1622
  * @param {Number} config.mixUsersArray[].rect.left - 图层位置的左坐标
1537
1623
  * @param {Number} config.mixUsersArray[].rect.top - 图层位置的上坐标
@@ -1600,14 +1686,15 @@ class TRTCCloud extends events_1.EventEmitter {
1600
1686
  }
1601
1687
  // view 为 null 时,可能启动了自定义渲染,所以 Buffer 还是要创建,否则自定义渲染就拿不到数据;
1602
1688
  // view 非 null 时,当然必须创建 Buffer
1603
- // 只有在 Buffer 为 null 时才新建,否则只能在 onVideoSizeChange 事件中重新申请 Buffer
1689
+ // 只有在 Buffer 为 null 时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1604
1690
  if (!localVideoBuffer.buffer) {
1605
1691
  localVideoBuffer.streamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
1606
1692
  localVideoBuffer.buffer = (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength, localVideoBuffer.userId, localVideoBuffer.streamType);
1693
+ localVideoBuffer.id = (0, util_1.generateUniqueId)();
1607
1694
  localVideoBuffer.pixelFormat = this.pixelformate;
1608
1695
  localVideoBuffer.width = DEFAULT_VIDEO_WIDTH;
1609
1696
  localVideoBuffer.height = DEFAULT_VIDEO_HEIGHT;
1610
- this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, localVideoBuffer.width, localVideoBuffer.height, localVideoBuffer.pixelFormat);
1697
+ this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, localVideoBuffer.width, localVideoBuffer.height, localVideoBuffer.pixelFormat, localVideoBuffer.id);
1611
1698
  }
1612
1699
  this.rtcCloud.startLocalPreview();
1613
1700
  this.addLocalVideoRenderCallback();
@@ -1627,15 +1714,49 @@ class TRTCCloud extends events_1.EventEmitter {
1627
1714
  return !('' === item.uid && item.type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
1628
1715
  });
1629
1716
  if (localVideoBuffer.buffer) {
1630
- this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, 0, 0, localVideoBuffer.pixelFormat);
1717
+ this.rtcCloud.setLocalVideoBuffer(localVideoBuffer.buffer, 0, 0, localVideoBuffer.pixelFormat, localVideoBuffer.id);
1631
1718
  localVideoBuffer.buffer = null;
1719
+ localVideoBuffer.id = 0;
1632
1720
  }
1633
1721
  }
1634
1722
  /**
1635
- * 3.3 是否屏蔽自己的视频画面
1723
+ * 3.3 修改本地摄像头预览的 HTML 元素
1636
1724
  *
1637
- * 当屏蔽本地视频后,房间里的其它成员将会收到 onUserVideoAvailable 回调通知
1638
- * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
1725
+ * 本接口用于切换显示区域的交互场景中,修改本地摄像头预览的 HTML 元素。
1726
+ *
1727
+ * 注意:必须在调用 [startLocalPreview()]{@link TRTCCloud#startLocalPreview} 接口开启本地摄像头采集后,调用本接口才会生效。
1728
+ * - 如果用户调用 `startLocalPreview(view)` 接口开启了摄像头采集,则通过此接口可以修改摄像头采集视频渲染的 HTML 元素。
1729
+ * - 如果用户调用 `startLocalPreview(null)` 接口开启了摄像头采集,但未开启本地预览,支持调用此接口开启预览。
1730
+ *
1731
+ * @param {HTMLElement|null} view - 接收本地摄像头采集视频渲染的 HTML 元素,传入 `null` 结束本地摄像头采集视频的预览。
1732
+ * - 传入的 HTML 元素必须是块元素,比如:`div`
1733
+ */
1734
+ updateLocalView(view) {
1735
+ let key = this.getKey('local_video', trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
1736
+ if (view !== null && view instanceof HTMLElement) {
1737
+ this._initRender(key, view);
1738
+ }
1739
+ else if (view === null) {
1740
+ if (this.streams.has(String(key))) {
1741
+ this._destroyRender(key, null);
1742
+ }
1743
+ }
1744
+ else {
1745
+ console.error('trtc:updateLocalView() called with wrong parameter', view);
1746
+ }
1747
+ }
1748
+ /**
1749
+ * 3.3 暂停/恢复发布本地的视频流
1750
+ *
1751
+ * 该接口可以暂停(或恢复)发布本地的视频画面,暂停之后,同一房间中的其他用户将无法继续看到自己画面。
1752
+ * 该接口在指定 TRTCVideoStreamTypeBig 时等效于 start/stopLocalPreview 这两个接口,但具有更好的响应速度。
1753
+ * 因为 start/stopLocalPreview 需要打开和关闭摄像头,而打开和关闭摄像头都是硬件设备相关的操作,非常耗时。
1754
+ * 相比之下,muteLocalVideo 只需要在软件层面对数据流进行暂停或者放行即可,因此效率更高,也更适合需要频繁打开关闭的场景。
1755
+ * 当暂停/恢复发布指定 TRTCVideoStreamTypeBig 后,同一房间中的其他用户将会收到 onUserVideoAvailable 回调通知。
1756
+ * 当暂停/恢复发布指定 TRTCVideoStreamTypeSub 后,同一房间中的其他用户将会收到 onUserSubStreamAvailable 回调通知。
1757
+ *
1758
+ * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
1759
+ * @param {TRTCVideoStreamType} streamType - 要暂停/恢复的视频流类型, 仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub
1639
1760
  */
1640
1761
  muteLocalVideo(mute, streamType) {
1641
1762
  let newStreamType = streamType;
@@ -1647,7 +1768,7 @@ class TRTCCloud extends events_1.EventEmitter {
1647
1768
  /**
1648
1769
  * 3.4 开始显示远端视频画面
1649
1770
  *
1650
- * 在收到 SDK 的 onUserVideoAvailable(userId, true) 通知时,可以获知该远程用户开启了视频,
1771
+ * 在收到 SDK 的 onUserVideoAvailable(userId, 1) 通知时,可以获知该远程用户开启了视频,
1651
1772
  * 此后调用 startRemoteView(userId) 接口加载该用户的远程画面时,可以用 loading 动画优化加载过程中的等待体验。
1652
1773
  * 待该用户的首帧画面开始显示时,您会收到 onFirstVideoFrame(userId) 事件回调。
1653
1774
  *
@@ -1675,24 +1796,41 @@ class TRTCCloud extends events_1.EventEmitter {
1675
1796
  const videoBufferInfo = {
1676
1797
  userId: userId,
1677
1798
  buffer: (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength, userId, streamType),
1799
+ id: (0, util_1.generateUniqueId)(),
1678
1800
  streamType: streamType,
1679
1801
  width: DEFAULT_VIDEO_WIDTH,
1680
1802
  height: DEFAULT_VIDEO_HEIGHT,
1681
1803
  pixelFormat: this.pixelformate,
1682
1804
  };
1683
1805
  if (streamType !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
1684
- if (!remoteVideoBufferMap.get(userId)) {
1685
- // Buffer 不存在时才新建,否则只能在 onVideoSizeChange 事件中重新申请 Buffer
1686
- remoteVideoBufferMap.set(userId, videoBufferInfo);
1687
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat);
1806
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
1807
+ if (!remoteUserVideoBuffers) {
1808
+ // Buffer 不存在时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1809
+ if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig) {
1810
+ remoteVideoBufferMap.set(userId, { big: videoBufferInfo });
1811
+ }
1812
+ else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall) {
1813
+ remoteVideoBufferMap.set(userId, { small: videoBufferInfo });
1814
+ }
1815
+ this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1816
+ }
1817
+ else {
1818
+ if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && !remoteUserVideoBuffers.big) {
1819
+ remoteUserVideoBuffers.big = videoBufferInfo;
1820
+ this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1821
+ }
1822
+ else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && !remoteUserVideoBuffers.small) {
1823
+ remoteUserVideoBuffers.small = videoBufferInfo;
1824
+ this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
1825
+ }
1688
1826
  }
1689
1827
  }
1690
1828
  else {
1691
1829
  // 远端屏幕分享
1692
- // Buffer 为 null 时才新建,否则只能在 onVideoSizeChange 事件中重新申请 Buffer
1830
+ // Buffer 为 null 时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
1693
1831
  if (!screenVideoBuffer.buffer) {
1694
1832
  Object.assign(screenVideoBuffer, videoBufferInfo);
1695
- this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, screenVideoBuffer.width, screenVideoBuffer.height, screenVideoBuffer.pixelFormat);
1833
+ this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, screenVideoBuffer.width, screenVideoBuffer.height, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1696
1834
  }
1697
1835
  }
1698
1836
  this.addRemoteVideoRenderCallback(userId);
@@ -1717,18 +1855,65 @@ class TRTCCloud extends events_1.EventEmitter {
1717
1855
  let key = this.getKey(userId, streamType);
1718
1856
  this._destroyRender(key, null);
1719
1857
  this.rtcCloud.stopRemoteView(userId, streamType);
1720
- const videoBufferInfo = remoteVideoBufferMap.get(userId);
1721
- if (videoBufferInfo && videoBufferInfo.streamType === streamType) {
1722
- this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, 0, 0, videoBufferInfo.pixelFormat);
1723
- videoBufferInfo.buffer = null;
1724
- remoteVideoBufferMap.delete(userId);
1858
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
1859
+ if (remoteUserVideoBuffers && streamType !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
1860
+ if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && remoteUserVideoBuffers.big) {
1861
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.big.buffer, remoteUserVideoBuffers.big.streamType, 0, 0, remoteUserVideoBuffers.big.pixelFormat, remoteUserVideoBuffers.big.id);
1862
+ remoteUserVideoBuffers.big.buffer = null;
1863
+ remoteUserVideoBuffers.big = undefined;
1864
+ }
1865
+ else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && remoteUserVideoBuffers.small) {
1866
+ this.rtcCloud.setRemoteVideoBuffer(userId, remoteUserVideoBuffers.small.buffer, remoteUserVideoBuffers.small.streamType, 0, 0, remoteUserVideoBuffers.small.pixelFormat, remoteUserVideoBuffers.small.id);
1867
+ remoteUserVideoBuffers.small.buffer = null;
1868
+ remoteUserVideoBuffers.small = undefined;
1869
+ }
1870
+ if (!remoteUserVideoBuffers.big && !remoteUserVideoBuffers.small) {
1871
+ remoteVideoBufferMap.delete(userId);
1872
+ }
1725
1873
  }
1726
1874
  else if (screenVideoBuffer.userId === userId && screenVideoBuffer.streamType === streamType) {
1727
- this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat);
1875
+ this.rtcCloud.setSubVideoBuffer(userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1728
1876
  screenVideoBuffer.buffer = null;
1877
+ screenVideoBuffer.id = 0;
1729
1878
  screenVideoBuffer.userId = '';
1730
1879
  }
1731
1880
  }
1881
+ /**
1882
+ * 3.7 修改远端视频渲染的 HTML 元素
1883
+ *
1884
+ * 本接口用于切换显示区域的交互场景中,修改远端视频渲染的 HTML 元素。
1885
+ *
1886
+ * 注意:必须调用 [startRemoteView()]{@link TRTCCloud#startRemoteView} 订阅了远端视频流之后,调用此接口才会生效。
1887
+ *
1888
+ * @param {String} userId - 远端视频流的用户 ID
1889
+ * @param {HTMLElement|null} view - 接受远端视频流渲染的 HTML 元素,传入 null 结束远端视频的渲染
1890
+ * - 传入的 HTML 元素必须时块元素,例如:div
1891
+ * @param {TRTCVideoStreamType} streamType - 视频流类型
1892
+ *
1893
+ */
1894
+ updateRemoteView(userId, view, streamType) {
1895
+ if (streamType === undefined) {
1896
+ streamType = this.priorRemoteVideoStreamType;
1897
+ }
1898
+ let bindStreamType = streamType;
1899
+ if (bindStreamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall) {
1900
+ // 如果拉取小流, 绑定 render 时也采用大流, 防止大小流切换后无法找到对应 render 进行渲染
1901
+ // 这里的逻辑和 _onRenderFrame 里, 获取 render 是不论小流还是大流, 都采用大流取获取 render 有关
1902
+ bindStreamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
1903
+ }
1904
+ const key = this.getKey(userId, bindStreamType);
1905
+ if (view !== null && view instanceof HTMLElement) {
1906
+ this._initRender(key, view);
1907
+ }
1908
+ else if (view === null) {
1909
+ if (this.streams.has(String(key))) {
1910
+ this._destroyRender(key, null);
1911
+ }
1912
+ }
1913
+ else {
1914
+ console.error('trtc:updateRemoteView() called with wrong view parameter', view);
1915
+ }
1916
+ }
1732
1917
  /**
1733
1918
  * 3.6 停止显示所有远端视频画面,同时不再拉取该远端用户的视频数据流
1734
1919
  *
@@ -1743,13 +1928,20 @@ class TRTCCloud extends events_1.EventEmitter {
1743
1928
  });
1744
1929
  this.rtcCloud.stopAllRemoteView();
1745
1930
  remoteVideoBufferMap.forEach((value, key) => {
1746
- this.rtcCloud.setRemoteVideoBuffer(key, value.buffer, value.streamType, 0, 0, value.pixelFormat);
1747
- value.buffer = null;
1931
+ if (value.big) {
1932
+ this.rtcCloud.setRemoteVideoBuffer(key, value.big.buffer, value.big.streamType, 0, 0, value.big.pixelFormat, value.big.id);
1933
+ value.big.buffer = null;
1934
+ }
1935
+ if (value.small) {
1936
+ this.rtcCloud.setRemoteVideoBuffer(key, value.small.buffer, value.small.streamType, 0, 0, value.small.pixelFormat, value.small.id);
1937
+ value.small.buffer = null;
1938
+ }
1748
1939
  });
1749
1940
  remoteVideoBufferMap.clear();
1750
1941
  if (screenVideoBuffer.buffer && !this.isScreenCapturing) {
1751
- this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat);
1942
+ this.rtcCloud.setSubVideoBuffer(screenVideoBuffer.userId, screenVideoBuffer.buffer, screenVideoBuffer.streamType, 0, 0, screenVideoBuffer.pixelFormat, screenVideoBuffer.id);
1752
1943
  screenVideoBuffer.buffer = null;
1944
+ screenVideoBuffer.id = 0;
1753
1945
  screenVideoBuffer.userId = '';
1754
1946
  }
1755
1947
  }
@@ -1855,7 +2047,7 @@ class TRTCCloud extends events_1.EventEmitter {
1855
2047
  }
1856
2048
  }
1857
2049
  /**
1858
- * 3.13 设置远端图像的渲染模式
2050
+ * 3.13 设置远端画面的渲染模式
1859
2051
  *
1860
2052
  * @param {String} userId - 用户 ID
1861
2053
  * @param {TRTCVideoStreamType} streamType - 视频流类型
@@ -2007,12 +2199,36 @@ class TRTCCloud extends events_1.EventEmitter {
2007
2199
  * 如果该 userId 没有开启双路编码模式,则此操作无效。
2008
2200
  *
2009
2201
  * @param {String} userId - 用户 ID
2010
- * @param {TRTCVideoStreamType} type - 视频流类型,即选择看大画面还是小画面,默认为 TRTCVideoStreamTypeBig
2202
+ * @param {TRTCVideoStreamType} streamType - 视频流类型,即选择看大画面还是小画面,默认为 TRTCVideoStreamTypeBig
2011
2203
  * - TRTCVideoStreamTypeBig : 大画面视频流
2012
2204
  * - TRTCVideoStreamTypeSmall: 小画面视频流
2013
2205
  */
2014
- setRemoteVideoStreamType(userId, type) {
2015
- this.rtcCloud.setRemoteVideoStreamType(userId, type);
2206
+ setRemoteVideoStreamType(userId, streamType) {
2207
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(userId);
2208
+ if (remoteUserVideoBuffers) {
2209
+ const videoBufferInfo = {
2210
+ userId: userId,
2211
+ buffer: (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength, userId, streamType),
2212
+ id: (0, util_1.generateUniqueId)(),
2213
+ streamType: streamType,
2214
+ width: DEFAULT_VIDEO_WIDTH,
2215
+ height: DEFAULT_VIDEO_HEIGHT,
2216
+ pixelFormat: this.pixelformate,
2217
+ };
2218
+ if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && !remoteUserVideoBuffers.big) {
2219
+ remoteUserVideoBuffers.big = videoBufferInfo;
2220
+ this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
2221
+ }
2222
+ else if (streamType === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && !remoteUserVideoBuffers.small) {
2223
+ remoteUserVideoBuffers.small = videoBufferInfo;
2224
+ this.rtcCloud.setRemoteVideoBuffer(userId, videoBufferInfo.buffer, videoBufferInfo.streamType, videoBufferInfo.width, videoBufferInfo.height, videoBufferInfo.pixelFormat, videoBufferInfo.id);
2225
+ }
2226
+ else {
2227
+ videoBufferInfo.buffer = null;
2228
+ videoBufferInfo.id = 0;
2229
+ }
2230
+ }
2231
+ this.rtcCloud.setRemoteVideoStreamType(userId, streamType);
2016
2232
  }
2017
2233
  /**
2018
2234
  * 3.22 视频画面截图
@@ -2097,7 +2313,11 @@ class TRTCCloud extends events_1.EventEmitter {
2097
2313
  this.rtcCloud.muteRemoteAudio(userId, mute);
2098
2314
  }
2099
2315
  /**
2100
- * 4.5 静音掉所有用户的声音,同时不再拉取该远端用户的音频数据流
2316
+ * 4.5 静音/取消静音所有远端用户的音频流
2317
+ *
2318
+ * 当您静音所有用户的远端音频时,SDK 会停止播放所有来自远端的音频流,同时也会停止拉取所有用户的音频数据。
2319
+ *
2320
+ * 注意:该接口支持您在进入房间(enterRoom)前调用,暂停状态会在退出房间(exitRoom)在之后会被重置。
2101
2321
  *
2102
2322
  * @param {Boolean} mute - true:静音;false:非静音
2103
2323
  */
@@ -2157,10 +2377,11 @@ class TRTCCloud extends events_1.EventEmitter {
2157
2377
  * 我们在 Demo 中有一个音量大小的提示条,就是基于这个接口实现的。
2158
2378
  * 如希望打开此功能,请在 startLocalAudio() 之前调用。
2159
2379
  *
2160
- * @param {Number} interval - 设置 onUserVoiceVolume 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms
2380
+ * @param {Number} interval - 设置 onUserVoiceVolume 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms
2381
+ * @param {Boolean} enableVad - true: 打开人声检测;false: 关闭人声检测。目前仅 windows 支持。
2161
2382
  */
2162
- enableAudioVolumeEvaluation(interval) {
2163
- this.rtcCloud.enableAudioVolumeEvaluation(interval);
2383
+ enableAudioVolumeEvaluation(interval, enableVad = false) {
2384
+ this.rtcCloud.enableAudioVolumeEvaluation(interval, enableVad);
2164
2385
  }
2165
2386
  /**
2166
2387
  * 4.12 开始录音
@@ -2215,6 +2436,15 @@ class TRTCCloud extends events_1.EventEmitter {
2215
2436
  setAudioQuality(quality) {
2216
2437
  this.audioQuality = quality;
2217
2438
  }
2439
+ /**
2440
+ * 4.15 废弃接口:设置麦克风的音量大小
2441
+ *
2442
+ * @deprecated 从 TRTCSDK6.9 后该接口已被废弃,请使用 setAudioCaptureVolume 接口替代。
2443
+ * @param {Number} volume - 音量大小,100为正常音量,取值范围为0 - 200。
2444
+ */
2445
+ setMicVolumeOnMixing(volume) {
2446
+ this.setAudioCaptureVolume(volume);
2447
+ }
2218
2448
  /////////////////////////////////////////////////////////////////////////////////
2219
2449
  //
2220
2450
  // (五)摄像头相关接口函数
@@ -2224,7 +2454,7 @@ class TRTCCloud extends events_1.EventEmitter {
2224
2454
  * 5.1 获取摄像头设备列表
2225
2455
  *
2226
2456
  * @example
2227
- * var cameralist = this.rtcCloud.getCameraDevicesList();
2457
+ * var cameralist = rtcCloud.getCameraDevicesList();
2228
2458
  * for (i=0;i<cameralist.length;i++) {
2229
2459
  * var camera = cameralist[i];
2230
2460
  * console.info("camera deviceName: " + camera.deviceName + " deviceId:" + camera.deviceId);
@@ -2259,7 +2489,7 @@ class TRTCCloud extends events_1.EventEmitter {
2259
2489
  * 6.1 获取麦克风设备列表
2260
2490
  *
2261
2491
  * @example
2262
- * var miclist = this.rtcCloud.getMicDevicesList();
2492
+ * var miclist = rtcCloud.getMicDevicesList();
2263
2493
  * for (i=0;i<miclist.length;i++) {
2264
2494
  * var mic = miclist[i];
2265
2495
  * console.info("mic deviceName: " + mic.deviceName + " deviceId:" + mic.deviceId);
@@ -2325,7 +2555,7 @@ class TRTCCloud extends events_1.EventEmitter {
2325
2555
  * 6.8 获取扬声器设备列表
2326
2556
  *
2327
2557
  * @example
2328
- * var speakerlist = this.rtcCloud.getSpeakerDevicesList();
2558
+ * var speakerlist = rtcCloud.getSpeakerDevicesList();
2329
2559
  * for (i=0;i<speakerlist.length;i++) {
2330
2560
  * var speaker = speakerlist[i];
2331
2561
  * console.info("mic deviceName: " + speaker.deviceName + " deviceId:" + speaker.deviceId);
@@ -2354,10 +2584,6 @@ class TRTCCloud extends events_1.EventEmitter {
2354
2584
  /**
2355
2585
  * 6.11 获取系统当前扬声器设备音量
2356
2586
  *
2357
- * 注意:
2358
- * - SDK6.7 及以下版本,windows 查询的不是系统扬声器的音量大小,mac 是查询系统扬声器音量大小
2359
- * - SDK6.8 及以上版本,windows 和 mac 查询的都是系统扬声器的音量大小
2360
- *
2361
2587
  * @return {Number} 扬声器音量,范围0 - 100
2362
2588
  */
2363
2589
  getCurrentSpeakerVolume() {
@@ -2367,8 +2593,6 @@ class TRTCCloud extends events_1.EventEmitter {
2367
2593
  * 6.12 设置系统当前扬声器设备音量
2368
2594
  *
2369
2595
  * 注意:该接口的功能是调节系统播放音量,如果用户直接调节系统设置的播放音量时,该接口的设置结果会被用户的操作所覆盖。
2370
- * - SDK6.7 及以下版本,windows 设置的不是系统扬声器的音量大小,mac 是设置系统扬声器音量大小
2371
- * - SDK6.8 及以上版本,windows 和 mac 设置的都是系统扬声器的音量大小
2372
2596
  *
2373
2597
  * @param {Number} volume - 设置的扬声器音量,范围0 - 100
2374
2598
  */
@@ -2518,7 +2742,7 @@ class TRTCCloud extends events_1.EventEmitter {
2518
2742
  * 8.5 枚举可共享的窗口列表
2519
2743
  *
2520
2744
  * 如果您要给您的 App 增加屏幕分享功能,一般需要先显示一个窗口选择界面,这样用户可以选择希望分享的窗口。
2521
- * 通过如下函数,您可以获得可分享窗口的 ID、类型、窗口名称以及缩略图。
2745
+ * 通过此函数,您可以获得可分享窗口的 ID、类型、窗口名称以及缩略图。
2522
2746
  * 拿到这些信息后,您就可以实现一个窗口选择界面,当然,您也可以使用我们在 Demo 源码中已经实现好的一个界面。
2523
2747
  *
2524
2748
  * 注意:返回的列表中包括屏幕和应用窗口,屏幕会在列表的前面几个元素中。
@@ -2564,6 +2788,7 @@ class TRTCCloud extends events_1.EventEmitter {
2564
2788
  * @param {Boolean} highlightWindow - 指定是否高亮正在共享的窗口,以及当捕获图像被遮挡时高亮遮挡窗口提示用户移走遮挡
2565
2789
  */
2566
2790
  selectScreenCaptureTarget(source, captureRect, property, deprecatedCaptureRect, captureMouse, highlightWindow) {
2791
+ console.debug('trtc:selectScreenCaptureTarget:', source, captureRect, property, deprecatedCaptureRect, captureMouse, highlightWindow);
2567
2792
  if (source.sourceId && captureRect instanceof trtc_define_1.Rect && property instanceof trtc_define_1.TRTCScreenCaptureProperty) {
2568
2793
  const realSource = source;
2569
2794
  return this.rtcCloud.selectScreenCaptureTarget(realSource.type, realSource.sourceId, realSource.sourceName, realSource.isMinimizeWindow, captureRect.left, captureRect.top, captureRect.right, captureRect.bottom, property.enableCaptureMouse, property.enableHighLight, property.enableHighPerformance, property.highLightColor, property.highLightWidth, property.enableCaptureChildWindow);
@@ -2583,7 +2808,7 @@ class TRTCCloud extends events_1.EventEmitter {
2583
2808
  }
2584
2809
  }
2585
2810
  /**
2586
- * 8.7 启动屏幕分享,支持选择使用主路或辅路进行屏幕分享。(暂不支持 mac 平台预览界面)
2811
+ * 8.7 启动屏幕分享,支持选择使用主路或辅路进行屏幕分享。
2587
2812
  *
2588
2813
  * 注意:
2589
2814
  * 一个用户同时最多只能上传一条主路(TRTCVideoStreamTypeBig)画面和一条辅路(TRTCVideoStreamTypeSub)画面,
@@ -2601,6 +2826,10 @@ class TRTCCloud extends events_1.EventEmitter {
2601
2826
  console.error('trtc:startScreenCapture, params is not instanceof TRTCVideoEncParam!');
2602
2827
  return;
2603
2828
  }
2829
+ if (this.isScreenCapturing && this.screenCaptureStreamType !== type && screenVideoBuffer.buffer) {
2830
+ // 已经在分享中,切换分享流类型,停止当前正在进行的分享
2831
+ this.stopScreenCapture();
2832
+ }
2604
2833
  this.screenCaptureStreamType = type;
2605
2834
  if (view !== undefined) {
2606
2835
  if (view !== null) {
@@ -2638,12 +2867,14 @@ class TRTCCloud extends events_1.EventEmitter {
2638
2867
  this.screenCaptureStreamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub;
2639
2868
  }
2640
2869
  /**
2641
- * 8.11 设置辅流(屏幕分享)的编码器参数
2870
+ * 8.11 设置屏幕分享(即辅路)的视频编码参数
2642
2871
  *
2643
- * - setVideoEncoderParam() 用于设置远端主路画面(TRTCVideoStreamTypeBig,一般用于摄像头)的编码参数。
2644
- * - setSubStreamEncoderParam() 用于设置远端辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)的编码参数。
2872
+ * 该接口可以设定远端用户所看到的屏幕分享(即辅路)的画面质量,同时也能决定云端录制出的视频文件中屏幕分享的画面质量。 请注意如下两个接口的差异:
2873
+ * - setVideoEncoderParam() 用于设置主路画面(TRTCVideoStreamTypeBig,一般用于摄像头)的视频编码参数。
2874
+ * - setSubStreamEncoderParam() 用于设置辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)的视频编码参数。
2645
2875
  *
2646
- * 该设置决定了远端用户看到的画面质量,同时也是云端录制出的视频文件的画面质量。
2876
+ * 注意:
2877
+ * 即使您使用主路传输屏幕分享(在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig),依然要使用 setSubStreamEncoderParam 设定屏幕分享的编码参数,而不要使用 setVideoEncoderParam 。
2647
2878
  *
2648
2879
  * @param {TRTCVideoEncParam} params - 辅流(屏幕分享)编码参数
2649
2880
  * @param {TRTCVideoResolution} params.videoResolution - 视频分辨率
@@ -3058,7 +3289,13 @@ class TRTCCloud extends events_1.EventEmitter {
3058
3289
  return this.rtcCloud.seekMusicToPosInTime(id, pts);
3059
3290
  }
3060
3291
  /**
3061
- * 11.19 设置背景音乐的音量大小,播放背景音乐混音时使用,用来控制背景音音量大小
3292
+ * 11.19 设置所有背景音乐的本地音量和远端音量的大小
3293
+ *
3294
+ * 该接口可以设置所有背景音乐的本地音量和远端音量。
3295
+ * - 本地音量:即主播本地可以听到的背景音乐的音量大小。
3296
+ * - 远端音量:即观众端可以听到的背景音乐的音量大小。
3297
+ *
3298
+ * 注意:如果将 volume 设置成 100 之后感觉音量还是太小,可以将 volume 最大设置成 150,但超过 100 的 volume 会有爆音的风险,请谨慎操作。
3062
3299
  *
3063
3300
  * @param {Number} volume - 音量大小,100为正常音量,取值范围为0 - 200。
3064
3301
  */
@@ -3227,17 +3464,7 @@ class TRTCCloud extends events_1.EventEmitter {
3227
3464
  this.rtcCloud.stopSpeedTest();
3228
3465
  }
3229
3466
  /**
3230
- * 13.3 设置 SDK 使用的音频设备根据跟随系统默认设备
3231
- *
3232
- * @param {TRTCDeviceType} deviceType - 设备类型
3233
- * @param {Boolean} enable - 是否跟随系统默认的音频设备。 true:跟随, 当系统默认音频设备发生改变时,SDK 立即切换音频设备; false:不跟随, 只有当 SDK 使用的音频设备被移除后或插入新的音频设备为系统默认设备时,SDK 才切换至系统默认的音频设备。
3234
- *
3235
- */
3236
- enableFollowingDefaultAudioDevice(deviceType, enable) {
3237
- this.rtcCloud.enableFollowingDefaultAudioDevice(deviceType, enable);
3238
- }
3239
- /**
3240
- * 13.4 开始进行摄像头测试
3467
+ * 13.3 开始进行摄像头测试
3241
3468
  *
3242
3469
  * 会触发 onFirstVideoFrame 回调接口
3243
3470
  *
@@ -3248,24 +3475,35 @@ class TRTCCloud extends events_1.EventEmitter {
3248
3475
  startCameraDeviceTest(view) {
3249
3476
  if (view !== undefined) {
3250
3477
  if (view !== null) {
3251
- let key = this.getKey(CAMERA_DEVICE_TEST_VIEW, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
3478
+ const key = this.getKey(CAMERA_DEVICE_TEST_VIEW, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
3252
3479
  this._initRender(key, view);
3253
3480
  const renderer = this.streams.get(key);
3254
3481
  renderer.setContentMode(trtc_define_1.TRTCVideoFillMode.TRTCVideoFillMode_Fill);
3255
3482
  }
3256
- // Buffer 为 null 时才新建,否则只能在 onVideoSizeChange 事件中重新申请 Buffer
3483
+ // Buffer 为 null 时才新建,否则只能在 handleVideoSizeChange 事件中重新申请 Buffer
3257
3484
  if (!cameraTestVideoBuffer.buffer) {
3258
3485
  const streamType = trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
3259
3486
  cameraTestVideoBuffer.streamType = streamType;
3260
3487
  cameraTestVideoBuffer.pixelFormat = this.pixelformate;
3261
3488
  cameraTestVideoBuffer.buffer = (0, util_1.allocBuffer)(DEFAULT_VIDEO_WIDTH * DEFAULT_VIDEO_HEIGHT * this.pixelLength, cameraTestVideoBuffer.userId, streamType);
3489
+ cameraTestVideoBuffer.id = (0, util_1.generateUniqueId)();
3262
3490
  cameraTestVideoBuffer.width = DEFAULT_VIDEO_WIDTH;
3263
3491
  cameraTestVideoBuffer.height = DEFAULT_VIDEO_HEIGHT;
3264
- this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, cameraTestVideoBuffer.width, cameraTestVideoBuffer.height, cameraTestVideoBuffer.pixelFormat);
3492
+ this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, cameraTestVideoBuffer.width, cameraTestVideoBuffer.height, cameraTestVideoBuffer.pixelFormat, cameraTestVideoBuffer.id);
3265
3493
  }
3266
- this.rtcCloud.startCameraDeviceTest((id, type, width, height, timestamp, rotation) => {
3494
+ this.rtcCloud.startCameraDeviceTest((id, type, width, height, timestamp, rotation, valid, bufferId) => {
3267
3495
  if (this.enableRenderFrame) {
3268
- this._onRenderFrame(id, type, width, height, timestamp, rotation, cameraTestVideoBuffer.buffer);
3496
+ if (valid === 1) {
3497
+ if (cameraTestVideoBuffer.id === bufferId) {
3498
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, cameraTestVideoBuffer.buffer);
3499
+ }
3500
+ else {
3501
+ console.log('trtc:camera video buffer reallocated');
3502
+ }
3503
+ }
3504
+ else {
3505
+ this.handleVideoSizeChange(id, type, width, height);
3506
+ }
3269
3507
  }
3270
3508
  });
3271
3509
  }
@@ -3274,7 +3512,7 @@ class TRTCCloud extends events_1.EventEmitter {
3274
3512
  }
3275
3513
  }
3276
3514
  /**
3277
- * 13.5 停止摄像头测试
3515
+ * 13.4 停止摄像头测试
3278
3516
  */
3279
3517
  stopCameraDeviceTest() {
3280
3518
  let key = this.getKey(CAMERA_DEVICE_TEST_VIEW, trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
@@ -3284,30 +3522,32 @@ class TRTCCloud extends events_1.EventEmitter {
3284
3522
  return !('' === item.uid && item.type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig);
3285
3523
  });
3286
3524
  if (cameraTestVideoBuffer.buffer) {
3287
- this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, 0, 0, cameraTestVideoBuffer.pixelFormat);
3525
+ this.rtcCloud.setCameraTestVideoBuffer(cameraTestVideoBuffer.buffer, 0, 0, cameraTestVideoBuffer.pixelFormat, cameraTestVideoBuffer.id);
3288
3526
  cameraTestVideoBuffer.buffer = null;
3527
+ cameraTestVideoBuffer.id = 0;
3289
3528
  }
3290
3529
  }
3291
3530
  /**
3292
- * 13.6 开始进行麦克风测试
3531
+ * 13.5 开始进行麦克风测试
3293
3532
  *
3294
3533
  * 回调接口 onTestMicVolume 获取测试数据
3295
3534
  *
3296
3535
  * 该方法测试麦克风是否能正常工作,volume 的取值范围为0 - 100。
3297
3536
  *
3298
3537
  * @param {Number} interval - 反馈音量提示的时间间隔(ms),建议设置到大于 200 毫秒
3538
+ * @param {Boolean} playback - 是否开启回播麦克风声音,开启后用户测试麦克风时会听到自己的声音。默认值 true
3299
3539
  */
3300
- startMicDeviceTest(interval) {
3301
- this.rtcCloud.startMicDeviceTest(interval);
3540
+ startMicDeviceTest(interval, playback = true) {
3541
+ this.rtcCloud.startMicDeviceTest(interval, playback);
3302
3542
  }
3303
3543
  /**
3304
- * 13.7 停止麦克风测试
3544
+ * 13.6 停止麦克风测试
3305
3545
  */
3306
3546
  stopMicDeviceTest() {
3307
3547
  this.rtcCloud.stopMicDeviceTest();
3308
3548
  }
3309
3549
  /**
3310
- * 13.8 开始进行扬声器测试
3550
+ * 13.7 开始进行扬声器测试
3311
3551
  *
3312
3552
  * 回调接口 onTestSpeakerVolume 获取测试数据
3313
3553
  *
@@ -3320,7 +3560,7 @@ class TRTCCloud extends events_1.EventEmitter {
3320
3560
  this.rtcCloud.startSpeakerDeviceTest(testAudioFilePath);
3321
3561
  }
3322
3562
  /**
3323
- * 13.9 停止扬声器测试
3563
+ * 13.8 停止扬声器测试
3324
3564
  */
3325
3565
  stopSpeakerDeviceTest() {
3326
3566
  this.rtcCloud.stopSpeakerDeviceTest();
@@ -3409,25 +3649,16 @@ class TRTCCloud extends events_1.EventEmitter {
3409
3649
  // (十五) 废弃接口函数
3410
3650
  //
3411
3651
  /////////////////////////////////////////////////////////////////////////////////
3412
- /**
3413
- * 从 TRTCSDK6.9 后该接口已被废弃
3414
- *
3415
- * @deprecated 从 TRTCSDK6.9 后该接口已被废弃,请使用 setAudioCaptureVolume 接口替代。
3416
- * @param {Number} volume - 音量大小,100为正常音量,取值范围为0 - 200。
3417
- */
3418
- setMicVolumeOnMixing(volume) {
3419
- this.setAudioCaptureVolume(volume);
3420
- }
3421
3652
  ///------------------------内部方法-----------------------------
3422
3653
  addLocalVideoRenderCallback() {
3423
- if ([1, 2, 5].indexOf(this.renderMode) !== -1) {
3424
- this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3425
- this.pixelLength = 1.5;
3426
- }
3427
- else if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(this.renderMode) !== -1) {
3654
+ if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(this.renderMode) !== -1) {
3428
3655
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_RGBA32;
3429
3656
  this.pixelLength = 4;
3430
3657
  }
3658
+ else if ([1, 2, 5].indexOf(this.renderMode) !== -1) {
3659
+ this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3660
+ this.pixelLength = 1.5;
3661
+ }
3431
3662
  else if ([7, 8].indexOf(this.renderMode) !== -1) {
3432
3663
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32;
3433
3664
  this.pixelLength = 4;
@@ -3436,24 +3667,34 @@ class TRTCCloud extends events_1.EventEmitter {
3436
3667
  console.error('trtc: not supported renderMode:', this.renderMode);
3437
3668
  return;
3438
3669
  }
3439
- this.rtcCloud.addLocalVideoRenderCallback((id, type, width, height, timestamp, rotation) => {
3440
- if (this.isScreenCapturing && this.screenCaptureStreamType === type) {
3441
- this._onRenderFrame(id, type, width, height, timestamp, rotation, screenVideoBuffer.buffer);
3442
- }
3443
- else {
3444
- this._onRenderFrame(id, type, width, height, timestamp, rotation, localVideoBuffer.buffer);
3670
+ this.rtcCloud.addLocalVideoRenderCallback((id, type, width, height, timestamp, rotation, valid, bufferId) => {
3671
+ if (this.enableRenderFrame) {
3672
+ if (valid === 1) {
3673
+ if (this.isScreenCapturing && this.screenCaptureStreamType === type && screenVideoBuffer.id === bufferId) {
3674
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, screenVideoBuffer.buffer);
3675
+ }
3676
+ else if (localVideoBuffer.id === bufferId) {
3677
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, localVideoBuffer.buffer);
3678
+ }
3679
+ else {
3680
+ console.log(`trtc: ${id} ${type} video buffer reallocated`);
3681
+ }
3682
+ }
3683
+ else {
3684
+ this.handleVideoSizeChange(id, type, width, height);
3685
+ }
3445
3686
  }
3446
3687
  }, this.pixelformate);
3447
3688
  }
3448
3689
  addRemoteVideoRenderCallback(userId) {
3449
- if ([1, 2, 5].indexOf(this.renderMode) !== -1) {
3450
- this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3451
- this.pixelLength = 1.5;
3452
- }
3453
- else if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(this.renderMode) !== -1) {
3690
+ if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(this.renderMode) !== -1) {
3454
3691
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_RGBA32;
3455
3692
  this.pixelLength = 4;
3456
3693
  }
3694
+ else if ([1, 2, 5].indexOf(this.renderMode) !== -1) {
3695
+ this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3696
+ this.pixelLength = 1.5;
3697
+ }
3457
3698
  else if ([7, 8].indexOf(this.renderMode) !== -1) {
3458
3699
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32;
3459
3700
  this.pixelLength = 4;
@@ -3462,13 +3703,30 @@ class TRTCCloud extends events_1.EventEmitter {
3462
3703
  console.error('trtc: not supported renderMode:', this.renderMode);
3463
3704
  return;
3464
3705
  }
3465
- this.rtcCloud.addRemoteVideoRenderCallback(userId, (id, type, width, height, timestamp, rotation) => {
3466
- const videoBufferInfo = remoteVideoBufferMap.get(id);
3467
- if (videoBufferInfo && videoBufferInfo.streamType === type) {
3468
- this._onRenderFrame(id, type, width, height, timestamp, rotation, videoBufferInfo.buffer);
3469
- }
3470
- else {
3471
- this._onRenderFrame(id, type, width, height, timestamp, rotation, screenVideoBuffer.buffer);
3706
+ this.rtcCloud.addRemoteVideoRenderCallback(userId, (id, type, width, height, timestamp, rotation, valid, bufferId) => {
3707
+ if (this.enableRenderFrame) {
3708
+ if (valid === 1) {
3709
+ const remoteUserVideoBuffers = remoteVideoBufferMap.get(id);
3710
+ if (remoteUserVideoBuffers && type !== trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
3711
+ // 大流和小流
3712
+ if (type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeBig && remoteUserVideoBuffers.big && remoteUserVideoBuffers.big.id === bufferId) {
3713
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, remoteUserVideoBuffers.big.buffer);
3714
+ }
3715
+ else if (type === trtc_define_1.TRTCVideoStreamType.TRTCVideoStreamTypeSmall && remoteUserVideoBuffers.small && remoteUserVideoBuffers.small.id === bufferId) {
3716
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, remoteUserVideoBuffers.small.buffer);
3717
+ }
3718
+ }
3719
+ else if (screenVideoBuffer.id === bufferId) {
3720
+ // 辅流
3721
+ this._onRenderFrame(id, type, width, height, timestamp, rotation, screenVideoBuffer.buffer);
3722
+ }
3723
+ else {
3724
+ console.log(`trtc: ${id} ${type} video buffer reallocated`);
3725
+ }
3726
+ }
3727
+ else {
3728
+ this.handleVideoSizeChange(id, type, width, height);
3729
+ }
3472
3730
  }
3473
3731
  }, this.pixelformate);
3474
3732
  }
@@ -3496,14 +3754,14 @@ class TRTCCloud extends events_1.EventEmitter {
3496
3754
  this.streams.forEach((value, key, map) => {
3497
3755
  oldStreams.set(key, value);
3498
3756
  });
3499
- if ([1, 2, 5].indexOf(mode) !== -1) {
3500
- this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3501
- this.pixelLength = 1.5;
3502
- }
3503
- else if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(mode) !== -1) {
3757
+ if (this.isExternalRenderEnabled || [3, 4, 6].indexOf(mode) !== -1) {
3504
3758
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_RGBA32;
3505
3759
  this.pixelLength = 4;
3506
3760
  }
3761
+ else if ([1, 2, 5].indexOf(mode) !== -1) {
3762
+ this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420;
3763
+ this.pixelLength = 1.5;
3764
+ }
3507
3765
  else {
3508
3766
  // 7,8
3509
3767
  this.pixelformate = trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32;
@@ -3867,7 +4125,7 @@ class TRTCCloud extends events_1.EventEmitter {
3867
4125
  }
3868
4126
  else if (format == trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32) {
3869
4127
  if (this.renderMode !== 3) {
3870
- videoframe.data = this._YUV2RGBA(width, height, data);
4128
+ videoframe.data = this._YUV2RGBA(width, height, data.buffer || data);
3871
4129
  videoframe.length = width * height * 4;
3872
4130
  callback(userid, streamType, videoframe);
3873
4131
  }