李勇

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 {
... ...