@rongcloud/plugin-rtc 5.2.2-alpha.1 → 5.2.4-beem.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.
package/dist/index.umd.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
- * RCRTC - v5.2.2-alpha.1
3
- * CommitId - de4f9bc28bbee35d2d5f206a68144c89c098573f
4
- * Mon Nov 22 2021 10:51:42 GMT+0800 (China Standard Time)
2
+ * RCRTC - v5.2.4-beem.1
3
+ * CommitId - d026964c6715be7805a3e5c8addd64d4008d17bd
4
+ * Thu May 12 2022 18:57:27 GMT+0800 (China Standard Time)
5
5
  * ©2020 RongCloud, Inc. All rights reserved.
6
6
  */
7
7
  (function (global, factory) {
@@ -5603,6 +5603,25 @@
5603
5603
  RCResolution["W1920_H1080"] = "W1920_H1080";
5604
5604
  })(exports.RCResolution || (exports.RCResolution = {}));
5605
5605
 
5606
+ /**
5607
+ * 媒体资源类型
5608
+ */
5609
+ exports.RCMediaType = void 0;
5610
+ (function (RCMediaType) {
5611
+ /**
5612
+ * 音频流
5613
+ */
5614
+ RCMediaType[RCMediaType["AUDIO_ONLY"] = 0] = "AUDIO_ONLY";
5615
+ /**
5616
+ * 视频流
5617
+ */
5618
+ RCMediaType[RCMediaType["VIDEO_ONLY"] = 1] = "VIDEO_ONLY";
5619
+ /**
5620
+ * 音视频混合流,只在 web 端存在混合流的情况
5621
+ */
5622
+ RCMediaType[RCMediaType["AUDIO_VIDEO"] = 2] = "AUDIO_VIDEO";
5623
+ })(exports.RCMediaType || (exports.RCMediaType = {}));
5624
+
5606
5625
  const RongRTCVideoBitrate = {
5607
5626
  [exports.RCResolution.W176_H132]: { width: 176, height: 132, maxBitrate: 150, minBitrate: 80 },
5608
5627
  [exports.RCResolution.W176_H144]: { width: 176, height: 144, maxBitrate: 160, minBitrate: 80 },
@@ -6121,6 +6140,40 @@
6121
6140
  class RCScreenVideoTrack extends RCLocalVideoTrack {
6122
6141
  }
6123
6142
 
6143
+ class RCRemoteTrack extends RCTrack {
6144
+ constructor(tag, userId, kind, roomId) {
6145
+ super(tag, userId, kind, false, roomId);
6146
+ this._isSubscribed = false;
6147
+ }
6148
+ /**
6149
+ * 根据房间数据更新状态
6150
+ * @param value
6151
+ */
6152
+ __innerSetRemoteMuted(bool) {
6153
+ this._remoteMuted = bool;
6154
+ }
6155
+ __innerSetSubscribed(bool) {
6156
+ this._isSubscribed = bool;
6157
+ }
6158
+ /**
6159
+ * 查看是否已订阅了该远端资源
6160
+ * @returns
6161
+ */
6162
+ isSubscribed() {
6163
+ return this._isSubscribed;
6164
+ }
6165
+ }
6166
+ class RCRemoteAudioTrack extends RCRemoteTrack {
6167
+ constructor(tag, userId, roomId) {
6168
+ super(tag, userId, 'audio', roomId);
6169
+ }
6170
+ }
6171
+ class RCRemoteVideoTrack extends RCRemoteTrack {
6172
+ constructor(tag, userId, roomId) {
6173
+ super(tag, userId, 'video', roomId);
6174
+ }
6175
+ }
6176
+
6124
6177
  /**
6125
6178
  * 构建增量消息内容
6126
6179
  * @param objectname 消息名
@@ -6395,6 +6448,79 @@
6395
6448
  });
6396
6449
  return result;
6397
6450
  };
6451
+ /**
6452
+ * 解析观众加房间 kv 数据
6453
+ * 远端无人员时,kvEntries 的 key 不包含 RC_ANCHOR_LIST
6454
+ * 远端无资源时,key 不包含 RC_RES_、RC_CDN
6455
+ * 远端有资源、无 CDN 资源时,key 不包含 RC_CDN
6456
+ */
6457
+ const parseAudienceRoomData = (roomId, kvEntries) => {
6458
+ const sessionId = kvEntries.filter((kvItem) => {
6459
+ return kvItem.key === 'RC_RTC_SESSIONID';
6460
+ })[0].value;
6461
+ /**
6462
+ * 房间内远端人员
6463
+ */
6464
+ const remoteUserIds = kvEntries.filter((kvItem) => {
6465
+ return kvItem.key === 'RC_ANCHOR_LIST';
6466
+ }).map((kvItem) => JSON.parse(kvItem.value || '[]'))[0];
6467
+ /**
6468
+ * 远端 RTC、MUC 资源
6469
+ */
6470
+ const remoteRes = kvEntries.filter((kvItem) => {
6471
+ return kvItem.key.includes('RC_RES_');
6472
+ }).map((kvItem) => JSON.parse(kvItem.value || '{}'));
6473
+ /**
6474
+ * 远端 MUC 资源
6475
+ */
6476
+ const remoteMUCUris = remoteRes.length ? JSON.parse(remoteRes[0].mcu_uris || '[]') : [];
6477
+ /**
6478
+ * 远端 MUC tracks
6479
+ */
6480
+ const remoteMCUTracks = [];
6481
+ remoteMUCUris.forEach((uri) => {
6482
+ const { mediaType, tag } = uri;
6483
+ const track = mediaType === exports.RCMediaType.AUDIO_ONLY ? new RCRemoteAudioTrack(tag, '', roomId) : new RCRemoteVideoTrack(tag, '', roomId);
6484
+ remoteMCUTracks.push(track);
6485
+ });
6486
+ /**
6487
+ * 远端 RTC 资源
6488
+ */
6489
+ const remoteRTCUris = [];
6490
+ /**
6491
+ * 远端 RTC tracks
6492
+ */
6493
+ const remoteRTCTracks = [];
6494
+ remoteRes.forEach((res) => {
6495
+ const RTCUris = JSON.parse(res.uris || '[]');
6496
+ remoteRTCUris.push(...RTCUris);
6497
+ RTCUris.forEach((uri) => {
6498
+ const { mediaType, tag, msid } = uri;
6499
+ const userId = msid.split('_')[0];
6500
+ const track = mediaType === exports.RCMediaType.AUDIO_ONLY ? new RCRemoteAudioTrack(tag, userId) : new RCRemoteVideoTrack(tag, userId);
6501
+ remoteRTCTracks.push(track);
6502
+ });
6503
+ });
6504
+ /**
6505
+ * 房间内 CDN 信息
6506
+ */
6507
+ const CDNUris = kvEntries.filter((kvItem) => {
6508
+ return kvItem.key === 'RC_CDN';
6509
+ }).map((kvItem) => {
6510
+ const CDNUriStr = JSON.parse(kvItem.value || '[]');
6511
+ return JSON.parse(CDNUriStr.cdn_uris)[0];
6512
+ })[0];
6513
+ return {
6514
+ sessionId,
6515
+ remoteUserIds: remoteUserIds || [],
6516
+ remoteRTCUris,
6517
+ remoteMUCUris,
6518
+ remoteRTCTracks,
6519
+ remoteMCUTracks,
6520
+ remoteTracks: [...remoteRTCTracks, ...remoteMCUTracks],
6521
+ CDNUris: CDNUris || {}
6522
+ };
6523
+ };
6398
6524
 
6399
6525
  /**
6400
6526
  * RTC 消息类型常量
@@ -6560,7 +6686,7 @@
6560
6686
  audioLevel = audioLevel / 32767;
6561
6687
  }
6562
6688
  const rate = 10 ** factor;
6563
- return Math.floor(audioLevel * rate);
6689
+ return Math.ceil(audioLevel * rate);
6564
6690
  };
6565
6691
  /**
6566
6692
  * 计算丢包率
@@ -6602,25 +6728,6 @@
6602
6728
  return true;
6603
6729
  };
6604
6730
 
6605
- /**
6606
- * 媒体资源类型
6607
- */
6608
- exports.RCMediaType = void 0;
6609
- (function (RCMediaType) {
6610
- /**
6611
- * 音频流
6612
- */
6613
- RCMediaType[RCMediaType["AUDIO_ONLY"] = 0] = "AUDIO_ONLY";
6614
- /**
6615
- * 视频流
6616
- */
6617
- RCMediaType[RCMediaType["VIDEO_ONLY"] = 1] = "VIDEO_ONLY";
6618
- /**
6619
- * 音视频混合流,只在 web 端存在混合流的情况
6620
- */
6621
- RCMediaType[RCMediaType["AUDIO_VIDEO"] = 2] = "AUDIO_VIDEO";
6622
- })(exports.RCMediaType || (exports.RCMediaType = {}));
6623
-
6624
6731
  class AbstractStatParser {
6625
6732
  constructor(_rtcPeerConn, _sdpSemantics) {
6626
6733
  this._rtcPeerConn = _rtcPeerConn;
@@ -7078,7 +7185,7 @@
7078
7185
  }
7079
7186
  const { trackId } = inboundInfo;
7080
7187
  // inboundInfo 中取不到 audioLevel 时,需从 type 为 track 中取
7081
- const { audioLevel } = inboundInfo || stats[trackId];
7188
+ const audioLevel = inboundInfo.audioLevel || stats[trackId].audioLevel;
7082
7189
  const resourceId = this.getResourceIdByParseSdp(inboundInfo);
7083
7190
  audioLevelList.push({
7084
7191
  trackId: resourceId,
@@ -7491,6 +7598,7 @@
7491
7598
  */
7492
7599
  static setSdpSemantics(sdpSemantics) {
7493
7600
  const { browser, version, supportsUnifiedPlan } = browserInfo;
7601
+ logger.debug(`sdpSemantics, browser: ${browser}, version: ${version}, supportsUnifiedPlan: ${supportsUnifiedPlan}`);
7494
7602
  // 在明确不支持 unified-plan 的版本中使用 plan-b
7495
7603
  if (!supportsUnifiedPlan) {
7496
7604
  this._sdpSemantics = 'plan-b';
@@ -7767,8 +7875,12 @@
7767
7875
  removeTracks.length && removeTracks.forEach(item => {
7768
7876
  const trackId = item.getTrackId();
7769
7877
  item.__innerSetMediaStreamTrack(undefined);
7878
+ /**
7879
+ * peerConnection ontrack 回调参数 RTCTrackEvent 对象中 streams 为 [] 时,服务端无资源,不会添加 transceiver
7880
+ * 需兼容无 transceiver 的情况
7881
+ */
7770
7882
  const transceiver = this._recvTransceiver[trackId];
7771
- transceiver.direction = 'inactive';
7883
+ transceiver && (transceiver.direction = 'inactive');
7772
7884
  });
7773
7885
  const addCount = { audio: 0, video: 0 };
7774
7886
  addTracks.length && addTracks.forEach(item => {
@@ -7920,6 +8032,14 @@
7920
8032
  }
7921
8033
  }
7922
8034
  _onTrackReady(evt) {
8035
+ /**
8036
+ * signal 和 mediaServer 不同步时,signal 有资源,mediaServer 没资源,
8037
+ * 订阅 mediaServer 不存在的资源时,对应 answer sdp 中的通道没有 ssrc,
8038
+ * ontrack 会被触发,但 RTCTrackEvent 对象中的 streams 为 [],需兼容
8039
+ */
8040
+ if (!evt.streams.length) {
8041
+ return;
8042
+ }
7923
8043
  // 更新 transceiver 与 trackId 的订阅关系
7924
8044
  const msid = evt.streams[0].id;
7925
8045
  const track = evt.receiver.track;
@@ -7936,13 +8056,13 @@
7936
8056
  return __awaiter(this, void 0, void 0, function* () {
7937
8057
  const offer = yield this._sdpStrategy.createOffer(iceRestart);
7938
8058
  // logger.debug(`sdpDemantics -> ${offer.semantics}`)
7939
- // logger.debug(`offer -> ${JSON.stringify(offer.sdp)}`)
8059
+ logger.debug(`offer -> ${JSON.stringify(offer.sdp)}`);
7940
8060
  return offer;
7941
8061
  });
7942
8062
  }
7943
8063
  setRemoteAnswer(answer) {
7944
8064
  return __awaiter(this, void 0, void 0, function* () {
7945
- // logger.debug(`answer -> ${JSON.stringify(answer)}`)
8065
+ logger.debug(`answer -> ${JSON.stringify(answer)}`);
7946
8066
  return this._sdpStrategy.setRemoteAnswer(answer);
7947
8067
  });
7948
8068
  }
@@ -8317,7 +8437,7 @@
8317
8437
  * 加入房间
8318
8438
  */
8319
8439
  sendR1() {
8320
- const rtcVersion = "5.2.2-alpha.1";
8440
+ const rtcVersion = "5.2.4-beem.1";
8321
8441
  const imVersion = this._context.getCoreVersion();
8322
8442
  const platform = 'web';
8323
8443
  const pcName = navigator.platform;
@@ -8339,40 +8459,6 @@
8339
8459
  }
8340
8460
  }
8341
8461
 
8342
- class RCRemoteTrack extends RCTrack {
8343
- constructor(tag, userId, kind, roomId) {
8344
- super(tag, userId, kind, false, roomId);
8345
- this._isSubscribed = false;
8346
- }
8347
- /**
8348
- * 根据房间数据更新状态
8349
- * @param value
8350
- */
8351
- __innerSetRemoteMuted(bool) {
8352
- this._remoteMuted = bool;
8353
- }
8354
- __innerSetSubscribed(bool) {
8355
- this._isSubscribed = bool;
8356
- }
8357
- /**
8358
- * 查看是否已订阅了该远端资源
8359
- * @returns
8360
- */
8361
- isSubscribed() {
8362
- return this._isSubscribed;
8363
- }
8364
- }
8365
- class RCRemoteAudioTrack extends RCRemoteTrack {
8366
- constructor(tag, userId, roomId) {
8367
- super(tag, userId, 'audio', roomId);
8368
- }
8369
- }
8370
- class RCRemoteVideoTrack extends RCRemoteTrack {
8371
- constructor(tag, userId, roomId) {
8372
- super(tag, userId, 'video', roomId);
8373
- }
8374
- }
8375
-
8376
8462
  /**
8377
8463
  * 北极星上报 R2 参数
8378
8464
  */
@@ -8681,15 +8767,18 @@
8681
8767
  logger.warn(`onKickOff -> byServer: ${byServer}`);
8682
8768
  this._ntfClearRoomItem();
8683
8769
  this._leaveHandle(!byServer);
8770
+ // 扩展字段,备注用户为什么被踢出房间
8771
+ let kickExtra;
8684
8772
  let kickType;
8685
8773
  if (byServer) {
8686
8774
  ((content === null || content === void 0 ? void 0 : content.users) || []).forEach(item => {
8687
8775
  if (item.userId === this._context.getCurrentId()) {
8688
8776
  kickType = item.type;
8777
+ kickExtra = item.kickExtra;
8689
8778
  }
8690
8779
  });
8691
8780
  }
8692
- this._callAppListener('onKickOff', byServer, kickType);
8781
+ this._callAppListener('onKickOff', byServer, kickType, kickExtra);
8693
8782
  }
8694
8783
  _rtcpeerClosed() {
8695
8784
  this._ntfClearRoomItem();
@@ -8710,7 +8799,8 @@
8710
8799
  return;
8711
8800
  }
8712
8801
  const { uris, ignore } = content;
8713
- if (ignore) {
8802
+ // 内置 CDN 为自动时,先收到 cdn_uris,无 uris 时,不用再对比资源
8803
+ if (ignore || !uris) {
8714
8804
  return;
8715
8805
  }
8716
8806
  const publishedList = [];
@@ -9303,14 +9393,13 @@
9303
9393
  extend: JSON.stringify({
9304
9394
  resolutionInfo: this._pc.getOutboundVideoInfo()
9305
9395
  }),
9306
- /**
9307
- * 需过滤房间内不存在的资源
9308
- */
9309
9396
  subscribeList: subscribeList.filter((item) => {
9310
- var _a;
9311
9397
  const trackId = item.track.getTrackId();
9312
9398
  const { userId } = parseTrackId(trackId);
9313
- const isInclude = (_a = this._roomResources[userId]) === null || _a === void 0 ? void 0 : _a.filter(item => trackId === `${item.msid}_${item.mediaType}`).length;
9399
+ if (!this._roomResources[userId]) {
9400
+ return false;
9401
+ }
9402
+ const isInclude = this._roomResources[userId].filter(item => trackId === `${item.msid}_${item.mediaType}`).length;
9314
9403
  return isInclude;
9315
9404
  }).map(item => ({
9316
9405
  simulcast: item.subTiny ? RCStreamType.TINY : RCStreamType.NORMAL,
@@ -9611,7 +9700,7 @@
9611
9700
  if (result.code !== exports.RCRTCCode.SUCCESS) {
9612
9701
  return { code: result.code };
9613
9702
  }
9614
- const { sdp: answer, resultCode, message } = result.data;
9703
+ const { sdp: answer, resultCode, message, subscribedList } = result.data;
9615
9704
  if (resultCode !== exports.RCRTCCode.SUCCESS) {
9616
9705
  logger.error(`change subscribe list failed: ${resultCode}`);
9617
9706
  return { code: resultCode };
@@ -9621,14 +9710,18 @@
9621
9710
  if (resCode !== exports.RCRTCCode.SUCCESS) {
9622
9711
  return { code: resCode };
9623
9712
  }
9713
+ // 获取真正订阅成功的资源
9714
+ const subSuccessTrackIds = subscribedList === null || subscribedList === void 0 ? void 0 : subscribedList.map(item => `${item.msid}_${item.mediaType}`);
9715
+ const subSuccessList = attrs.filter(item => subSuccessTrackIds === null || subSuccessTrackIds === void 0 ? void 0 : subSuccessTrackIds.includes(item.track.getTrackId()));
9716
+ const failedList = attrs.filter(item => !(subSuccessTrackIds === null || subSuccessTrackIds === void 0 ? void 0 : subSuccessTrackIds.includes(item.track.getTrackId())));
9624
9717
  // 更新 remoteTrack.isSubscribed
9625
9718
  for (const trackId in this._remoteTracks) {
9626
- const subed = attrs.some(item => item.track.getTrackId() === trackId);
9719
+ const subed = subSuccessList.some(item => item.track.getTrackId() === trackId);
9627
9720
  this._remoteTracks[trackId].__innerSetSubscribed(subed);
9628
9721
  }
9629
9722
  // 更新本地订阅关系
9630
- this._subscribedList.splice(0, this._subscribedList.length, ...attrs);
9631
- return { code: exports.RCRTCCode.SUCCESS };
9723
+ this._subscribedList.splice(0, this._subscribedList.length, ...subSuccessList);
9724
+ return failedList.length ? { code: exports.RCRTCCode.SUCCESS, failedList } : { code: exports.RCRTCCode.SUCCESS };
9632
9725
  });
9633
9726
  }
9634
9727
  /**
@@ -10586,7 +10679,7 @@
10586
10679
  'Content-Type': 'application/json;charset=UTF-8',
10587
10680
  'Cache-Control': 'no-cache',
10588
10681
  ClientType: `web|${browserInfo.browser}|${browserInfo.version}`,
10589
- ClientVersion: "5.2.2-alpha.1",
10682
+ ClientVersion: "5.2.4-beem.1",
10590
10683
  'Client-Session-Id': getUUID(),
10591
10684
  'Request-Id': Date.now().toString()
10592
10685
  });
@@ -11053,14 +11146,28 @@
11053
11146
  this._roomId = _roomId;
11054
11147
  this._joinResData = _joinResData;
11055
11148
  this._livingType = _livingType;
11149
+ /**
11150
+ * 主播列表
11151
+ */
11056
11152
  this._roomAnchorList = [];
11153
+ /**
11154
+ * 合流、分流资源
11155
+ */
11057
11156
  this._roomRes = {};
11157
+ /**
11158
+ * 主播分流资源
11159
+ */
11058
11160
  this._roomAnchorRes = {};
11161
+ /**
11162
+ * 合流、分流 remoteTracks
11163
+ */
11059
11164
  this._remoteTracks = {};
11060
11165
  this._appListener = null;
11061
11166
  this._subscribedList = [];
11062
11167
  this._sessionId = '';
11063
11168
  this._destroyed = false;
11169
+ // 解析服务返回的 KV 数据,并赋值房间内数据
11170
+ this._setInitData();
11064
11171
  this._service = new RCMediaService(this._runtime, this._context, this._initOptions.mediaServer, this._initOptions.timeout);
11065
11172
  // 北极星数据
11066
11173
  this._polarisReport = new PolarisReporter(this._context, this._runtime, this._roomId, this, PolarisRole.Audience);
@@ -11082,6 +11189,54 @@
11082
11189
  // 房间主播加入|离开房间、发布|取消发布资源变更监听
11083
11190
  this._context.onrtcdatachange = this.singalDataChange.bind(this);
11084
11191
  }
11192
+ /**
11193
+ * 解析服务端返回的 KV 数据,赋值 room 内数据
11194
+ */
11195
+ _setInitData() {
11196
+ const { sessionId, remoteUserIds, remoteRTCUris, remoteMUCUris, remoteTracks, CDNUris } = parseAudienceRoomData(this._roomId, this._joinResData.kvEntries);
11197
+ /**
11198
+ * session 赋值
11199
+ */
11200
+ this._sessionId = sessionId;
11201
+ /**
11202
+ * 主播列表赋值
11203
+ */
11204
+ this._roomAnchorList = remoteUserIds;
11205
+ /**
11206
+ * RTC、MCU tracks 赋值
11207
+ */
11208
+ remoteTracks.forEach((track) => {
11209
+ this._remoteTracks[track.getTrackId()] = track;
11210
+ });
11211
+ /**
11212
+ * _CDNUris 赋值
11213
+ */
11214
+ this._CDNUris = CDNUris;
11215
+ /**
11216
+ * 房间内 RTC 资源赋值
11217
+ */
11218
+ remoteRTCUris.forEach((uri) => {
11219
+ const userId = uri.msid.split('_')[0];
11220
+ if (this._roomAnchorRes[userId]) {
11221
+ this._roomAnchorRes[userId].push(uri);
11222
+ }
11223
+ else {
11224
+ this._roomAnchorRes[userId] = [uri];
11225
+ }
11226
+ });
11227
+ /**
11228
+ * 房间内 RTC、MCU 资源赋值
11229
+ */
11230
+ remoteMUCUris.forEach((uri) => {
11231
+ const { mediaType, tag } = uri;
11232
+ const trackId = [this._roomId, tag, mediaType].join('_');
11233
+ this._roomRes[trackId] = uri;
11234
+ });
11235
+ remoteRTCUris.forEach((uri) => {
11236
+ const trackId = getTrackId(uri);
11237
+ this._roomRes[trackId] = uri;
11238
+ });
11239
+ }
11085
11240
  _assertRoomDestroyed() {
11086
11241
  if (this._destroyed) {
11087
11242
  const msg = 'This room has been destroyed. Please use `RCRTCClient.joinLivingRoomAsAudience` to catch another instance.';
@@ -11131,9 +11286,6 @@
11131
11286
  this._handleLeftedAnchor(leftUserIds);
11132
11287
  }
11133
11288
  }
11134
- if (key === 'RC_RTC_SESSIONID') {
11135
- this._sessionId = value;
11136
- }
11137
11289
  });
11138
11290
  // 处理直播间 MCU 合流资源资源
11139
11291
  this._diffRoomResource(allMcuUris);
@@ -11539,7 +11691,7 @@
11539
11691
  if (result.code !== exports.RCRTCCode.SUCCESS) {
11540
11692
  return { code: result.code };
11541
11693
  }
11542
- const { sdp: answer, resultCode, message } = result.data;
11694
+ const { sdp: answer, resultCode, message, subscribedList } = result.data;
11543
11695
  if (resultCode !== exports.RCRTCCode.SUCCESS) {
11544
11696
  logger.error('change subscribe list failed:', message, resultCode);
11545
11697
  return { code: resultCode };
@@ -11558,16 +11710,28 @@
11558
11710
  if (resCode !== exports.RCRTCCode.SUCCESS) {
11559
11711
  return { code: resCode };
11560
11712
  }
11713
+ // 获取真正订阅成功的资源
11714
+ const subSuccessTrackIds = subscribedList === null || subscribedList === void 0 ? void 0 : subscribedList.map(item => `${item.msid}_${item.mediaType}`);
11715
+ const subSuccessList = attrs.filter(item => {
11716
+ if (item.track.isMCUTrack()) {
11717
+ const serverTrackInfo = this._roomRes[item.track.getTrackId()];
11718
+ const sdpResourceId = `${serverTrackInfo.msid}_${serverTrackInfo.mediaType}`;
11719
+ return subSuccessTrackIds.includes(sdpResourceId);
11720
+ }
11721
+ return subSuccessTrackIds === null || subSuccessTrackIds === void 0 ? void 0 : subSuccessTrackIds.includes(item.track.getTrackId());
11722
+ });
11723
+ const afterReplaceTrackIds = subSuccessList === null || subSuccessList === void 0 ? void 0 : subSuccessList.map(item => `${item.track.getTrackId()}`);
11724
+ const failedList = attrs.filter(item => !(afterReplaceTrackIds === null || afterReplaceTrackIds === void 0 ? void 0 : afterReplaceTrackIds.includes(item.track.getTrackId())));
11561
11725
  // 更新 remoteTrack.isSubscribed
11562
11726
  for (const trackId in this._remoteTracks) {
11563
- const subed = attrs.some(item => {
11727
+ const subed = subSuccessList.some(item => {
11564
11728
  return item.track.getTrackId() === trackId;
11565
11729
  });
11566
11730
  this._remoteTracks[trackId].__innerSetSubscribed(subed);
11567
11731
  }
11568
11732
  // 更新本地订阅关系
11569
- this._subscribedList.splice(0, this._subscribedList.length, ...attrs);
11570
- return { code: exports.RCRTCCode.SUCCESS };
11733
+ this._subscribedList.splice(0, this._subscribedList.length, ...subSuccessList);
11734
+ return failedList.length ? { code: exports.RCRTCCode.SUCCESS, failedList } : { code: exports.RCRTCCode.SUCCESS };
11571
11735
  });
11572
11736
  }
11573
11737
  /**
@@ -11575,12 +11739,11 @@
11575
11739
  * @param newCDNUris 新的 cdn_uris 数据
11576
11740
  */
11577
11741
  _diffCDNUris(newCDNUris) {
11578
- var _a, _b, _c, _d, _e, _f, _g, _h;
11579
11742
  return __awaiter(this, void 0, void 0, function* () {
11580
11743
  /**
11581
11744
  * CDN 资源减少: 上次 CDNUris 中有 url,变更后无 url
11582
11745
  */
11583
- if (((_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.url) && !newCDNUris.url) {
11746
+ if (this._CDNUris.url && !newCDNUris.url) {
11584
11747
  this._callAppListener('onCDNInfoDisable');
11585
11748
  /**
11586
11749
  * 更新内存中存储的 cdn_uris 数据
@@ -11593,22 +11756,22 @@
11593
11756
  * 内存中无 CDNUris 或
11594
11757
  * 上次 CDNUris 无 url,变更后有 url
11595
11758
  */
11596
- if (!this._CDNUris || (!((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.url) && newCDNUris.url)) {
11759
+ if (!this._CDNUris || (!this._CDNUris.url && newCDNUris.url)) {
11597
11760
  this._callAppListener('onCDNInfoEnable', {
11598
11761
  resolution: `W${newCDNUris.w}_H${newCDNUris.h}`,
11599
- fps: newCDNUris.fps
11762
+ fps: `FPS_${newCDNUris.fps}`
11600
11763
  });
11601
11764
  }
11602
11765
  /**
11603
11766
  * CDN 资源变更: w、h、fps 其中一项变化
11604
11767
  */
11605
- const isWChange = (((_c = this._CDNUris) === null || _c === void 0 ? void 0 : _c.w) && newCDNUris.w && (((_d = this._CDNUris) === null || _d === void 0 ? void 0 : _d.w) !== newCDNUris.w));
11606
- const isHChange = (((_e = this._CDNUris) === null || _e === void 0 ? void 0 : _e.h) && newCDNUris.h && (((_f = this._CDNUris) === null || _f === void 0 ? void 0 : _f.h) !== newCDNUris.h));
11607
- const isFpsChange = (((_g = this._CDNUris) === null || _g === void 0 ? void 0 : _g.fps) && newCDNUris.fps && (((_h = this._CDNUris) === null || _h === void 0 ? void 0 : _h.fps) !== newCDNUris.fps));
11768
+ const isWChange = (this._CDNUris.w && newCDNUris.w && (this._CDNUris.w !== newCDNUris.w));
11769
+ const isHChange = (this._CDNUris.h && newCDNUris.h && (this._CDNUris.h !== newCDNUris.h));
11770
+ const isFpsChange = (this._CDNUris.fps && newCDNUris.fps && (this._CDNUris.fps !== newCDNUris.fps));
11608
11771
  if (isWChange || isHChange || isFpsChange) {
11609
11772
  this._callAppListener('onCDNInfoChange', {
11610
11773
  resolution: `W${newCDNUris.w}_H${newCDNUris.h}`,
11611
- fps: newCDNUris.fps
11774
+ fps: `FPS_${newCDNUris.fps}`
11612
11775
  });
11613
11776
  }
11614
11777
  /**
@@ -11619,21 +11782,16 @@
11619
11782
  }
11620
11783
  /**
11621
11784
  * 获取 CDN 资源对应的拉流地址
11622
- * 首次获取 CDNPlayUrl 时,需传入 url,
11623
- * 业务层调用时使用内存中 _CDNUris 的 url,无 _CDNUris 时说明观众端未赋值过 _CDNUris
11785
+ * _CDNUris url 时,说明未开启 CDN 推送
11624
11786
  * @returns CDNPlayUrl
11625
11787
  */
11626
- _getCDNPlayUrl(params, url) {
11627
- var _a, _b;
11788
+ _getCDNPlayUrl(params) {
11628
11789
  return __awaiter(this, void 0, void 0, function* () {
11629
11790
  const { w, h, fps } = params;
11630
11791
  const kind = this._initOptions.pullInnerCDNProtocol || exports.RCInnerCDNPullKind.FLV;
11631
11792
  const useHttps = (this._initOptions.pullInnerCDNUseHttps === exports.RCInnerCDNPullIsHttps.NOT_HTTPS) ? exports.RCInnerCDNPullIsHttps.NOT_HTTPS : exports.RCInnerCDNPullIsHttps.HTTPS;
11632
- /**
11633
- * 加入房间后拉 KV 数据,数据还未返回时,同步拉 KV 获取 CDN 信息
11634
- */
11635
- if (!((_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.url) && !url) {
11636
- logger.error(`cdn_uris url is empty, the anchor need to start CDN, code: ${exports.RCRTCCode.CDN_RESOURCE_IS_EMPTY}`);
11793
+ if (!this._CDNUris.url) {
11794
+ logger.error(`cdn_uris url is empty, the anchor need to open or push CDN, code: ${exports.RCRTCCode.CDN_RESOURCE_IS_EMPTY}`);
11637
11795
  return { code: exports.RCRTCCode.CDN_RESOURCE_IS_EMPTY };
11638
11796
  }
11639
11797
  const headers = {
@@ -11650,7 +11808,7 @@
11650
11808
  paramsArr.push(`kind=${kind}`);
11651
11809
  paramsArr.push(`is_https=${useHttps}`);
11652
11810
  const paramsStr = paramsArr.join('&');
11653
- let requestUrl = `${url || ((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.url)}?`;
11811
+ let requestUrl = `${this._CDNUris.url}?`;
11654
11812
  paramsStr && (requestUrl += paramsStr);
11655
11813
  const { code, res } = yield this._service.getCDNResourceInfo(headers, requestUrl);
11656
11814
  if (code !== exports.RCRTCCode.SUCCESS) {
@@ -11787,12 +11945,7 @@
11787
11945
  * @param tag 参数描述
11788
11946
  */
11789
11947
  registerRoomEventListener(listener) {
11790
- var _a;
11791
11948
  this._appListener = listener;
11792
- if (!listener) {
11793
- return;
11794
- }
11795
- ((_a = this._joinResData.kvEntries) === null || _a === void 0 ? void 0 : _a.length) && this.singalDataChange(this._joinResData.kvEntries, this._roomId);
11796
11949
  }
11797
11950
  /**
11798
11951
  * 音量上报
@@ -11873,6 +12026,44 @@
11873
12026
  });
11874
12027
  return [...mcuTracks, ...tracks];
11875
12028
  }
12029
+ /**
12030
+ * 获取远端 RTC tracks
12031
+ */
12032
+ getRemoteRTCTracks() {
12033
+ const tracks = [];
12034
+ for (const trackId in this._remoteTracks) {
12035
+ const track = this._remoteTracks[trackId];
12036
+ if (!track.isMCUTrack()) {
12037
+ tracks.push(track);
12038
+ }
12039
+ }
12040
+ return tracks;
12041
+ }
12042
+ /**
12043
+ * 获取远端 MCU tracks
12044
+ */
12045
+ getRemoteMCUTracks() {
12046
+ const tracks = [];
12047
+ for (const trackId in this._remoteTracks) {
12048
+ const track = this._remoteTracks[trackId];
12049
+ if (track.isMCUTrack()) {
12050
+ tracks.push(track);
12051
+ }
12052
+ }
12053
+ return tracks;
12054
+ }
12055
+ /**
12056
+ * 获取房间内 CDN 信息
12057
+ */
12058
+ getCDNInfo() {
12059
+ return this._CDNUris.w ? {
12060
+ resolution: `W${this._CDNUris.w}_H${this._CDNUris.h}`,
12061
+ fps: `FPS_${this._CDNUris.fps}`,
12062
+ CDNEnable: this._CDNUris.enableInnerCDN
12063
+ } : {
12064
+ CDNEnable: false
12065
+ };
12066
+ }
11876
12067
  }
11877
12068
 
11878
12069
  const getTracksWithOptions = (stream, options) => {
@@ -11924,11 +12115,15 @@
11924
12115
  /**
11925
12116
  * 加入普通音视频房间
11926
12117
  * @param roomId
12118
+ * @param joinType 多端处理方式
12119
+ * @param outerUserDatas 业务层设置人员属性
12120
+ * @param useMutilPeerC
12121
+ * @param roomType 加入房间的类型 默认参数 RTCMode.RTC
11927
12122
  */
11928
- joinRTCRoom(roomId, joinType) {
11929
- return push(() => this._joinRTCRoom(roomId, joinType));
12123
+ joinRTCRoom(roomId, joinType, outerUserDatas, useMutilPeerC, roomType = engine.RTCMode.RTC) {
12124
+ return push(() => this._joinRTCRoom(roomId, joinType, outerUserDatas, useMutilPeerC, roomType));
11930
12125
  }
11931
- _joinRTCRoom(roomId, joinType) {
12126
+ _joinRTCRoom(roomId, joinType, outerUserDatas, useMutilPeerC, roomType = engine.RTCMode.RTC) {
11932
12127
  return __awaiter(this, void 0, void 0, function* () {
11933
12128
  if (isIllegalConnection(this._context.getNaviInfo())) {
11934
12129
  return { code: exports.RCRTCCode.PACKAGE_ENVIRONMENT_ERROR };
@@ -11936,6 +12131,9 @@
11936
12131
  if (!engine.validate('roomId', roomId, engine.notEmptyString, true)) {
11937
12132
  return { code: exports.RCRTCCode.PARAMS_ERROR };
11938
12133
  }
12134
+ if (!engine.validate('roomType', roomType, (value) => engine.RTCMode[value] !== undefined)) {
12135
+ return { code: exports.RCRTCCode.PARAMS_ERROR };
12136
+ }
11939
12137
  if (this._crtRoom) {
11940
12138
  return { code: exports.RCRTCCode.REPERT_JOIN_ROOM };
11941
12139
  }
@@ -11946,8 +12144,8 @@
11946
12144
  if (!urls.length) {
11947
12145
  return { code: exports.RCRTCCode.NOT_OPEN_VIDEO_AUDIO_SERVER };
11948
12146
  }
11949
- logger.debug(`joinRoom -> roomId: ${roomId}; joinType: ${joinType || engine.RTCJoinType.KICK}`);
11950
- const { code, data } = yield this._context.joinRTCRoom(roomId, engine.RTCMode.RTC, undefined, joinType);
12147
+ logger.debug(`joinRoom -> roomId: ${roomId}; joinType: ${joinType || engine.RTCJoinType.KICK} roomType: ${roomType}`);
12148
+ const { code, data } = yield this._context.joinRTCRoom(roomId, roomType, undefined, joinType);
11951
12149
  if (code !== engine.ErrorCode.SUCCESS) {
11952
12150
  logger.error(`joinRoom failed -> code: ${code}`);
11953
12151
  const errorCode = code === RTCSignalCode.JOIN_REFUSED ? exports.RCRTCCode.SIGNAL_JOIN_RTC_ROOM_REFUSED : code;
@@ -12378,7 +12576,14 @@
12378
12576
  logger.info(`joinLivingRoomAsAudience success, room data: ${JSON.stringify(data)}`);
12379
12577
  const room = new RCAudienceLivingRoom(this._context, this._runtime, this._options, roomId, data, livingType);
12380
12578
  this._crtAudienceLivingRoom = room;
12381
- return { room, code: exports.RCRTCCode.SUCCESS };
12579
+ return {
12580
+ room,
12581
+ code: exports.RCRTCCode.SUCCESS,
12582
+ userIds: room.getRemoteUserIds(),
12583
+ RTCTracks: room.getRemoteRTCTracks(),
12584
+ MCUTracks: room.getRemoteMCUTracks(),
12585
+ CDNUris: room.getCDNInfo()
12586
+ };
12382
12587
  });
12383
12588
  }
12384
12589
  /**
@@ -12449,7 +12654,14 @@
12449
12654
  this._crtRoom.__destroy(false);
12450
12655
  // 重置主播房间
12451
12656
  this._crtRoom = null;
12452
- return { room: crtRoom, code: exports.RCRTCCode.SUCCESS };
12657
+ return {
12658
+ room: crtRoom,
12659
+ code: exports.RCRTCCode.SUCCESS,
12660
+ userIds: crtRoom.getRemoteUserIds(),
12661
+ RTCTracks: crtRoom.getRemoteRTCTracks(),
12662
+ MCUTracks: crtRoom.getRemoteMCUTracks(),
12663
+ CDNUris: crtRoom.getCDNInfo()
12664
+ };
12453
12665
  });
12454
12666
  }
12455
12667
  /**
@@ -12495,9 +12707,9 @@
12495
12707
  logger.error('Please use the https protocol or use `http://localhost` to open the page!');
12496
12708
  return false;
12497
12709
  }
12498
- engine.VersionManage.add('plugin-rtc', "5.2.2-alpha.1");
12499
- if (!engine.VersionManage.validEngine("~4.5.1")) {
12500
- logger.error(`The current engine version '${engine.VersionManage.getInfo().engine}' error, plugin-rtc required engine version at least '${"~4.5.1"}'.`);
12710
+ engine.VersionManage.add('plugin-rtc', "5.2.4-beem.1");
12711
+ if (!engine.VersionManage.validEngine("4.6.0-beem.5")) {
12712
+ logger.error(`The current engine version '${engine.VersionManage.getInfo().engine}' error, plugin-rtc required engine version at least '${"4.6.0-beem.5"}'.`);
12501
12713
  return false;
12502
12714
  }
12503
12715
  return true;
@@ -12505,7 +12717,7 @@
12505
12717
  setup(context, runtime, options = {}) {
12506
12718
  logger.setLogLevel(options.logLevel);
12507
12719
  logger.setLogStdout(options.logStdout);
12508
- logger.warn(`RCRTC Version: ${"5.2.2-alpha.1"}, Commit: ${"de4f9bc28bbee35d2d5f206a68144c89c098573f"}`);
12720
+ logger.warn(`RCRTC Version: ${"5.2.4-beem.1"}, Commit: ${"d026964c6715be7805a3e5c8addd64d4008d17bd"}`);
12509
12721
  logger.warn(`browserInfo.browser -> ${browserInfo.browser}`);
12510
12722
  logger.warn(`browserInfo.supportsUnifiedPlan -> ${browserInfo.supportsUnifiedPlan}`);
12511
12723
  logger.warn(`browserInfo.version -> ${browserInfo.version}`);