李勇
6419d964 1 parent 6ba26c4e webRtc-dev ... 20170922-1 20171019-1 20171120-1w dev ly20170723-1 ly20170724-2 ly20170726-1 ly20170731-1 ly20170731-2 ly20170801-2 ly20170802-1 ly20170818-1 ly20170818-2 ly20170820-1 ly20170821-1 ly20170824-1 ly20170829-1 ly20170925-1 ly20170926-1 ly20170927-1 ly20170929-1 ly20171011-1 ly20171013-1 ly20171013-2 ly20171016-1 ly20171021-1 ly20171023-1 ly20171024-1w ly20171025-1w ly20171026-1w ly20171027-1w ly20171030-1 ly20171030-2w ly20171107-1 ly20171110-1w ly20171113-1w ly20171204-1w ly20171208-1w ly20171211-1w ly20171211-2w ly20171214-1w v2.38.13.20171216 v2.38.11.20171214 v2.38.3.201712011 v2.38.1.201712011 v2.36.11.20171204 v2.36.8.20171206 v2.36.4.20171201 v2.35.11.20171130 v2.34.16.20171128 v2.34.5.20171127 v2.33.6.20171123 v2.32.1.20171123 v2.31.12.20171122 v2.31.10.20171122 v2.30.5.20171117 v2.30.2.20171117 v2.29.5.20171114 v2.28.1.20171110 v2.27.11.20171109 v2.26.9.20171107 v2.26.6.20171103 v2.26.2.20171102 v2.25.7.20171031 v2.25.6.20171031 v2.25.0.20171030 v2.24.2.20171030 v2.23.0.20171030 v2.22.7.20171026 v2.20.5.20171023 v2.20.0.20171021 v2.19.8.20171020 v2.18.14.20171020 v2.18.10.20171019 v2.17.11.20171014 v2.16.8.20171012 v2.16.5.20171012 v2.15.5.20171001 v2.15.3.20170929 v2.14.5.20170927 v2.13.5.20170927 v2.12.14.20170927 v2.12.8.20170926 v2.12.6.20170925 v2.11.13.20170925 v2.10.7.20170921 v2.10.6.20170921 v2.10.5.20170920 v2.10.4.20170920 v2.9.3.20170919 v2.8.17.20170918 v2.8.8.20170917 v2.8.2.20170916 v2.6.2.20170915 v2.5.12.20170915 v2.5.6.20170914 v2.5.5.20170914 v2.4.4.20170908 v2.4.2.20170908 v2.4.0.20170907 v2.3.6.20170907 v2.2.16.20170905 v2.1.22.20170904 v1.84.0.20170912 v1.83.2.20170831 v1.82.11.20170829 v1.81.19.20170828 v1.80.2.20170824 v1.79.6.20170822 v1.79.5.20170821 v1.79.4.20170821 v1.79.3.20170821 v1.78.4.20170820 v1.77.4.20170819 v1.76.2.20170818 v1.75.0.20170815 v1.74.0.20170814 v1.73.2.20170814 v1.73.1.20170814 v1.71.0.20170813 v1.70.5.20170812 v1.68.2.20170812 v1.66.1.20170809 v1.65.25.20170808 v1.65.24.20170806 v1.63.1.20170731 v1.62.3.20170731 v1.61.0.20170729 v1.60.0.20170729 v1.59.0.20170729 v1.58.0.20170729 v1.57.0.20170727 v1.56.1.20170727 v1.56.0.20170727 v1.52.1.20170726 v1.51.0.20170724 v1.50.7.20170724 v1.49.1.20170724

1.增加聊天模块支持图片消息;2.增加踢人接口;3.修改CDN地址和m3u8地址拼接规则

