@rongcloud/plugin-rtc 5.1.10-alpha.3 → 5.2.2-alpha.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.d.ts +367 -95
- package/dist/index.esm.js +585 -127
- package/dist/index.js +583 -125
- package/dist/index.umd.js +583 -125
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* RCRTC - v5.
|
|
3
|
-
* CommitId -
|
|
4
|
-
*
|
|
2
|
+
* RCRTC - v5.2.2-alpha.1
|
|
3
|
+
* CommitId - de4f9bc28bbee35d2d5f206a68144c89c098573f
|
|
4
|
+
* Mon Nov 22 2021 10:51:42 GMT+0800 (China Standard Time)
|
|
5
5
|
* ©2020 RongCloud, Inc. All rights reserved.
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
@@ -110,8 +110,12 @@ exports.RCRTCCode = void 0;
|
|
|
110
110
|
RCRTCCode[RCRTCCode["PACKAGE_ENVIRONMENT_ERROR"] = 53025] = "PACKAGE_ENVIRONMENT_ERROR";
|
|
111
111
|
/** 单个用户发布资源超过限制 ( MediaServer 限制最多 10 个 track ) */
|
|
112
112
|
RCRTCCode[RCRTCCode["PUBLISH_TRACK_LIMIT_EXCEEDED"] = 53026] = "PUBLISH_TRACK_LIMIT_EXCEEDED";
|
|
113
|
+
/** 房间内无主播推 CDN */
|
|
114
|
+
RCRTCCode[RCRTCCode["CDN_RESOURCE_IS_EMPTY"] = 53027] = "CDN_RESOURCE_IS_EMPTY";
|
|
113
115
|
/** 加入 RTC 房间 joinTYype 为 1 时,当前有其他端在房间时的应答码 */
|
|
114
|
-
RCRTCCode[RCRTCCode["SIGNAL_JOIN_RTC_ROOM_REFUSED"] =
|
|
116
|
+
RCRTCCode[RCRTCCode["SIGNAL_JOIN_RTC_ROOM_REFUSED"] = 53028] = "SIGNAL_JOIN_RTC_ROOM_REFUSED";
|
|
117
|
+
/** 设置音频输出设备时,无权限使用请求的设备 */
|
|
118
|
+
RCRTCCode[RCRTCCode["NO_PERMISSION_TO_USE_REQUESTED_DEVICE"] = 53029] = "NO_PERMISSION_TO_USE_REQUESTED_DEVICE";
|
|
115
119
|
})(exports.RCRTCCode || (exports.RCRTCCode = {}));
|
|
116
120
|
/**
|
|
117
121
|
* RTC 信令 Server 返回需处理的错误 Code
|
|
@@ -5656,6 +5660,33 @@ const getBitrateMultiple = (frameRate) => {
|
|
|
5656
5660
|
return rate;
|
|
5657
5661
|
};
|
|
5658
5662
|
|
|
5663
|
+
/**
|
|
5664
|
+
* 获取 Microphone 列表
|
|
5665
|
+
*/
|
|
5666
|
+
const getMicrophones = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5667
|
+
const mediaDivices = yield navigator.mediaDevices.enumerateDevices();
|
|
5668
|
+
return mediaDivices.filter(item => item.kind === 'audioinput');
|
|
5669
|
+
});
|
|
5670
|
+
/**
|
|
5671
|
+
* 获取摄像头设备列表
|
|
5672
|
+
*/
|
|
5673
|
+
const getCameras = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5674
|
+
const mediaDevices = yield navigator.mediaDevices.enumerateDevices();
|
|
5675
|
+
return mediaDevices.filter(item => item.kind === 'videoinput');
|
|
5676
|
+
});
|
|
5677
|
+
/**
|
|
5678
|
+
* 获取扬声器设备列表
|
|
5679
|
+
*/
|
|
5680
|
+
const getSpeakers = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5681
|
+
const mediaDevices = yield navigator.mediaDevices.enumerateDevices();
|
|
5682
|
+
return mediaDevices.filter(item => item.kind === 'audiooutput');
|
|
5683
|
+
});
|
|
5684
|
+
const device = {
|
|
5685
|
+
getCameras,
|
|
5686
|
+
getMicrophones,
|
|
5687
|
+
getSpeakers
|
|
5688
|
+
};
|
|
5689
|
+
|
|
5659
5690
|
class RCTrack extends engine.EventEmitter {
|
|
5660
5691
|
constructor(_tag, _userId, _kind, _isLocalTrack, _roomId) {
|
|
5661
5692
|
super();
|
|
@@ -5793,6 +5824,17 @@ class RCTrack extends engine.EventEmitter {
|
|
|
5793
5824
|
logger.warn('the valid range of options.volume is 0-100, the value of volume has been set 100');
|
|
5794
5825
|
}
|
|
5795
5826
|
}
|
|
5827
|
+
if (options === null || options === void 0 ? void 0 : options.audioDeviceId) {
|
|
5828
|
+
/**
|
|
5829
|
+
* 检测传入的 audioDeviceId 是否有效
|
|
5830
|
+
*/
|
|
5831
|
+
const deviceIds = (yield device.getSpeakers()).map((item) => { return item.deviceId; });
|
|
5832
|
+
const isValid = deviceIds.includes(options.audioDeviceId);
|
|
5833
|
+
if (!isValid) {
|
|
5834
|
+
logger.error(`the options.audioDeviceId is invalid --> ${options.audioDeviceId}`);
|
|
5835
|
+
return { code: exports.RCRTCCode.PARAMS_ERROR };
|
|
5836
|
+
}
|
|
5837
|
+
}
|
|
5796
5838
|
const isVideoTrack = this.isVideoTrack();
|
|
5797
5839
|
// video 播放必须传递一个 HTMLVideoElement 实例作为 video track 的播放组件
|
|
5798
5840
|
if (isVideoTrack && (!element || !(element instanceof HTMLVideoElement))) {
|
|
@@ -5856,9 +5898,21 @@ class RCTrack extends engine.EventEmitter {
|
|
|
5856
5898
|
this._element.volume = (options === null || options === void 0 ? void 0 : options.volume) / 100;
|
|
5857
5899
|
}
|
|
5858
5900
|
try {
|
|
5859
|
-
|
|
5901
|
+
if ((options === null || options === void 0 ? void 0 : options.audioDeviceId) && !isVideoTrack) {
|
|
5902
|
+
yield this._element.setSinkId(options.audioDeviceId);
|
|
5903
|
+
}
|
|
5904
|
+
else {
|
|
5905
|
+
this._element.play();
|
|
5906
|
+
}
|
|
5860
5907
|
}
|
|
5861
5908
|
catch (error) {
|
|
5909
|
+
/**
|
|
5910
|
+
* 检测是否有设置音频输出设备的权限
|
|
5911
|
+
*/
|
|
5912
|
+
if (error.message === 'No permission to use requested device') {
|
|
5913
|
+
logger.error(`setSinkId failed -> ${error.message}`);
|
|
5914
|
+
return { code: exports.RCRTCCode.NO_PERMISSION_TO_USE_REQUESTED_DEVICE };
|
|
5915
|
+
}
|
|
5862
5916
|
logger.error(error);
|
|
5863
5917
|
return { code: exports.RCRTCCode.TRACK_PLAY_ERROR };
|
|
5864
5918
|
}
|
|
@@ -6320,6 +6374,27 @@ const calcTracksNum = (tracks) => {
|
|
|
6320
6374
|
});
|
|
6321
6375
|
return length;
|
|
6322
6376
|
};
|
|
6377
|
+
/**
|
|
6378
|
+
* 解析房间数据
|
|
6379
|
+
*/
|
|
6380
|
+
const parseRoomData = (data) => {
|
|
6381
|
+
const result = {};
|
|
6382
|
+
const userIds = Object.keys(data.users);
|
|
6383
|
+
userIds.length && userIds.forEach(userId => {
|
|
6384
|
+
const tmp = [];
|
|
6385
|
+
const userData = data.users[userId];
|
|
6386
|
+
if (userData.uris) {
|
|
6387
|
+
try {
|
|
6388
|
+
tmp.push(...JSON.parse(userData.uris));
|
|
6389
|
+
}
|
|
6390
|
+
catch (error) {
|
|
6391
|
+
logger.warn(`invalid user data -> userId: ${userId}, userData: ${userData}`);
|
|
6392
|
+
}
|
|
6393
|
+
}
|
|
6394
|
+
result[userId] = tmp;
|
|
6395
|
+
});
|
|
6396
|
+
return result;
|
|
6397
|
+
};
|
|
6323
6398
|
|
|
6324
6399
|
/**
|
|
6325
6400
|
* RTC 消息类型常量
|
|
@@ -8242,7 +8317,7 @@ class PolarisReporter {
|
|
|
8242
8317
|
* 加入房间
|
|
8243
8318
|
*/
|
|
8244
8319
|
sendR1() {
|
|
8245
|
-
const rtcVersion = "5.
|
|
8320
|
+
const rtcVersion = "5.2.2-alpha.1";
|
|
8246
8321
|
const imVersion = this._context.getCoreVersion();
|
|
8247
8322
|
const platform = 'web';
|
|
8248
8323
|
const pcName = navigator.platform;
|
|
@@ -8378,24 +8453,21 @@ class RCAudioLevelReport {
|
|
|
8378
8453
|
}
|
|
8379
8454
|
}
|
|
8380
8455
|
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
});
|
|
8397
|
-
return result;
|
|
8398
|
-
};
|
|
8456
|
+
/**
|
|
8457
|
+
* 直播角色
|
|
8458
|
+
*/
|
|
8459
|
+
exports.RCRTCLiveRole = void 0;
|
|
8460
|
+
(function (RCRTCLiveRole) {
|
|
8461
|
+
/**
|
|
8462
|
+
* 主播
|
|
8463
|
+
*/
|
|
8464
|
+
RCRTCLiveRole[RCRTCLiveRole["ANCHOR"] = 1] = "ANCHOR";
|
|
8465
|
+
/**
|
|
8466
|
+
* 观众
|
|
8467
|
+
*/
|
|
8468
|
+
RCRTCLiveRole[RCRTCLiveRole["AUDIENCE"] = 2] = "AUDIENCE";
|
|
8469
|
+
})(exports.RCRTCLiveRole || (exports.RCRTCLiveRole = {}));
|
|
8470
|
+
|
|
8399
8471
|
const getTrackIdFromAttr = (track) => {
|
|
8400
8472
|
if (track instanceof RCTrack) {
|
|
8401
8473
|
return track.getTrackId();
|
|
@@ -8453,7 +8525,7 @@ class RCAbstractRoom {
|
|
|
8453
8525
|
/**
|
|
8454
8526
|
* 观众升级为主播后不会收到全量 uri 消息,需直接触发人员、资源变更
|
|
8455
8527
|
*/
|
|
8456
|
-
isUpgrade && this._afterChangedRole(
|
|
8528
|
+
isUpgrade && this._afterChangedRole(data);
|
|
8457
8529
|
// 开始心跳,心跳失败时主动退出房间
|
|
8458
8530
|
this._pinger = new Pinger(_roomId, this._roomMode, _context, this._initOptions.pingGap);
|
|
8459
8531
|
this._pinger.onFailed = this._kickoff.bind(this);
|
|
@@ -8743,30 +8815,49 @@ class RCAbstractRoom {
|
|
|
8743
8815
|
* @param content
|
|
8744
8816
|
*/
|
|
8745
8817
|
_stateHandle(content) {
|
|
8818
|
+
var _a;
|
|
8746
8819
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8747
8820
|
const { users } = content;
|
|
8748
8821
|
if (users.length === 0) {
|
|
8749
8822
|
return;
|
|
8750
8823
|
}
|
|
8824
|
+
/**
|
|
8825
|
+
* 主动加入房间
|
|
8826
|
+
*/
|
|
8751
8827
|
const joined = [];
|
|
8828
|
+
/**
|
|
8829
|
+
* 主动退出房间
|
|
8830
|
+
*/
|
|
8752
8831
|
const left = [];
|
|
8832
|
+
/**
|
|
8833
|
+
* 观众升级为主播加入房间
|
|
8834
|
+
*/
|
|
8835
|
+
const upgrade = [];
|
|
8836
|
+
/**
|
|
8837
|
+
* 主播降级为观众退出房间
|
|
8838
|
+
*/
|
|
8839
|
+
const downgrade = [];
|
|
8753
8840
|
users.forEach(item => {
|
|
8754
8841
|
if (+item.state === 0) {
|
|
8755
8842
|
logger.debug(`user joined -> ${item.userId}`);
|
|
8756
8843
|
// 对端 im 重连之后调加入房间信令获取最新数据,服务会给本端下发“对端加入房间”的消息,本端内存已包含对端人员,所以需过滤掉
|
|
8757
|
-
!this._roomResources[item.userId]
|
|
8844
|
+
if (!this._roomResources[item.userId]) {
|
|
8845
|
+
item.switchRoleType ? upgrade.push(item.userId) : joined.push(item.userId);
|
|
8846
|
+
}
|
|
8758
8847
|
this._roomResources[item.userId] = this._roomResources[item.userId] || [];
|
|
8759
8848
|
}
|
|
8760
8849
|
else {
|
|
8761
8850
|
logger.debug(`user left -> ${item.userId}`);
|
|
8762
|
-
left.push(item.userId);
|
|
8851
|
+
item.switchRoleType ? downgrade.push(item.userId) : left.push(item.userId);
|
|
8763
8852
|
}
|
|
8764
8853
|
});
|
|
8854
|
+
const allJoined = [...joined, ...upgrade];
|
|
8855
|
+
const allLeft = [...left, ...downgrade];
|
|
8765
8856
|
// 用户离开房间时,自动退订对方资源
|
|
8766
|
-
if (
|
|
8857
|
+
if (allLeft.length) {
|
|
8767
8858
|
const tracks = [];
|
|
8768
8859
|
const userIds = [];
|
|
8769
|
-
|
|
8860
|
+
allLeft.forEach(userId => {
|
|
8770
8861
|
tracks.push(...this.getRemoteTracksByUserId(userId));
|
|
8771
8862
|
// 先暂存待删用户,因当前异步队列中可能存在等待中的待处理任务,需要当前房间数据状态
|
|
8772
8863
|
// delete this._roomResources[userId]
|
|
@@ -8781,9 +8872,23 @@ class RCAbstractRoom {
|
|
|
8781
8872
|
userIds.forEach(userId => delete this._roomResources[userId]);
|
|
8782
8873
|
}
|
|
8783
8874
|
}
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8875
|
+
/**
|
|
8876
|
+
* 通知业务层
|
|
8877
|
+
* 有 onSwitchRole 监听时,按 switchRole 分“角色切换、加入房间、退出房间”抛出
|
|
8878
|
+
*/
|
|
8879
|
+
if ((_a = this._appListener) === null || _a === void 0 ? void 0 : _a.onSwitchRole) {
|
|
8880
|
+
upgrade.length && upgrade.forEach(userId => this._callAppListener('onSwitchRole', userId, exports.RCRTCLiveRole.ANCHOR));
|
|
8881
|
+
downgrade.length && downgrade.forEach(userId => this._callAppListener('onSwitchRole', userId, exports.RCRTCLiveRole.AUDIENCE));
|
|
8882
|
+
joined.length && this._callAppListener('onUserJoin', joined);
|
|
8883
|
+
left.length && this._callAppListener('onUserLeave', left);
|
|
8884
|
+
return;
|
|
8885
|
+
}
|
|
8886
|
+
/**
|
|
8887
|
+
* 通知业务层
|
|
8888
|
+
* 无 onSwitchRole 监听时,统一按“加入房间、退出房间”抛出
|
|
8889
|
+
*/
|
|
8890
|
+
allJoined.length && this._callAppListener('onUserJoin', allJoined);
|
|
8891
|
+
allLeft.length && this._callAppListener('onUserLeave', allLeft);
|
|
8787
8892
|
});
|
|
8788
8893
|
}
|
|
8789
8894
|
/**
|
|
@@ -9204,7 +9309,7 @@ class RCAbstractRoom {
|
|
|
9204
9309
|
subscribeList: subscribeList.filter((item) => {
|
|
9205
9310
|
var _a;
|
|
9206
9311
|
const trackId = item.track.getTrackId();
|
|
9207
|
-
const { userId } =
|
|
9312
|
+
const { userId } = parseTrackId(trackId);
|
|
9208
9313
|
const isInclude = (_a = this._roomResources[userId]) === null || _a === void 0 ? void 0 : _a.filter(item => trackId === `${item.msid}_${item.mediaType}`).length;
|
|
9209
9314
|
return isInclude;
|
|
9210
9315
|
}).map(item => ({
|
|
@@ -9652,6 +9757,7 @@ class RCAbstractRoom {
|
|
|
9652
9757
|
rTrack.isAudioTrack() ? this._onAudioMuteChange(rTrack) : this._onVideoMuteChange(rTrack);
|
|
9653
9758
|
});
|
|
9654
9759
|
});
|
|
9760
|
+
return { data };
|
|
9655
9761
|
});
|
|
9656
9762
|
}
|
|
9657
9763
|
_onAudioMuteChange(audioTrack) {
|
|
@@ -9663,35 +9769,7 @@ class RCAbstractRoom {
|
|
|
9663
9769
|
/**
|
|
9664
9770
|
* 观众切换为主播后直接处理人员变更及资源变更
|
|
9665
9771
|
*/
|
|
9666
|
-
_afterChangedRole(data) {
|
|
9667
|
-
const currentUserId = this._context.getCurrentId();
|
|
9668
|
-
const joinedAnchorList = Object.keys(data);
|
|
9669
|
-
// 观众升级主播成功后返回房间实例,才可注册房间事件,需异步抛出
|
|
9670
|
-
setTimeout(() => {
|
|
9671
|
-
// 通知业务层人员变更
|
|
9672
|
-
const needNoticeUserIds = joinedAnchorList.filter(id => {
|
|
9673
|
-
return id !== currentUserId;
|
|
9674
|
-
});
|
|
9675
|
-
needNoticeUserIds.length > 0 && this._callAppListener('onUserJoin', needNoticeUserIds);
|
|
9676
|
-
// 通知业务层资源变更
|
|
9677
|
-
for (const userId in data) {
|
|
9678
|
-
if (userId === currentUserId) {
|
|
9679
|
-
continue;
|
|
9680
|
-
}
|
|
9681
|
-
this.msgTaskQueue.push(() => this._resourceHandle({
|
|
9682
|
-
uris: data[userId]
|
|
9683
|
-
}, RCRTCMessageType.TOTAL_CONTENT_RESOURCE, userId));
|
|
9684
|
-
}
|
|
9685
|
-
});
|
|
9686
|
-
}
|
|
9687
|
-
/**
|
|
9688
|
-
* 主播身份降级,取消己端已发布的所有资源
|
|
9689
|
-
*/
|
|
9690
|
-
__unpublishToSingal() {
|
|
9691
|
-
const crtUserId = this._context.getCurrentId();
|
|
9692
|
-
const unpublishList = this._roomResources[crtUserId];
|
|
9693
|
-
return this._context.setRTCTotalRes(this._roomId, buildPlusMessage(RCRTCMessageType.UNPUBLISH, unpublishList), buildTotalURIMessageContent([]), RCRTCMessageType.TOTAL_CONTENT_RESOURCE);
|
|
9694
|
-
}
|
|
9772
|
+
_afterChangedRole(data) { }
|
|
9695
9773
|
/**
|
|
9696
9774
|
* 销毁远端资源
|
|
9697
9775
|
*/
|
|
@@ -9769,9 +9847,14 @@ class RCMCUConfigBuilder {
|
|
|
9769
9847
|
/**
|
|
9770
9848
|
* trackId 有效性验证方法
|
|
9771
9849
|
*/
|
|
9772
|
-
_isValidTrackId
|
|
9850
|
+
_isValidTrackId,
|
|
9851
|
+
/**
|
|
9852
|
+
* 扩散 cdn_uris
|
|
9853
|
+
*/
|
|
9854
|
+
_sendCDNInfoSignal) {
|
|
9773
9855
|
this._onFlush = _onFlush;
|
|
9774
9856
|
this._isValidTrackId = _isValidTrackId;
|
|
9857
|
+
this._sendCDNInfoSignal = _sendCDNInfoSignal;
|
|
9775
9858
|
/**
|
|
9776
9859
|
* mcu 配置数据,每次向服务器提交全量数据
|
|
9777
9860
|
*/
|
|
@@ -10158,24 +10241,62 @@ class RCMCUConfigBuilder {
|
|
|
10158
10241
|
* 使已修改的配置生效,在调用该方法前,所有数据只会对本地配置进行修改,不会产生实际效果
|
|
10159
10242
|
*/
|
|
10160
10243
|
flush() {
|
|
10244
|
+
var _a, _b, _c, _d;
|
|
10161
10245
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10162
10246
|
const config = JSON.parse(JSON.stringify(this._values));
|
|
10163
10247
|
const { code } = yield this._onFlush(config);
|
|
10248
|
+
/**
|
|
10249
|
+
* 合流布局中包含分辨率设置时,需扩散 cdn_uris
|
|
10250
|
+
*/
|
|
10251
|
+
if (code === exports.RCRTCCode.SUCCESS && (((_b = (_a = this._values.output) === null || _a === void 0 ? void 0 : _a.video.normal) === null || _b === void 0 ? void 0 : _b.width) || ((_d = (_c = this._values.output) === null || _c === void 0 ? void 0 : _c.video.normal) === null || _d === void 0 ? void 0 : _d.fps))) {
|
|
10252
|
+
this._sendCDNInfoSignal();
|
|
10253
|
+
}
|
|
10164
10254
|
this._values = createMCUConfig();
|
|
10165
10255
|
return { code };
|
|
10166
10256
|
});
|
|
10167
10257
|
}
|
|
10168
10258
|
}
|
|
10169
10259
|
|
|
10260
|
+
var RCInnerCDNModel;
|
|
10261
|
+
(function (RCInnerCDNModel) {
|
|
10262
|
+
// 开启
|
|
10263
|
+
RCInnerCDNModel[RCInnerCDNModel["OPEN"] = 1] = "OPEN";
|
|
10264
|
+
// 停用
|
|
10265
|
+
RCInnerCDNModel[RCInnerCDNModel["STOP"] = 2] = "STOP";
|
|
10266
|
+
})(RCInnerCDNModel || (RCInnerCDNModel = {}));
|
|
10267
|
+
|
|
10268
|
+
var RCInnerCDNBroadcast;
|
|
10269
|
+
(function (RCInnerCDNBroadcast) {
|
|
10270
|
+
// 扩散
|
|
10271
|
+
RCInnerCDNBroadcast[RCInnerCDNBroadcast["SPREAD"] = 0] = "SPREAD";
|
|
10272
|
+
RCInnerCDNBroadcast[RCInnerCDNBroadcast["NO_SPREAD"] = -1] = "NO_SPREAD";
|
|
10273
|
+
})(RCInnerCDNBroadcast || (RCInnerCDNBroadcast = {}));
|
|
10274
|
+
|
|
10275
|
+
var RCInnerCDNPushMode;
|
|
10276
|
+
(function (RCInnerCDNPushMode) {
|
|
10277
|
+
// 自动模式
|
|
10278
|
+
RCInnerCDNPushMode[RCInnerCDNPushMode["AUTOMATIC"] = 0] = "AUTOMATIC";
|
|
10279
|
+
// 手动模式
|
|
10280
|
+
RCInnerCDNPushMode[RCInnerCDNPushMode["MANUAL"] = 1] = "MANUAL";
|
|
10281
|
+
})(RCInnerCDNPushMode || (RCInnerCDNPushMode = {}));
|
|
10282
|
+
|
|
10170
10283
|
/**
|
|
10171
10284
|
* 直播房间
|
|
10172
10285
|
*/
|
|
10173
10286
|
class RCLivingRoom extends RCAbstractRoom {
|
|
10174
10287
|
constructor(context, runtime, roomId, data, service, initOptions, clientEvent, _livingType, isUpgrage = false) {
|
|
10288
|
+
var _a;
|
|
10175
10289
|
super(context, runtime, roomId, data, engine.RTCMode.LIVE, service, initOptions, clientEvent, isUpgrage);
|
|
10176
10290
|
this._livingType = _livingType;
|
|
10291
|
+
/**
|
|
10292
|
+
* cdn_uris 信令扩散数据
|
|
10293
|
+
*/
|
|
10294
|
+
this._CDNUris = null;
|
|
10295
|
+
this._CDNEnable = false;
|
|
10177
10296
|
// 初始化 MCUBuilder
|
|
10178
|
-
this._mcuConfigBuilder = new RCMCUConfigBuilder(this._onMCUConfigFlush.bind(this), this._isValidResourceId.bind(this));
|
|
10297
|
+
this._mcuConfigBuilder = new RCMCUConfigBuilder(this._onMCUConfigFlush.bind(this), this._isValidResourceId.bind(this), this._sendCDNInfoSignal.bind(this));
|
|
10298
|
+
const CDNUris = (_a = data.roomInfo.filter((item) => { return item.key === 'cdn_uris'; })[0]) === null || _a === void 0 ? void 0 : _a.value;
|
|
10299
|
+
CDNUris && (this._CDNUris = JSON.parse(CDNUris)[0]);
|
|
10179
10300
|
}
|
|
10180
10301
|
getLivingType() {
|
|
10181
10302
|
return this._livingType;
|
|
@@ -10199,16 +10320,214 @@ class RCLivingRoom extends RCAbstractRoom {
|
|
|
10199
10320
|
UserId: this._context.getCurrentId(),
|
|
10200
10321
|
SessionId: this.getSessionId()
|
|
10201
10322
|
};
|
|
10202
|
-
const { code } = yield this._service.setMcuConfig(headers, data);
|
|
10323
|
+
const { code, res } = yield this._service.setMcuConfig(headers, data);
|
|
10203
10324
|
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
10204
10325
|
logger.error(`set MCU config failed: ${code}`);
|
|
10326
|
+
return { code };
|
|
10205
10327
|
}
|
|
10206
|
-
logger.
|
|
10207
|
-
|
|
10328
|
+
logger.info('set MCU config success');
|
|
10329
|
+
res.pull_url && (this._CDNUris = JSON.parse(res.pull_url));
|
|
10330
|
+
return { code, res };
|
|
10208
10331
|
});
|
|
10209
10332
|
}
|
|
10333
|
+
/**
|
|
10334
|
+
* 主播端断线重连后,需更新内存中的 CDN 数据
|
|
10335
|
+
* 判断房间内 CDN 状态是否和内存数据一致,不一致时需通知到客户端
|
|
10336
|
+
*/
|
|
10210
10337
|
__onReconnected() {
|
|
10211
|
-
|
|
10338
|
+
const _super = Object.create(null, {
|
|
10339
|
+
__onReconnected: { get: () => super.__onReconnected }
|
|
10340
|
+
});
|
|
10341
|
+
var _a, _b;
|
|
10342
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10343
|
+
const res = yield _super.__onReconnected.call(this, this._livingType);
|
|
10344
|
+
if (!res || !res.data) {
|
|
10345
|
+
return;
|
|
10346
|
+
}
|
|
10347
|
+
const roomInfo = res.data.roomInfo;
|
|
10348
|
+
const CDNUris = (_a = roomInfo.filter((item) => { return item.key === 'cdn_uris'; })[0]) === null || _a === void 0 ? void 0 : _a.value;
|
|
10349
|
+
if (!CDNUris) {
|
|
10350
|
+
return;
|
|
10351
|
+
}
|
|
10352
|
+
const parseCDNUris = JSON.parse(CDNUris);
|
|
10353
|
+
if (((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.enableInnerCDN) !== parseCDNUris.enableInnerCDN) {
|
|
10354
|
+
this._callAppListener('onCDNEnableChange', parseCDNUris.enableInnerCDN);
|
|
10355
|
+
}
|
|
10356
|
+
this._CDNUris = parseCDNUris;
|
|
10357
|
+
});
|
|
10358
|
+
}
|
|
10359
|
+
/**
|
|
10360
|
+
* 开启/停用推 CDN
|
|
10361
|
+
*/
|
|
10362
|
+
enableInnerCDN(enable) {
|
|
10363
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10364
|
+
if (!engine.isBoolean(enable)) {
|
|
10365
|
+
logger.error('`enable` is invalid');
|
|
10366
|
+
return { code: exports.RCRTCCode.PARAMS_ERROR };
|
|
10367
|
+
}
|
|
10368
|
+
this._CDNEnable = enable;
|
|
10369
|
+
const params = {
|
|
10370
|
+
version: 2,
|
|
10371
|
+
output: {
|
|
10372
|
+
inCDNModel: enable ? RCInnerCDNModel.OPEN : RCInnerCDNModel.STOP
|
|
10373
|
+
}
|
|
10374
|
+
};
|
|
10375
|
+
const { code } = yield this._onMCUConfigFlush(params);
|
|
10376
|
+
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
10377
|
+
logger.error(`enableInnerCDN failed -> code: ${code}`);
|
|
10378
|
+
return { code: exports.RCRTCCode.SIGNAL_ERROR };
|
|
10379
|
+
}
|
|
10380
|
+
// 判断是否需要扩散 cdn_uris 时
|
|
10381
|
+
if (this._CDNUris && (this._CDNUris.broadcast !== RCInnerCDNBroadcast.SPREAD)) {
|
|
10382
|
+
logger.info('enableInnerCDN succeed');
|
|
10383
|
+
return { code: exports.RCRTCCode.SUCCESS };
|
|
10384
|
+
}
|
|
10385
|
+
/**
|
|
10386
|
+
* 扩散 cdn_uris
|
|
10387
|
+
*/
|
|
10388
|
+
const { code: sendSingalCode } = yield push(() => __awaiter(this, void 0, void 0, function* () { return this._sendCDNInfoSignal(); }));
|
|
10389
|
+
if (sendSingalCode === exports.RCRTCCode.SUCCESS) {
|
|
10390
|
+
logger.info('enableInnerCDN succeed');
|
|
10391
|
+
return { code: exports.RCRTCCode.SUCCESS };
|
|
10392
|
+
}
|
|
10393
|
+
logger.error(`enableInnerCDN failed -> code: ${sendSingalCode}`);
|
|
10394
|
+
return { code: sendSingalCode };
|
|
10395
|
+
});
|
|
10396
|
+
}
|
|
10397
|
+
/**
|
|
10398
|
+
* 开启、停用 CDN 推资源后发信令
|
|
10399
|
+
*/
|
|
10400
|
+
_sendCDNInfoSignal() {
|
|
10401
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10402
|
+
this._CDNUris = Object.assign({}, this._CDNUris, { enableInnerCDN: this._CDNEnable });
|
|
10403
|
+
const resCodeArr = yield Promise.all([this._spreadCDNInfo(this._CDNUris), this._setRoomCDNInfo(this._CDNUris)]);
|
|
10404
|
+
const isSuccess = resCodeArr.every((item) => {
|
|
10405
|
+
return item.code === exports.RCRTCCode.SUCCESS;
|
|
10406
|
+
});
|
|
10407
|
+
return isSuccess ? { code: exports.RCRTCCode.SUCCESS } : { code: exports.RCRTCCode.SIGNAL_ERROR };
|
|
10408
|
+
});
|
|
10409
|
+
}
|
|
10410
|
+
/**
|
|
10411
|
+
* 扩散 cdn_uris 资源
|
|
10412
|
+
*/
|
|
10413
|
+
_spreadCDNInfo(CDNUris) {
|
|
10414
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10415
|
+
const code = yield this._context.setRTCCDNUris(this._roomId, RCRTCMessageType.TOTAL_CONTENT_RESOURCE, JSON.stringify([CDNUris]));
|
|
10416
|
+
if (code !== engine.ErrorCode.SUCCESS) {
|
|
10417
|
+
logger.error(`spreadCDNInfo failed -> code: ${code}`);
|
|
10418
|
+
return { code: exports.RCRTCCode.SIGNAL_ERROR };
|
|
10419
|
+
}
|
|
10420
|
+
logger.info('spreadCDNInfo succeed');
|
|
10421
|
+
return { code: exports.RCRTCCode.SUCCESS };
|
|
10422
|
+
});
|
|
10423
|
+
}
|
|
10424
|
+
/**
|
|
10425
|
+
* 给房间设置 CDN 数据
|
|
10426
|
+
*/
|
|
10427
|
+
_setRoomCDNInfo(CDNUris) {
|
|
10428
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10429
|
+
const code = yield this._context.setRTCData(this._roomId, 'cdn_uris', JSON.stringify([CDNUris]), true, engine.RTCApiType.ROOM);
|
|
10430
|
+
if (code !== engine.ErrorCode.SUCCESS) {
|
|
10431
|
+
logger.error(`setRoomCDNInfo failed -> code: ${code}`);
|
|
10432
|
+
return { code: exports.RCRTCCode.SIGNAL_ERROR };
|
|
10433
|
+
}
|
|
10434
|
+
logger.info('setRoomCDNInfo succeed');
|
|
10435
|
+
return { code: exports.RCRTCCode.SUCCESS };
|
|
10436
|
+
});
|
|
10437
|
+
}
|
|
10438
|
+
/**
|
|
10439
|
+
* 资源变化时触发
|
|
10440
|
+
* 直播房间需单独处理 cdn_uris
|
|
10441
|
+
*/
|
|
10442
|
+
_resourceHandle(content, messageType, userId) {
|
|
10443
|
+
const _super = Object.create(null, {
|
|
10444
|
+
_resourceHandle: { get: () => super._resourceHandle }
|
|
10445
|
+
});
|
|
10446
|
+
var _a;
|
|
10447
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10448
|
+
_super._resourceHandle.call(this, content, messageType, userId);
|
|
10449
|
+
if (!content.cdn_uris) {
|
|
10450
|
+
return;
|
|
10451
|
+
}
|
|
10452
|
+
// 给业务层抛 CDN 状态
|
|
10453
|
+
if (((_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.enableInnerCDN) !== content.cdn_uris[0].enableInnerCDN) {
|
|
10454
|
+
this._callAppListener('onCDNEnableChange', !this.__getCDNEnable());
|
|
10455
|
+
}
|
|
10456
|
+
// 更新 _CDNUris
|
|
10457
|
+
this._CDNUris = content.cdn_uris[0];
|
|
10458
|
+
});
|
|
10459
|
+
}
|
|
10460
|
+
/**
|
|
10461
|
+
* 重写父类 _exchangeHandle 方法
|
|
10462
|
+
*/
|
|
10463
|
+
_exchangeHandle(body) {
|
|
10464
|
+
var _a, _b, _c;
|
|
10465
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10466
|
+
const res = yield this._service.exchange(this._getRTCReqestHeaders(), body);
|
|
10467
|
+
const pullUrl = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.urls) === null || _b === void 0 ? void 0 : _b.pull_url;
|
|
10468
|
+
if (res.code !== exports.RCRTCCode.SUCCESS || !pullUrl) {
|
|
10469
|
+
return res;
|
|
10470
|
+
}
|
|
10471
|
+
/**
|
|
10472
|
+
* 自动模式下:
|
|
10473
|
+
* /exchange 完需根据 broadcast 字端判断是否扩散 cdn_uris 数据,设置房间 cdn_uris 数据
|
|
10474
|
+
*/
|
|
10475
|
+
this._CDNUris = JSON.parse(pullUrl);
|
|
10476
|
+
if (((_c = this._CDNUris) === null || _c === void 0 ? void 0 : _c.broadcast) === RCInnerCDNBroadcast.SPREAD) {
|
|
10477
|
+
this._CDNEnable = true;
|
|
10478
|
+
this._sendCDNInfoSignal();
|
|
10479
|
+
}
|
|
10480
|
+
return res;
|
|
10481
|
+
});
|
|
10482
|
+
}
|
|
10483
|
+
/**
|
|
10484
|
+
* 观众切换为主播后直接处理人员变更及资源变更
|
|
10485
|
+
*/
|
|
10486
|
+
_afterChangedRole(data) {
|
|
10487
|
+
const parseData = parseRoomData(data);
|
|
10488
|
+
const currentUserId = this._context.getCurrentId();
|
|
10489
|
+
const joinedAnchorList = Object.keys(parseData);
|
|
10490
|
+
// 观众升级主播成功后返回房间实例,才可注册房间事件,需异步抛出
|
|
10491
|
+
setTimeout(() => {
|
|
10492
|
+
var _a, _b, _c;
|
|
10493
|
+
// 通知业务层人员变更
|
|
10494
|
+
const needNoticeUserIds = joinedAnchorList.filter(id => {
|
|
10495
|
+
return id !== currentUserId;
|
|
10496
|
+
});
|
|
10497
|
+
needNoticeUserIds.length > 0 && this._callAppListener('onUserJoin', needNoticeUserIds);
|
|
10498
|
+
// 通知业务层资源变更
|
|
10499
|
+
for (const userId in parseData) {
|
|
10500
|
+
if (userId === currentUserId) {
|
|
10501
|
+
continue;
|
|
10502
|
+
}
|
|
10503
|
+
this._resourceHandle({
|
|
10504
|
+
uris: parseData[userId]
|
|
10505
|
+
}, RCRTCMessageType.TOTAL_CONTENT_RESOURCE, userId);
|
|
10506
|
+
}
|
|
10507
|
+
const CDNUris = (_a = data.roomInfo.filter((item) => { return item.key === 'cdn_uris'; })[0]) === null || _a === void 0 ? void 0 : _a.value;
|
|
10508
|
+
if (!CDNUris) {
|
|
10509
|
+
return;
|
|
10510
|
+
}
|
|
10511
|
+
if (((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.push_mode) === RCInnerCDNPushMode.MANUAL) {
|
|
10512
|
+
this._callAppListener('onCDNEnableChange', (_c = this._CDNUris) === null || _c === void 0 ? void 0 : _c.enableInnerCDN);
|
|
10513
|
+
}
|
|
10514
|
+
});
|
|
10515
|
+
}
|
|
10516
|
+
/**
|
|
10517
|
+
* 返回 CDN 是否可用
|
|
10518
|
+
* @returns boolean
|
|
10519
|
+
*/
|
|
10520
|
+
__getCDNEnable() {
|
|
10521
|
+
var _a;
|
|
10522
|
+
return (_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.enableInnerCDN;
|
|
10523
|
+
}
|
|
10524
|
+
/**
|
|
10525
|
+
* 返回 CDN 推送模式: 自动 or 手动
|
|
10526
|
+
* @returns boolean
|
|
10527
|
+
*/
|
|
10528
|
+
__getCDNPushMode() {
|
|
10529
|
+
var _a;
|
|
10530
|
+
return (_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.push_mode;
|
|
10212
10531
|
}
|
|
10213
10532
|
}
|
|
10214
10533
|
|
|
@@ -10267,7 +10586,7 @@ const getCommonHeader = () => ({
|
|
|
10267
10586
|
'Content-Type': 'application/json;charset=UTF-8',
|
|
10268
10587
|
'Cache-Control': 'no-cache',
|
|
10269
10588
|
ClientType: `web|${browserInfo.browser}|${browserInfo.version}`,
|
|
10270
|
-
ClientVersion: "5.
|
|
10589
|
+
ClientVersion: "5.2.2-alpha.1",
|
|
10271
10590
|
'Client-Session-Id': getUUID(),
|
|
10272
10591
|
'Request-Id': Date.now().toString()
|
|
10273
10592
|
});
|
|
@@ -10435,7 +10754,25 @@ class RCMediaService {
|
|
|
10435
10754
|
if (status === 200) {
|
|
10436
10755
|
logger.debug(`request success -> Request-Id: ${commonHeader['Request-Id']}`);
|
|
10437
10756
|
const data = JSON.parse(jsonStr);
|
|
10438
|
-
return { code: data.resultCode };
|
|
10757
|
+
return { code: data.resultCode, res: data };
|
|
10758
|
+
}
|
|
10759
|
+
return { code: exports.RCRTCCode.REQUEST_FAILED };
|
|
10760
|
+
});
|
|
10761
|
+
}
|
|
10762
|
+
/**
|
|
10763
|
+
* 房间内观众获取 CDN 资源信息、拉流地址
|
|
10764
|
+
*/
|
|
10765
|
+
getCDNResourceInfo(headers, url) {
|
|
10766
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10767
|
+
const commonHeader = getCommonHeader();
|
|
10768
|
+
const { status, data: resStr } = yield this._runtime.httpReq({
|
|
10769
|
+
url,
|
|
10770
|
+
headers: Object.assign(Object.assign({}, commonHeader), headers),
|
|
10771
|
+
method: engine.HttpMethod.GET
|
|
10772
|
+
});
|
|
10773
|
+
if (status === 200) {
|
|
10774
|
+
const data = JSON.parse(resStr);
|
|
10775
|
+
return { code: data.resultCode, res: data };
|
|
10439
10776
|
}
|
|
10440
10777
|
logger.warn(`request failed -> Request-Id: ${commonHeader['Request-Id']}, status: ${status}, url: ${url}`);
|
|
10441
10778
|
return { code: exports.RCRTCCode.REQUEST_FAILED };
|
|
@@ -10580,12 +10917,15 @@ class RCAudienceClient {
|
|
|
10580
10917
|
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
10581
10918
|
return { code, tracks };
|
|
10582
10919
|
}
|
|
10583
|
-
//
|
|
10920
|
+
// 直播观众订阅的是合流后的数据,并不存在流的归属问题,此处直接以虚拟生成的合流 id 替代 userId
|
|
10584
10921
|
const mcuId = `rc_mcu_${Date.now()}`;
|
|
10585
10922
|
const tag = 'RongCloudRTC';
|
|
10586
|
-
this._subTracks.length
|
|
10587
|
-
|
|
10588
|
-
|
|
10923
|
+
if (this._subTracks.length === 0) {
|
|
10924
|
+
// 观众端单次只能订阅一个 liveUrl, 订阅后再次重复订阅只是修改订阅参数
|
|
10925
|
+
// 重复订阅后之前订阅的流可直接根据参数变动,无需重新添加 transceiver
|
|
10926
|
+
this._subTracks.push(new RCRemoteAudioTrack(tag, mcuId), new RCRemoteVideoTrack(tag, mcuId));
|
|
10927
|
+
this._pc.updateSubRemoteTracks(this._subTracks.slice());
|
|
10928
|
+
}
|
|
10589
10929
|
const offer = yield this._pc.createOffer(true);
|
|
10590
10930
|
const body = {
|
|
10591
10931
|
sdp: offer,
|
|
@@ -10685,6 +11025,19 @@ class RCAudienceClient {
|
|
|
10685
11025
|
}
|
|
10686
11026
|
}
|
|
10687
11027
|
|
|
11028
|
+
exports.RCInnerCDNPullKind = void 0;
|
|
11029
|
+
(function (RCInnerCDNPullKind) {
|
|
11030
|
+
RCInnerCDNPullKind["RTMP"] = "rtmp";
|
|
11031
|
+
RCInnerCDNPullKind["FLV"] = "flv";
|
|
11032
|
+
RCInnerCDNPullKind["HLS"] = "hls";
|
|
11033
|
+
})(exports.RCInnerCDNPullKind || (exports.RCInnerCDNPullKind = {}));
|
|
11034
|
+
|
|
11035
|
+
exports.RCInnerCDNPullIsHttps = void 0;
|
|
11036
|
+
(function (RCInnerCDNPullIsHttps) {
|
|
11037
|
+
RCInnerCDNPullIsHttps[RCInnerCDNPullIsHttps["NOT_HTTPS"] = 0] = "NOT_HTTPS";
|
|
11038
|
+
RCInnerCDNPullIsHttps[RCInnerCDNPullIsHttps["HTTPS"] = 1] = "HTTPS";
|
|
11039
|
+
})(exports.RCInnerCDNPullIsHttps || (exports.RCInnerCDNPullIsHttps = {}));
|
|
11040
|
+
|
|
10688
11041
|
const tinyConf = Object.assign(Object.assign({}, transResolution(exports.RCResolution.W176_H144)), { frameRate: transFrameRate(exports.RCFrameRate.FPS_15) });
|
|
10689
11042
|
/**
|
|
10690
11043
|
* 观众直播房间类
|
|
@@ -10693,12 +11046,12 @@ const tinyConf = Object.assign(Object.assign({}, transResolution(exports.RCResol
|
|
|
10693
11046
|
* 2、观众订阅、取消订阅资源
|
|
10694
11047
|
*/
|
|
10695
11048
|
class RCAudienceLivingRoom {
|
|
10696
|
-
constructor(_context, _runtime, _initOptions, _roomId,
|
|
11049
|
+
constructor(_context, _runtime, _initOptions, _roomId, _joinResData, _livingType) {
|
|
10697
11050
|
this._context = _context;
|
|
10698
11051
|
this._runtime = _runtime;
|
|
10699
11052
|
this._initOptions = _initOptions;
|
|
10700
11053
|
this._roomId = _roomId;
|
|
10701
|
-
this.
|
|
11054
|
+
this._joinResData = _joinResData;
|
|
10702
11055
|
this._livingType = _livingType;
|
|
10703
11056
|
this._roomAnchorList = [];
|
|
10704
11057
|
this._roomRes = {};
|
|
@@ -10743,14 +11096,18 @@ class RCAudienceLivingRoom {
|
|
|
10743
11096
|
* * key RC_ANCHOR_LIST value: 为主播 ID 集合
|
|
10744
11097
|
* * key RC_RES_`userId` value: 为主播发布的资源
|
|
10745
11098
|
* * key RC_RTC_SESSIONID value: sessionId
|
|
11099
|
+
* * key RC_CDN value: CDN 资源数据
|
|
10746
11100
|
*/
|
|
10747
11101
|
singalDataChange(singalData, roomId) {
|
|
11102
|
+
var _a;
|
|
10748
11103
|
if (roomId !== this._roomId) {
|
|
10749
11104
|
logger.warn(`singalDataChange -> not the current room data: data roomId: ${roomId}, current roomId: ${this._roomId}`);
|
|
10750
11105
|
return;
|
|
10751
11106
|
}
|
|
10752
11107
|
logger.debug('singalDataChange -> singalData:', JSON.stringify(singalData || {}));
|
|
10753
11108
|
const allMcuUris = [];
|
|
11109
|
+
const CDNUrisStr = (_a = singalData.filter((item) => { return item.key === 'RC_CDN'; })[0]) === null || _a === void 0 ? void 0 : _a.value;
|
|
11110
|
+
CDNUrisStr && this._diffCDNUris(JSON.parse(JSON.parse(CDNUrisStr).cdn_uris)[0]);
|
|
10754
11111
|
singalData.forEach(data => {
|
|
10755
11112
|
const { key, value, timestamp, uid } = data;
|
|
10756
11113
|
const isResKey = key.indexOf('RC_RES_') !== -1;
|
|
@@ -11104,7 +11461,7 @@ class RCAudienceLivingRoom {
|
|
|
11104
11461
|
return {
|
|
11105
11462
|
'App-Key': this._context.getAppkey(),
|
|
11106
11463
|
RoomId: userId,
|
|
11107
|
-
Token: this.
|
|
11464
|
+
Token: this._joinResData.token,
|
|
11108
11465
|
RoomType: engine.RTCMode.LIVE,
|
|
11109
11466
|
UserId: userId,
|
|
11110
11467
|
'Session-Id': this._sessionId
|
|
@@ -11213,6 +11570,123 @@ class RCAudienceLivingRoom {
|
|
|
11213
11570
|
return { code: exports.RCRTCCode.SUCCESS };
|
|
11214
11571
|
});
|
|
11215
11572
|
}
|
|
11573
|
+
/**
|
|
11574
|
+
* 对比 cdn_uris 资源
|
|
11575
|
+
* @param newCDNUris 新的 cdn_uris 数据
|
|
11576
|
+
*/
|
|
11577
|
+
_diffCDNUris(newCDNUris) {
|
|
11578
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
11579
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
11580
|
+
/**
|
|
11581
|
+
* CDN 资源减少: 上次 CDNUris 中有 url,变更后无 url
|
|
11582
|
+
*/
|
|
11583
|
+
if (((_a = this._CDNUris) === null || _a === void 0 ? void 0 : _a.url) && !newCDNUris.url) {
|
|
11584
|
+
this._callAppListener('onCDNInfoDisable');
|
|
11585
|
+
/**
|
|
11586
|
+
* 更新内存中存储的 cdn_uris 数据
|
|
11587
|
+
*/
|
|
11588
|
+
this._CDNUris = newCDNUris;
|
|
11589
|
+
return;
|
|
11590
|
+
}
|
|
11591
|
+
/**
|
|
11592
|
+
* CDN 资源新增条件:
|
|
11593
|
+
* 内存中无 CDNUris 或
|
|
11594
|
+
* 上次 CDNUris 无 url,变更后有 url
|
|
11595
|
+
*/
|
|
11596
|
+
if (!this._CDNUris || (!((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.url) && newCDNUris.url)) {
|
|
11597
|
+
this._callAppListener('onCDNInfoEnable', {
|
|
11598
|
+
resolution: `W${newCDNUris.w}_H${newCDNUris.h}`,
|
|
11599
|
+
fps: newCDNUris.fps
|
|
11600
|
+
});
|
|
11601
|
+
}
|
|
11602
|
+
/**
|
|
11603
|
+
* CDN 资源变更: w、h、fps 其中一项变化
|
|
11604
|
+
*/
|
|
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));
|
|
11608
|
+
if (isWChange || isHChange || isFpsChange) {
|
|
11609
|
+
this._callAppListener('onCDNInfoChange', {
|
|
11610
|
+
resolution: `W${newCDNUris.w}_H${newCDNUris.h}`,
|
|
11611
|
+
fps: newCDNUris.fps
|
|
11612
|
+
});
|
|
11613
|
+
}
|
|
11614
|
+
/**
|
|
11615
|
+
* 更新内存中存储的 cdn_uris 数据
|
|
11616
|
+
*/
|
|
11617
|
+
this._CDNUris = newCDNUris;
|
|
11618
|
+
});
|
|
11619
|
+
}
|
|
11620
|
+
/**
|
|
11621
|
+
* 获取 CDN 资源对应的拉流地址
|
|
11622
|
+
* 首次获取 CDNPlayUrl 时,需传入 url,
|
|
11623
|
+
* 业务层调用时使用内存中 _CDNUris 的 url,无 _CDNUris 时说明观众端未赋值过 _CDNUris
|
|
11624
|
+
* @returns CDNPlayUrl
|
|
11625
|
+
*/
|
|
11626
|
+
_getCDNPlayUrl(params, url) {
|
|
11627
|
+
var _a, _b;
|
|
11628
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
11629
|
+
const { w, h, fps } = params;
|
|
11630
|
+
const kind = this._initOptions.pullInnerCDNProtocol || exports.RCInnerCDNPullKind.FLV;
|
|
11631
|
+
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}`);
|
|
11637
|
+
return { code: exports.RCRTCCode.CDN_RESOURCE_IS_EMPTY };
|
|
11638
|
+
}
|
|
11639
|
+
const headers = {
|
|
11640
|
+
'App-Key': this._context.getAppkey(),
|
|
11641
|
+
Token: this._joinResData.token,
|
|
11642
|
+
RoomId: this.getRoomId(),
|
|
11643
|
+
UserId: this._context.getCurrentId(),
|
|
11644
|
+
SessionId: this.getSessionId()
|
|
11645
|
+
};
|
|
11646
|
+
const paramsArr = [];
|
|
11647
|
+
w && paramsArr.push(`w=${w}`);
|
|
11648
|
+
h && paramsArr.push(`h=${h}`);
|
|
11649
|
+
fps && paramsArr.push(`fps=${fps}`);
|
|
11650
|
+
paramsArr.push(`kind=${kind}`);
|
|
11651
|
+
paramsArr.push(`is_https=${useHttps}`);
|
|
11652
|
+
const paramsStr = paramsArr.join('&');
|
|
11653
|
+
let requestUrl = `${url || ((_b = this._CDNUris) === null || _b === void 0 ? void 0 : _b.url)}?`;
|
|
11654
|
+
paramsStr && (requestUrl += paramsStr);
|
|
11655
|
+
const { code, res } = yield this._service.getCDNResourceInfo(headers, requestUrl);
|
|
11656
|
+
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
11657
|
+
logger.error(`getCDNPlayUrl failed: ${code}`);
|
|
11658
|
+
return { code };
|
|
11659
|
+
}
|
|
11660
|
+
logger.info(`getCDNPlayUrl success: ${res === null || res === void 0 ? void 0 : res.data.pull_url}`);
|
|
11661
|
+
return {
|
|
11662
|
+
code,
|
|
11663
|
+
CDNPlayUrl: res === null || res === void 0 ? void 0 : res.data.pull_url
|
|
11664
|
+
};
|
|
11665
|
+
});
|
|
11666
|
+
}
|
|
11667
|
+
/**
|
|
11668
|
+
* 获取 CDN 资源对应的拉流地址
|
|
11669
|
+
* @returns CDNPlayUrl
|
|
11670
|
+
*/
|
|
11671
|
+
getCDNPlayUrl(resolution, fps) {
|
|
11672
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
11673
|
+
if (resolution && !isValidResolution(resolution)) {
|
|
11674
|
+
logger.error('`resolution` is invalid');
|
|
11675
|
+
return { code: exports.RCRTCCode.PARAMS_ERROR };
|
|
11676
|
+
}
|
|
11677
|
+
if (fps && !isValidFPS(fps)) {
|
|
11678
|
+
logger.error('`fps` is invalid');
|
|
11679
|
+
return { code: exports.RCRTCCode.PARAMS_ERROR };
|
|
11680
|
+
}
|
|
11681
|
+
const { width, height } = resolution ? transResolution(resolution) : { width: null, height: null };
|
|
11682
|
+
const fpsNum = fps ? transFrameRate(fps) : null;
|
|
11683
|
+
const params = {};
|
|
11684
|
+
width && (params.w = width);
|
|
11685
|
+
height && (params.h = height);
|
|
11686
|
+
fpsNum && (params.fps = fpsNum);
|
|
11687
|
+
return this._getCDNPlayUrl(params);
|
|
11688
|
+
});
|
|
11689
|
+
}
|
|
11216
11690
|
/**
|
|
11217
11691
|
* 订阅资源
|
|
11218
11692
|
* @param tracks
|
|
@@ -11270,6 +11744,8 @@ class RCAudienceLivingRoom {
|
|
|
11270
11744
|
this._pc.destroy();
|
|
11271
11745
|
// 销毁 polarisReport 实例
|
|
11272
11746
|
this._polarisReport = null;
|
|
11747
|
+
// 清空 onrtcdatachange 事件监听
|
|
11748
|
+
this._context.onrtcdatachange = () => { };
|
|
11273
11749
|
});
|
|
11274
11750
|
}
|
|
11275
11751
|
/**
|
|
@@ -11311,7 +11787,12 @@ class RCAudienceLivingRoom {
|
|
|
11311
11787
|
* @param tag 参数描述
|
|
11312
11788
|
*/
|
|
11313
11789
|
registerRoomEventListener(listener) {
|
|
11790
|
+
var _a;
|
|
11314
11791
|
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);
|
|
11315
11796
|
}
|
|
11316
11797
|
/**
|
|
11317
11798
|
* 音量上报
|
|
@@ -11516,7 +11997,12 @@ class RCRTCClient {
|
|
|
11516
11997
|
logger.debug(`JoinRoom success -> userId: ${this._context.getCurrentId()}, roomId: ${roomId}, data: ${JSON.stringify(data)}`);
|
|
11517
11998
|
const room = new RCLivingRoom(this._context, this._runtime, roomId, data, this._service, this._options, this._releaseCrtRoomObj.bind(this), livingType, false);
|
|
11518
11999
|
this._crtRoom = room;
|
|
11519
|
-
|
|
12000
|
+
const joinLivingResData = { room, code: exports.RCRTCCode.SUCCESS, userIds: room.getRemoteUserIds(), tracks: room.getRemoteTracks() };
|
|
12001
|
+
// 手动模式时,用户加入房间,需返回 CDN 开关状态
|
|
12002
|
+
if (room.__getCDNPushMode() === RCInnerCDNPushMode.MANUAL) {
|
|
12003
|
+
Object.assign(joinLivingResData, { CDNEnable: room.__getCDNEnable() });
|
|
12004
|
+
}
|
|
12005
|
+
return joinLivingResData;
|
|
11520
12006
|
});
|
|
11521
12007
|
}
|
|
11522
12008
|
/**
|
|
@@ -11627,7 +12113,8 @@ class RCRTCClient {
|
|
|
11627
12113
|
deviceId: options === null || options === void 0 ? void 0 : options.cameraId,
|
|
11628
12114
|
frameRate: transFrameRate((options === null || options === void 0 ? void 0 : options.frameRate) || exports.RCFrameRate.FPS_15),
|
|
11629
12115
|
width,
|
|
11630
|
-
height
|
|
12116
|
+
height,
|
|
12117
|
+
facingMode: options === null || options === void 0 ? void 0 : options.faceMode
|
|
11631
12118
|
}
|
|
11632
12119
|
});
|
|
11633
12120
|
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
@@ -11645,7 +12132,7 @@ class RCRTCClient {
|
|
|
11645
12132
|
* @returns
|
|
11646
12133
|
*/
|
|
11647
12134
|
createMicrophoneAndCameraTracks(tag = 'RongCloudRTC', options) {
|
|
11648
|
-
var _a, _b, _c, _d, _e;
|
|
12135
|
+
var _a, _b, _c, _d, _e, _f;
|
|
11649
12136
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11650
12137
|
const tracks = [];
|
|
11651
12138
|
if (!isValidTag(tag)) {
|
|
@@ -11662,9 +12149,10 @@ class RCRTCClient {
|
|
|
11662
12149
|
deviceId: (_b = options === null || options === void 0 ? void 0 : options.video) === null || _b === void 0 ? void 0 : _b.cameraId,
|
|
11663
12150
|
frameRate: transFrameRate(((_c = options === null || options === void 0 ? void 0 : options.video) === null || _c === void 0 ? void 0 : _c.frameRate) || exports.RCFrameRate.FPS_15),
|
|
11664
12151
|
width,
|
|
11665
|
-
height
|
|
12152
|
+
height,
|
|
12153
|
+
facingMode: (_d = options === null || options === void 0 ? void 0 : options.video) === null || _d === void 0 ? void 0 : _d.faceMode
|
|
11666
12154
|
},
|
|
11667
|
-
audio: { deviceId: (
|
|
12155
|
+
audio: { deviceId: (_e = options === null || options === void 0 ? void 0 : options.audio) === null || _e === void 0 ? void 0 : _e.micphoneId, sampleRate: (_f = options === null || options === void 0 ? void 0 : options.audio) === null || _f === void 0 ? void 0 : _f.sampleRate }
|
|
11668
12156
|
});
|
|
11669
12157
|
if (code !== exports.RCRTCCode.SUCCESS) {
|
|
11670
12158
|
return { code, tracks };
|
|
@@ -11887,7 +12375,8 @@ class RCRTCClient {
|
|
|
11887
12375
|
logger.error('audienceJoinLivingRoomError:', code);
|
|
11888
12376
|
return { code: exports.RCRTCCode.SIGNAL_AUDIENCE_JOIN_ROOM_FAILED };
|
|
11889
12377
|
}
|
|
11890
|
-
|
|
12378
|
+
logger.info(`joinLivingRoomAsAudience success, room data: ${JSON.stringify(data)}`);
|
|
12379
|
+
const room = new RCAudienceLivingRoom(this._context, this._runtime, this._options, roomId, data, livingType);
|
|
11891
12380
|
this._crtAudienceLivingRoom = room;
|
|
11892
12381
|
return { room, code: exports.RCRTCCode.SUCCESS };
|
|
11893
12382
|
});
|
|
@@ -11948,18 +12437,13 @@ class RCRTCClient {
|
|
|
11948
12437
|
if (this._crtAudienceLivingRoom) {
|
|
11949
12438
|
return { code: exports.RCRTCCode.REPERT_JOIN_ROOM };
|
|
11950
12439
|
}
|
|
11951
|
-
const singalCode = yield room.__unpublishToSingal();
|
|
11952
|
-
if (singalCode !== engine.ErrorCode.SUCCESS) {
|
|
11953
|
-
logger.error('change room identity setAllUris error', singalCode);
|
|
11954
|
-
return { code: exports.RCRTCCode.SIGNAL_ERROR };
|
|
11955
|
-
}
|
|
11956
12440
|
const { code, data } = yield this._context.rtcIdentityChange(room._roomId, engine.RTCIdentityChangeType.AnchorToViewer, room.getLivingType());
|
|
11957
12441
|
if (code !== engine.ErrorCode.SUCCESS) {
|
|
11958
12442
|
logger.error('change room identity error', code);
|
|
11959
12443
|
return { code: exports.RCRTCCode.SIGNAL_ROOM_CHANGE_IDENTITY_FAILED };
|
|
11960
12444
|
}
|
|
11961
|
-
|
|
11962
|
-
const crtRoom = new RCAudienceLivingRoom(this._context, this._runtime, this._options, room._roomId,
|
|
12445
|
+
logger.info(`downgradeToAudienceRoom success, room data: ${JSON.stringify(data)}`);
|
|
12446
|
+
const crtRoom = new RCAudienceLivingRoom(this._context, this._runtime, this._options, room._roomId, data, room.getLivingType());
|
|
11963
12447
|
this._crtAudienceLivingRoom = crtRoom;
|
|
11964
12448
|
// 主播房间内存数据清除及停止 Signal 房间心跳
|
|
11965
12449
|
this._crtRoom.__destroy(false);
|
|
@@ -11970,15 +12454,11 @@ class RCRTCClient {
|
|
|
11970
12454
|
}
|
|
11971
12455
|
/**
|
|
11972
12456
|
* 获取在房间内用户信息
|
|
11973
|
-
*
|
|
11974
|
-
* @since version 5.1.5
|
|
12457
|
+
* @since version 5.2.1
|
|
11975
12458
|
*/
|
|
11976
|
-
|
|
12459
|
+
getJoinedRoomInfo() {
|
|
11977
12460
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11978
|
-
|
|
11979
|
-
return { code: exports.RCRTCCode.PARAMS_ERROR };
|
|
11980
|
-
}
|
|
11981
|
-
const { code, data } = yield this._context.getRTCJoinedUserInfo(userId);
|
|
12461
|
+
const { code, data } = yield this._context.getRTCJoinedUserInfo(this._context.getCurrentId());
|
|
11982
12462
|
if (code !== engine.ErrorCode.SUCCESS) {
|
|
11983
12463
|
logger.error('getJoinedUserInfo error', code);
|
|
11984
12464
|
return { code: exports.RCRTCCode.SIGNAL_ROOM_CHANGE_IDENTITY_FAILED };
|
|
@@ -12000,33 +12480,6 @@ exports.RCKickReason = void 0;
|
|
|
12000
12480
|
RCKickReason[RCKickReason["OTHER_KICK"] = 2] = "OTHER_KICK";
|
|
12001
12481
|
})(exports.RCKickReason || (exports.RCKickReason = {}));
|
|
12002
12482
|
|
|
12003
|
-
/**
|
|
12004
|
-
* 获取 Microphone 列表
|
|
12005
|
-
*/
|
|
12006
|
-
const getMicrophones = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
12007
|
-
const mediaDivices = yield navigator.mediaDevices.enumerateDevices();
|
|
12008
|
-
return mediaDivices.filter(item => item.kind === 'audioinput');
|
|
12009
|
-
});
|
|
12010
|
-
/**
|
|
12011
|
-
* 获取摄像头设备列表
|
|
12012
|
-
*/
|
|
12013
|
-
const getCameras = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
12014
|
-
const mediaDevices = yield navigator.mediaDevices.enumerateDevices();
|
|
12015
|
-
return mediaDevices.filter(item => item.kind === 'videoinput');
|
|
12016
|
-
});
|
|
12017
|
-
/**
|
|
12018
|
-
* 获取扬声器设备列表
|
|
12019
|
-
*/
|
|
12020
|
-
const getSpeakers = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
12021
|
-
const mediaDevices = yield navigator.mediaDevices.enumerateDevices();
|
|
12022
|
-
return mediaDevices.filter(item => item.kind === 'audiooutput');
|
|
12023
|
-
});
|
|
12024
|
-
const device = {
|
|
12025
|
-
getCameras,
|
|
12026
|
-
getMicrophones,
|
|
12027
|
-
getSpeakers
|
|
12028
|
-
};
|
|
12029
|
-
|
|
12030
12483
|
/**
|
|
12031
12484
|
* RTC 插件生成器
|
|
12032
12485
|
* @public
|
|
@@ -12042,12 +12495,17 @@ const installer = {
|
|
|
12042
12495
|
logger.error('Please use the https protocol or use `http://localhost` to open the page!');
|
|
12043
12496
|
return false;
|
|
12044
12497
|
}
|
|
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"}'.`);
|
|
12501
|
+
return false;
|
|
12502
|
+
}
|
|
12045
12503
|
return true;
|
|
12046
12504
|
},
|
|
12047
12505
|
setup(context, runtime, options = {}) {
|
|
12048
12506
|
logger.setLogLevel(options.logLevel);
|
|
12049
12507
|
logger.setLogStdout(options.logStdout);
|
|
12050
|
-
logger.warn(`RCRTC Version: ${"5.
|
|
12508
|
+
logger.warn(`RCRTC Version: ${"5.2.2-alpha.1"}, Commit: ${"de4f9bc28bbee35d2d5f206a68144c89c098573f"}`);
|
|
12051
12509
|
logger.warn(`browserInfo.browser -> ${browserInfo.browser}`);
|
|
12052
12510
|
logger.warn(`browserInfo.supportsUnifiedPlan -> ${browserInfo.supportsUnifiedPlan}`);
|
|
12053
12511
|
logger.warn(`browserInfo.version -> ${browserInfo.version}`);
|