... ... @@ -35,7 +35,7 @@ import QuestionApe from 'apes/QuestionApe';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = { "version": "v1.48.2.20170723", "author": "www.3mang.com" };
let _sdkInfo = { "version": "v1.49.1.20170724", "author": "www.3mang.com" };
//APE
let _sass;
... ... @@ -164,7 +164,9 @@ export default class MessageEntrance extends Emiter {
this.controlHandUpStatus = this._controlHandUpStatus.bind(this); //控制别人的举手状态
this.controlSilenceStatus = this._controlSilenceStatus.bind(this); //改变禁言状态
this.sceneTableChange = this._sceneTableChange.bind(this); //控制别人的举手状态
this.sceneTableChange = this._sceneTableChange.bind(this); //切换模块显示
this.kickOutRosterFormNodeId= this._kickOutRosterFormNodeId.bind(this); //把指定nodeId的人踢出课堂
//录制回放
this.initRecordPlayback = this._initRecordPlayback.bind(this);
... ... @@ -433,7 +435,8 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.portal = _param.portal;
GlobalConfig.isH5=_param.isH5||false;//外部传入的参数,是否是H5
if(GlobalConfig.isH5==true){
GlobalConfig.platform = 3;//3是H5
GlobalConfig.platform = "H5";
GlobalConfig.deviceType=3//3是H5
loger.warn("设备类型是H5");
}
//GlobalConfig.userId = _param.userId || "0";
... ... @@ -1054,6 +1057,17 @@ export default class MessageEntrance extends Emiter {
}
}
//将指定nodeId的人踢出课堂
_kickOutRosterFormNodeId(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return { "code": ApeConsts.RETURN_FAILED, "data": "" };
}
if (_confer_ape) {
_confer_ape.kickOutRosterFormNodeId(_param);
}
}
// 禁言控制
_controlSilenceStatus(_param) {
if (!_mcu.connected) {
... ... @@ -1244,7 +1258,8 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.MS_PLAY_HLS_IP = ipItem; //ip包含了端口
GlobalConfig.MS_PLAY_HLS_PORT = "";
loger.log('videoCDNAddr>初始->MSHls', GlobalConfig.MS_PLAY_HLS_IP);
} else if (ipItem.indexOf('rtmppull') >= 0) {
}
if (ipItem.indexOf('rtmppull')>= 0) {
//直播的时候rtmp拉流地址
GlobalConfig.MS_PLAY_RTMP_IP = ipItem; //ip包含了端口
GlobalConfig.MS_PLAY_RTMP_PORT = '';
... ... @@ -1838,12 +1853,12 @@ export default class MessageEntrance extends Emiter {
//音乐共享模块加入频道成功,同步到MCU服务器上的数据
musicShareApeJoinChannelSuccess() {
loger.log("伴音MUSIC模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.sharedMusicList.length);
console.log("伴音MUSIC模块共享模数据->", GlobalConfig.sharedMusicList);
loger.log("伴音MUSIC模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.musicListPrepare.length);
console.log("伴音MUSIC模块共享模数据->", GlobalConfig.musicListPrepare);
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if (GlobalConfig.isHost && GlobalConfig.sharedMusicList.length > 0) {
for (let i = 0; i < GlobalConfig.sharedMusicList.length; i++) {
let value = GlobalConfig.sharedMusicList[i];
if (GlobalConfig.isHost && GlobalConfig.musicListPrepare.length > 0) {
for (let i = 0; i < GlobalConfig.musicListPrepare.length; i++) {
let value = GlobalConfig.musicListPrepare[i];
if (value) {
let paramInfo = {
"status": 0,
... ...
... ... @@ -24,6 +24,7 @@ ApeConsts.CLASS_PAUSING = "class.update"; //更新当前的状态信息
ApeConsts.CLASS_ACTION_CLOSE_ALL = 1; //所有人关闭课堂
ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE = 2; //更改用户的举手状态
ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE = 3; //更改用户的禁言状态
ApeConsts.CLASS_ACTION_KICK_OUT_ROSTER=4; //指定的人踢出课堂
//课堂类型 1:1v1(2路流) 2:直播(1路流) 3:小班课(可以多路流)
ApeConsts.CLASS_TYPE_1 = 1; // 互动课堂,通过MS转发音视频,不能进行H5观看 1v1(2路流)
... ...
... ... @@ -58,6 +58,7 @@ class ChatApe extends Ape {
chatSendPdu.initiator = this._classInfo.nodeId;//发起人
chatSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
chatSendPdu.msgType=parseInt(_messageInfo.msgType)||0;
chatSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
chatSendPdu.fromName = this._rCArrayBufferUtil.strToUint8Array("h5" + this._classInfo.userName);
chatSendPdu.fromRole = this._classInfo.userRole;// classRole已经废弃
... ...
... ... @@ -56,42 +56,43 @@ class ConferApe extends Ape {
//加入课堂
_joinSessionHandler(_data) {
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let nodeInfoRecordPdu = this.getNodeInfo();
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let nodeInfoRecordPdu = this.getNodeInfo();
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
userDataPdu.qq = '';
userDataPdu.skype = '';
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
userDataPdu.qq = '';
userDataPdu.skype = '';
nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; //设备类型
nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; //设备类型
loger.log('开始加入->', nodeInfoRecordPdu);
loger.log('开始加入->', nodeInfoRecordPdu);
let item = new pdu['RCRegistryRosterItemPdu'];
item.nodeId = nodeInfoRecordPdu.nodeId;
item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
let item = new pdu['RCRegistryRosterItemPdu'];
item.nodeId = nodeInfoRecordPdu.nodeId;
item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
rosterUpdateItem.items.push(item);
let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
rosterUpdateItem.items.push(item);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
updateObjPdu.subType = rosterUpdateItem.type;
updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
updateObjPdu.subType = rosterUpdateItem.type;
updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
this.sendUniform(adapterPdu, true);
}
//获取角色信息
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
this.sendUniform(adapterPdu, true);
}
//获取角色信息
getNodeInfo() {
let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
nodeInfoRecordPdu.nodeId = GlobalConfig.nodeId;
... ... @@ -225,7 +226,7 @@ class ConferApe extends Ape {
sendConferRecordMsg(_param) {
if (!this.mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return { "code": ApeConsts.RETURN_FAILED, "data": "已经断开连接" };
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (_param == null) {
loger.warn("控制录制状的消息发送失败,参数错误", _param);
... ... @@ -269,7 +270,7 @@ class ConferApe extends Ape {
//如果是host
if (GlobalConfig.isHost) {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({ "recordStatus": true });
this.sendConferRecordMsg({"recordStatus": true});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
}
... ... @@ -282,14 +283,14 @@ class ConferApe extends Ape {
//强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
if (GlobalConfig.recordStatus) {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({ "recordStatus": false });
this.sendConferRecordMsg({"recordStatus": false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
}
} else {
//身份是host,并且当前正在录制中
if (GlobalConfig.isHost && GlobalConfig.recordStatus) {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({ "recordStatus": false });
this.sendConferRecordMsg({"recordStatus": false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
}
}
... ... @@ -336,7 +337,7 @@ class ConferApe extends Ape {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.stopRecord();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({ "actionType": 0, isStopAllPublishMedia: true });
this.sendUpdaterClassStatusInfo({"actionType": 0, isStopAllPublishMedia: true});
loger.log('restorClass');
}
... ... @@ -378,7 +379,7 @@ class ConferApe extends Ape {
//课堂状态改变
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步课堂状态
this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: true });
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: true});
//开始计时
this.startTimerCounter();
... ... @@ -398,23 +399,24 @@ class ConferApe extends Ape {
this.stopRecord();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE, _param);
this.sendUpdaterClassStatusInfo({ "actionType": 2, isStopAllPublishMedia: true });
this.sendUpdaterClassStatusInfo({"actionType": 2, isStopAllPublishMedia: true});
this.stopTimerCounter();
}
//关闭课堂
closeClass(_param) {
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
loger.warn('还没有开始,不能点关闭');
return;
}
this.stopTimerCounter();
this.restorClass();
//把所有人都踢出课堂
this.sendConferMsg({ "to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL });
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
loger.warn('还没有开始,不能点关闭');
return;
}
//更新设备信息
this.stopTimerCounter();
this.restorClass();
//把所有人都踢出课堂
this.sendConferMsg({"to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
}
//更新设备信息
updateDeviceInfo(_param) {
loger.log('更新用户的设备信息->', _param);
this.updateUserInfo();
... ... @@ -434,7 +436,7 @@ class ConferApe extends Ape {
GlobalConfig.silenceUsers[_param.userId || _param.nodeId] = _param;
}
this.sendUpdaterClassStatusInfo({ silenceUsers: GlobalConfig.silenceUsers });
this.sendUpdaterClassStatusInfo({silenceUsers: GlobalConfig.silenceUsers});
}
changeSilenceStatus(_param) {
... ... @@ -443,6 +445,24 @@ class ConferApe extends Ape {
this.updateUserInfo();
}
//将指定nodeId的人踢出课堂
kickOutRosterFormNodeId(_param) {
if(GlobalConfig.isNormal){
loger.warn("普通身份没有踢人的权限");
return;
}
if (_param && _param.nodeId) {
this.sendConferMsg({
"to": parseInt(_param.nodeId),
"message": "" + _param.nodeId + "踢出课堂",
"actionType": ApeConsts.CLASS_ACTION_KICK_OUT_ROSTER
});
} else {
loger.warn("踢人失败-参数无效")
console.log(_param);
}
}
//控制举手状态
controlHandUpStatus(_param) {
//控制用户的举手状态
... ... @@ -456,21 +476,26 @@ class ConferApe extends Ape {
if (_param && _param.isHandUp == true) {
msgObj.isHandUp = true;
}
this.sendConferMsg({ "to": _param.nodeId, "message": JSON.stringify(msgObj), "actionType": ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE });
this.sendConferMsg({
"to": _param.nodeId,
"message": JSON.stringify(msgObj),
"actionType": ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE
});
}
//切换举手状态
changeHandUpStatus(_param) {
loger.log('切换举手状态->', _param);
if (_param && _param.isHandUp == true) {
//举手
GlobalConfig.handUpTime = EngineUtils.creatTimestamp();
} else {
GlobalConfig.handUpTime = 0; //默认0是没有举手的状态(大于0就是举手)
}
this.updateUserInfo();
loger.log('切换举手状态->', _param);
if (_param && _param.isHandUp == true) {
//举手
GlobalConfig.handUpTime = EngineUtils.creatTimestamp();
} else {
GlobalConfig.handUpTime = 0; //默认0是没有举手的状态(大于0就是举手)
}
//课堂的场景模块发送改变
this.updateUserInfo();
}
//课堂的场景模块发送改变
sceneTableChange(_param) {
if (GlobalConfig.isRecordPlayBack) {
return;
... ... @@ -483,7 +508,7 @@ class ConferApe extends Ape {
//保存数据到Sass
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: false });
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
}
}
... ... @@ -550,8 +575,7 @@ class ConferApe extends Ape {
//如果是host ,开始录制
this.startRecord();
} else if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT &&
GlobalConfig.isHost && GlobalConfig.isAutoStartClass &&
!GlobalConfig.isRecordPlayBack) {
GlobalConfig.isHost && GlobalConfig.isAutoStartClass && !GlobalConfig.isRecordPlayBack) {
//自动开始上课的4个条件
//1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
... ... @@ -593,7 +617,7 @@ class ConferApe extends Ape {
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
}
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER, { "classTimestamp": GlobalConfig.classTimestamp });
this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
//如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
... ... @@ -602,7 +626,7 @@ class ConferApe extends Ape {
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步消息给其他人
this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: false });
this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
}
}
... ... @@ -619,9 +643,9 @@ class ConferApe extends Ape {
//处理课堂更新的信息
if (model && model.classStatusInfo) {
try{
model.classStatusInfo.silenceUsers=JSON.parse( model.classStatusInfo.silenceUsers);
}catch (err){
try {
model.classStatusInfo.silenceUsers = JSON.parse(model.classStatusInfo.silenceUsers);
} catch (err) {
}
... ... @@ -670,48 +694,55 @@ class ConferApe extends Ape {
chatMsg.toNodeID = chatReceivePdu.peer;
chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2);
chatMsg.actionType = chatReceivePdu.actionType;
loger.log("conferMsgComingHandler", chatMsg); //{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}
loger.log("课堂控制消息", chatMsg); //{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}
switch (chatMsg.actionType) {
case ApeConsts.CLASS_ACTION_CLOSE_ALL:
loger.log(chatMsg.message);
//收到课堂关闭,所有人都退出,执行自己关闭的流程
this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
break;
case ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE:
console.log('chatMsg', chatMsg);
let msgObj = null;
try {
msgObj = JSON.parse(chatMsg.message);
if (msgObj && msgObj.nodeId == GlobalConfig.nodeId) {
this.changeHandUpStatus(msgObj);
case ApeConsts.CLASS_ACTION_CLOSE_ALL:
loger.log(chatMsg.message);
//收到课堂关闭,所有人都退出,执行自己关闭的流程
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1});
break;
case ApeConsts.CLASS_ACTION_KICK_OUT_ROSTER:
if (chatMsg.toNodeID == GlobalConfig.nodeId) {
//自己被踢出课堂
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 2});
}
} catch (err) {
loger.warn('chatMsg->JSON数据解析失败');
}
break;
case ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE:
let silenceMsg = null;
try {
silenceMsg = JSON.parse(chatMsg.message);
if (silenceMsg && silenceMsg.nodeId == GlobalConfig.nodeId) {
this.changeSilenceStatus(silenceMsg);
break;
case ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE:
//console.log('chatMsg', chatMsg);
let msgObj = null;
try {
msgObj = JSON.parse(chatMsg.message);
if (msgObj && msgObj.nodeId == GlobalConfig.nodeId) {
this.changeHandUpStatus(msgObj);
}
} catch (err) {
loger.warn('chatMsg->JSON数据解析失败');
}
} catch (err) {
loger.warn('chatMsg->JSON数据解析失败');
}
break;
default:
break;
break;
case ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE:
let silenceMsg = null;
try {
silenceMsg = JSON.parse(chatMsg.message);
if (silenceMsg && silenceMsg.nodeId == GlobalConfig.nodeId) {
this.changeSilenceStatus(silenceMsg);
}
} catch (err) {
loger.warn('chatMsg->JSON数据解析失败');
}
break;
default:
break;
}
}
//-------------第三方消息------------------------------
//收到父级页面的消息,需要广播发送出去
onThirdReciveParentMessage(_msg) {
loger.log('收到页面的消息->广播给其他模块->', _msg);
this.sendThirdBroadcastData({ to: 0, message: _msg });
}
//发送第三方广播消息
loger.log('收到页面的消息->广播给其他模块->', _msg);
this.sendThirdBroadcastData({to: 0, message: _msg});
}
//发送第三方广播消息
sendThirdBroadcastData(_param) {
loger.log("发送第三方广播消息->", _param);
if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {
... ... @@ -783,63 +814,64 @@ class ConferApe extends Ape {
//更新人员列表数据
rosterUpdateHandler(nodeId, nodeData) {
nodeData.userRole = ApeConsts.userTypes[nodeData.role];
//如果是自己的信息,不处理跳过
if (nodeId == GlobalConfig.nodeId) {
//loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:
// 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
let rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber=rosterLen;//记录当前的总人数
if (rosterLen < 1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
loger.warn("当前课堂没有老师->暂停课堂");
this.pauseClass({ isForce: true });
this.stopRecord(true);
}
//处理用户信息
this.unPackRosterInfo(nodeId, nodeData);
return;
nodeData.userRole = ApeConsts.userTypes[nodeData.role];
//如果是自己的信息,不处理跳过
if (nodeId == GlobalConfig.nodeId) {
//loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:
// 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
let rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = rosterLen;//记录当前的总人数
if (rosterLen < 1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
loger.warn("当前课堂没有老师->暂停课堂");
this.pauseClass({isForce: true});
this.stopRecord(true);
}
//loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//新加入的人员不是自己
//1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉
//2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大
if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") {
loger.log("异地登陆->userId->", GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
}
}
/*if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {
this.kickOutRoster();
return;
}else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){
loger.log("异地登陆->userId->",GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});
}
}*/
//处理用户信息
this.unPackRosterInfo(nodeId, nodeData);
return;
}
//loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
//新加入的人员不是自己
//1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉
//2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大
if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") {
loger.log("异地登陆->userId->", GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1});
}
}
/*if (parseInt(nodeId) > GlobalConfig.nodeId) {
if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {
this.kickOutRoster();
return;
} else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {
this.kickOutRoster();
return;
}else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){
loger.log("异地登陆->userId->",GlobalConfig.userId);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});
}
}*/
//处理用户信息
this.unPackRosterInfo(nodeId, nodeData);
}
//处理用户信息
unPackRosterInfo(nodeId, nodeData) {
let rosterExists = this.rosters[nodeId];
this.rosters[nodeId] = nodeData;
... ... @@ -859,13 +891,13 @@ class ConferApe extends Ape {
}
if (!rosterExists) {
loger.log("人员加入->", newNodeData);
this._emit(MessageTypes.CLASS_INSERT_ROSTER, { "nodeId": nodeId, "nodeData": newNodeData });
this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
this.emitRosterChange();
} else {
//loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
loger.log("人员更新信息->", newNodeData);
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, { "nodeId": nodeId, "nodeData": newNodeData });
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
}
}
... ... @@ -873,46 +905,47 @@ class ConferApe extends Ape {
//踢出用户
kickOutRoster() {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_KICK_OUT);
this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1});
}
//视频模块发生更新,人员状态需要更新
updaterRosterStatus(_param) {
//loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);
//如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING && this.rosters[_param.fromNodeId] == null) {
loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, { "nodeId": _param.fromNodeId });
}
/* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
if(this.rosters[_param.fromNodeId] == null){
loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
GlobalConfig.openCamera=0;
}else {
GlobalConfig.openCamera=EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones=GlobalConfig.openCamera;
}
this.updateUserInfo();
}
}else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
GlobalConfig.openCamera=0;
GlobalConfig.openMicrophones=0;
this.updateUserInfo();
}
}*/
//loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);
//如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING && this.rosters[_param.fromNodeId] == null) {
loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//设备状态更新
/* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
if(this.rosters[_param.fromNodeId] == null){
loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
}
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
GlobalConfig.openCamera=0;
}else {
GlobalConfig.openCamera=EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones=GlobalConfig.openCamera;
}
this.updateUserInfo();
}
}else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
//如果音视频消息是自己的,需要设置麦克风和摄像头状态
if(_param.fromNodeId==GlobalConfig.nodeId){
GlobalConfig.openCamera=0;
GlobalConfig.openMicrophones=0;
this.updateUserInfo();
}
}*/
}
//设备状态更新
updaterUserDeviecStatusChange(_data) {
loger.log("音视频设备状态更新->", _data);
this.updateUserInfo();
... ... @@ -923,7 +956,7 @@ class ConferApe extends Ape {
if (GlobalConfig.nodeId == nodeId) {
loger.log("自己离开课堂");
// 自己退出
this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 0 });
this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 0});
} else {
let user = this.rosters[nodeId];
if (user) {
... ... @@ -931,7 +964,7 @@ class ConferApe extends Ape {
}
delete this.rosters[nodeId];
this.emitRosterChange();
this._emit(MessageTypes.CLASS_DELETE_ROSTER, { "nodeId": nodeId });
this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId});
//当前人员列表中抽一个人来检查离开人员是否占用频道
for (let key in this.rosters) {
... ... @@ -939,7 +972,7 @@ class ConferApe extends Ape {
//如果抽到的人是自己就处理以下操作
if (randNodeId == GlobalConfig.nodeId) {
loger.log(randNodeId, "有权限检查离开的人员是否占用channel");
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, { "nodeId": nodeId });
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": nodeId});
//如果离开的人员是老师,需要暂停当前的课堂
if (user && user.role == ApeConsts.NR_HOST) {
... ...
... ... @@ -47,7 +47,8 @@ class MediaModule {
path = "http://" + GlobalConfig.MS_PLAY_HLS_IP
+ port + "/live/"
+ _param.streamId
+ "/"+fileName;
+".m3u8";//新版的规则,不需要加playlist 20170724
//+ "/"+fileName;//
} else {
... ...
... ... @@ -718,6 +718,7 @@ message RCChatSendDataRequestPdu {
required bytes user_data = 4;
required string from_role = 5;
required bytes from_name = 6;
optional uint32 msgType = 7 [default =0];//当前消息类型,0是文字消息 1是图片消息
}
message RCDocSendDataModelPdu {
... ...