李勇

1.录制回放消息和视频匹配部分忽略屏幕共享的消息;2.处理直播模式时H5的消息处理

... ... @@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter {
super();
this.lastClassActiveTime=0;//最后一次课堂激活的时间戳
//sdk 信息
GlobalConfig.sdkVersion = "v2.31.1.20171120";
GlobalConfig.sdkVersion = "v2.31.10.20171122";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
console.log("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -644,7 +644,7 @@ export default class MessageEntrance extends Emiter {
//如果没有名字的时候需要随机生成
let randUserId =parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000);
let randUserId =parseInt(Math.random()*1000)+"_"+parseInt(Math.random()*1000)+"_"+parseInt(Math.random()*1000);
if (GlobalConfig.userRole == ApeConsts.host) {
randUserId = "T" + randUserId;
} else if (GlobalConfig.userRole == ApeConsts.assistant) {
... ... @@ -1051,6 +1051,13 @@ export default class MessageEntrance extends Emiter {
//开始MCU选点操作
_getFastestMcuServer(_callback) {
//不再做MCU http测速
if (_callback) {
_callback(null);
}
return;
//正常的测试流程
if (_ipManager) {
_ipManager.getFastestMcuServer(GlobalConfig.mcuListFinal, _callback);
} else {
... ... @@ -1184,7 +1191,7 @@ export default class MessageEntrance extends Emiter {
//判断是否需要获取加入音视频通话频道的channelKey
if (GlobalConfig.appCertificate) {
loger.log("加入视频通话模块->需要先获取channelKey")
//loger.log("加入视频通话模块->需要先获取channelKey")
//获取channelKey
_sass.getChannelKeyToken((_data)=> {
//{"code":200,"channelKey":"005AQAoAEQzQUQxNzFDOEQwOEU3OTVGMjlCMzZDRUZENTNGOTU0RDY4N0ZGMUEQANylukzO70ocgrNX9hlkNNWvpLBZ9buDAy/fuVkAAA==","uid":"751373669"}
... ... @@ -1194,7 +1201,7 @@ export default class MessageEntrance extends Emiter {
this._joinClassSuccessSeting();
})
} else {
loger.log("加入视频通话模块->不需要获取channelKey")
//loger.log("加入视频通话模块->不需要获取channelKey")
this._joinClassSuccessSeting();
}
}
... ... @@ -1283,7 +1290,7 @@ export default class MessageEntrance extends Emiter {
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
//主讲人和老师可以设置旁录
if (GlobalConfig.appId && !GlobalConfig.openFlash) {
if (GlobalConfig.appId && !GlobalConfig.openFlash&&GlobalConfig.deviceType!=GlobalConfig.deviceH5) {
//加入之前先设置旁录地址,老师和主讲人开启旁路
if (_webRtc && GlobalConfig.isTeachOrAssistant) {
let curTimestamp = new Date().getTime();
... ... @@ -2568,7 +2575,7 @@ export default class MessageEntrance extends Emiter {
docJoinChannelSuccess() {
let interval=new Date().getTime()-parseInt(this.lastClassActiveTime);
interval=interval/1000;
loger.log("最后一次记录的时间->"+this.lastClassActiveTime,"当前时间:"+new Date().getTime(),"间隔:"+interval+"秒");
//loger.log("最后一次记录的时间->"+this.lastClassActiveTime,"当前时间:"+new Date().getTime(),"间隔:"+interval+"秒");
loger.log("文档加入频道成功->isHost=", GlobalConfig.isHost, "当前总人数:", GlobalConfig.rosterNumber, "sassDoclength=", GlobalConfig.docListPrepare.length);
... ...
... ... @@ -83,16 +83,37 @@ class EverSocket extends Emiter {
loger.warn('发送到MCU的数据文件超过10k-->byteLength->'+len,"type:"+type);
return;
}
this.send2mcu(len,type);
}
this.websocket.send(data);
} else {
loger.warn('WebSocket未建立连接.消息忽略');
}
}
this.sendToMcuList.push("c2s_"+EngineUtils.creatTimestampStr()+"_"+len+"_"+type);
if(this.sendToMcuList.length>80){
//统计发送到MCU的数据
/*
* len 长度
* type 类型
* */
send2mcu(len,type){
this.sendToMcuList.push(""+len+":"+type);
if(this.sendToMcuList.length>=50){
loger.log("发送到MCU数据统计->",this.sendToMcuList);
this.sendToMcuList=[];
}
}
this.websocket.send(data);
} else {
loger.warn('WebSocket未建立连接.消息忽略');
//统计收到MCU的数据
/*
* len 长度
* type 类型
* */
mcu2client(len,type){
this.receiveFromMcuList.push(""+len+":"+type);
if(this.receiveFromMcuList.length>50){
loger.log("收到MCU数据统计->",this.receiveFromMcuList);
this.receiveFromMcuList=[];
}
}
... ... @@ -218,18 +239,17 @@ class EverSocket extends Emiter {
const bufferData = messageEvent.data;
//loger.log('RECEIVE-->byteLength->',bufferData.byteLength);
let len=bufferData.byteLength;
this.receiveFromMcuList.push("s2c_"+EngineUtils.creatTimestampStr()+"_"+len);
if(this.receiveFromMcuList.length>80){
loger.log("收到MCU数据统计->",this.receiveFromMcuList);
this.receiveFromMcuList=[];
}
if (len> 0) {
this._emit(EverSocket.MESSAGE, bufferData);
this.mcu2client(len,"消息");
}else {
this.mcu2client(0,"回应");
}
}
_sendPingHandler() {
if (this._connected) {
this.send2mcu(0,"心跳");
this.websocket.send(new ArrayBuffer);
} else {
this._reConnection();
... ...
... ... @@ -1240,8 +1240,11 @@ class RecordPlayBackParse extends Emiter {
}
}
//****1310721是屏幕共享和外部流 不需要匹配*****
if(parseInt(videoChannelInfo.channelId)<1310721){
this.videoPublishMessages.push(videoChannelInfo);
}
}
this.mediaChannleList[videoChannelInfo.channelId][timestamp] = {
parseData: videoChannelInfo,
byteData: data,
... ...
... ... @@ -73,24 +73,13 @@ export default class Ape extends Emiter {
}
// 消息处理
_pduMessageHandler(regBuffer,_seekTime) {
let seekTime=_seekTime||0;//这个只有在录制回放的时候才有
/* loger.warn('APE->收到消息处理->',GlobalConfig.mcuDelay,GlobalConfig.messageDelay);
//延迟处理消息(3个条件--->ape允许延迟&&客户端设置需要延迟&&Sass设置的延迟时间大于0)
if (this._apeDelayed&&GlobalConfig.messageDelay&&GlobalConfig.mcuDelay>0) {
loger.warn('延迟处理消息->',GlobalConfig.mcuDelay);
setTimeout(() => {
this._pduRegAdapterHandler(regBuffer,seekTime);
}, GlobalConfig.mcuDelay*1000);//mcuDelay单位是秒,这里需要换算为毫秒
return;
}
*/
//不延迟,立即处理
this._pduRegAdapterHandler(regBuffer,seekTime);
_pduMessageHandler(regBuffer, _seekTime) {
let seekTime = _seekTime || 0;//这个只有在录制回放的时候才有
this._pduRegAdapterHandler(regBuffer, seekTime);
}
// 数据同步处理
_pduRegAdapterHandler(regBuffer,seekTime) {
_pduRegAdapterHandler(regBuffer, seekTime) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
... ... @@ -103,7 +92,6 @@ export default class Ape extends Emiter {
let regItemData = regItem.itemData;
//根据数据包中的type处理数据是否同步
if (pdu.RCPDU_REG_UPDATE_OBJ !== regItemType) {
if (pdu.RCPDU_REG_RESPONSE_OBJ == regItemType) {
let regResponsePdu = pdu['RCRegistryResponseObjPdu'].decode(regItemData);
... ... @@ -124,7 +112,7 @@ export default class Ape extends Emiter {
case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
//let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].decode(user_data);
//loger.log('RCPDU_REG_ROSTER_INSERT_PDU---->');
console.log(user_data);
try{
let rosterInsertData = pdu['RCRegistryRosterInsertItemPdu'].decode(user_data);
let rosterInsertItems = rosterInsertData.items;
let rosterInsertItemsLen = rosterInsertItems.length;
... ... @@ -134,6 +122,9 @@ export default class Ape extends Emiter {
let recordData = pdu['RCNodeInfoRecordPdu'].decode(record.item_data);
this.rosterInsertHandler(recordId, recordData);
}
}catch (err){
console.log("RCPDU_REG_ROSTER_INSERT_PDU err",err)
}
break;
case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
... ... @@ -161,7 +152,7 @@ export default class Ape extends Emiter {
}
//文档数据数组内部自己处理数组
this.tableInsertApeHandler(tableInsertItems,seekTime);
this.tableInsertApeHandler(tableInsertItems, seekTime);
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
... ... @@ -178,11 +169,11 @@ export default class Ape extends Emiter {
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData,seekTime);
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData, seekTime);
}
//白板,文档数据数组内部自己处理数组
this.tableUpdateApeHandler(tableUpdateItems,seekTime);
this.tableUpdateApeHandler(tableUpdateItems, seekTime);
break;
case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
... ... @@ -210,15 +201,18 @@ export default class Ape extends Emiter {
//loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
tableUpdateHandler(ownerId, recordId, recordData,seekTime) {
tableUpdateHandler(ownerId, recordId, recordData, seekTime) {
//loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
tableUpdateApeHandler(tableUpdateItems,seekTime){
tableUpdateApeHandler(tableUpdateItems, seekTime) {
}
tableInsertApeHandler(tableInsertItems,seekTime){
tableInsertApeHandler(tableInsertItems, seekTime) {
}
tableDeleteHandler(tableId, record) {
//loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
... ... @@ -230,10 +224,12 @@ export default class Ape extends Emiter {
onJoinSessionHandlerSuccess() {
//loger.warn(this._session_name + ' onJoinSessionHandlerSuccess 应有子类具体覆盖处理.');
}
//录制状态发生改变后ape模块数据更新
updaterRecordApeStatus(_data){
updaterRecordApeStatus(_data) {
loger.warn(this._session_name + 'updaterRecordApeStatus->应有子类具体覆盖处理.');
}
// 加入Session处理
_joinSessionHandler(data) {
//loger.log(this._session_name, ' -> 加入Session');
... ... @@ -331,17 +327,11 @@ export default class Ape extends Emiter {
send(appPdu) {
//loger.log('Ape发送数据NORMAL PDU');
//console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
/* if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}*/
if(!this.mcu||!this.mcu.connected){
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
if(!this._classInfo){
if (!this._classInfo) {
loger.warn('Ape发送数据NORMAL PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
... ... @@ -364,7 +354,10 @@ export default class Ape extends Emiter {
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
if(!this._classInfo){
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
}
if (!this._classInfo) {
loger.warn('Ape发送数据UNIFORM PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
... ... @@ -381,22 +374,21 @@ export default class Ape extends Emiter {
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
if(this.mcu){
if (this.mcu) {
this.mcu.send(uniformPdu);
}else {
loger.warn('MCU为空->无法发送消息',uniformPdu);
} else {
loger.warn('MCU为空->无法发送消息', uniformPdu);
}
}
sendChatUniform(appPdu, top) {
//console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
if(!this._classInfo){
if (!this._classInfo) {
loger.warn("课堂数据还未获取,不能发送消息");
return;
}
... ...
... ... @@ -194,16 +194,16 @@ ApeConsts.MUSIC_SESSION_TAG = "mis-tag";
ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag";
ApeConsts.QUESTION_SESSION_TAG = "qst-tag";
ApeConsts.CONFERENCE_OBJ_ROSTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 1);
ApeConsts.CONFERENCE_OBJ_ROSTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 1);//720897
ApeConsts.CONFERENCE_OBJ_ROSTER_NAME = "node list";
ApeConsts.CONFERENCE_OBJ_ROSTER_TAG = "node list tag";
ApeConsts.CONFERENCE_OBJ_QUEUE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 2);
ApeConsts.CONFERENCE_OBJ_QUEUE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 2);//720898
ApeConsts.CONFERENCE_OBJ_QUEUE_NAME = "mic list";
ApeConsts.CONFERENCE_OBJ_QUEUE_TAG = "mic list tag";
// conference tab pages
ApeConsts.CONFERENCE_OBJ_TABLE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 3);
ApeConsts.CONFERENCE_OBJ_TABLE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 3);//720899
ApeConsts.CONFERENCE_OBJ_TABLE_NAME = "tabbar list";
ApeConsts.CONFERENCE_OBJ_TABLE_TAG = "tabbar list tag";
... ...
... ... @@ -23,6 +23,7 @@ class ConferApe extends Ape {
ApeConsts.CONFERENCE_SESSION_NAME,
ApeConsts.CONFERENCE_SESSION_TAG
);
this.isSendInsterRoster=false;//这个很重要,每次MCU连接成功之后只发一次
this.isLeave=false;//记录自己是否已经离开
this.rosters = {}; //用户列表
this.rosterLen = 0;//当前课堂人数
... ... @@ -57,7 +58,10 @@ class ConferApe extends Ape {
//加入课堂
_joinSessionHandler(_data) {
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
if(this.isSendInsterRoster){
loger.warn("已经发送过insertRoster,不能再次发送");
return
}
let nodeInfoRecordPdu = this.getNodeInfo();
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
... ... @@ -67,14 +71,12 @@ class ConferApe extends Ape {
nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; //设备类型
//loger.log('开始加入->', nodeInfoRecordPdu);
let item = new pdu['RCRegistryRosterItemPdu'];
item.nodeId = nodeInfoRecordPdu.nodeId;
item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
let rosterUpdateItem = new pdu['RCRegistryRosterInsertItemPdu'];
rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
rosterUpdateItem.type =pdu.RCPDU_REG_ROSTER_UPDATE_PDU;// pdu.RCPDU_REG_ROSTER_INSERT_PDU 暂时用update的类型,MCU第一次会当insert处理,目前insert解包出错
rosterUpdateItem.items.push(item);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
... ... @@ -91,6 +93,9 @@ class ConferApe extends Ape {
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
this.sendUniform(adapterPdu, true);
this.isSendInsterRoster=true;
loger.log('发送insertRoster->', nodeInfoRecordPdu);
}
//获取角色信息
... ... @@ -289,7 +294,7 @@ class ConferApe extends Ape {
loger.warn('目前已经是录制状态->当前课堂人数:' + this.rosterLen);
return false;
}
//如果是host或者当前课堂只有1个人
//如果是host或者当前课堂只有1个人,并且不是H5
if (this.checkHasRecordControl()) {
loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus, "当前人数:" + this.rosterLen);
//如果录制的文件名不存在,需要创建一个名字
... ... @@ -619,6 +624,9 @@ class ConferApe extends Ape {
sendUpdaterClassStatusInfo(_param) {
//{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流
//console.log('发送更新课堂信息->');
if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_ZHIBO&&GlobalConfig.isH5==true){
return;
}
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.log('发送更新课堂信息->参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -733,6 +741,10 @@ class ConferApe extends Ape {
//更新录制进行时间
GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
if (this.checkHasRecordControl()) {
if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_ZHIBO&&GlobalConfig.isH5==true){
return;
}
//以一定的时间间隔同步课堂内所有人的累积上课时间
if (GlobalConfig.recordTimestamp % GlobalConfig.updateRecordTimeDelay == 0) {
//保存数据到Sass
... ... @@ -945,7 +957,6 @@ class ConferApe extends Ape {
}
rosterInsertHandler(nodeId, nodeData) {
//loger.log("人员进入--->");
if (GlobalConfig.nodeId == nodeId) {
loger.log("人员进入课堂模块--->自己");
} else {
... ... @@ -1026,8 +1037,10 @@ class ConferApe extends Ape {
loger.log("人员加入->", newNodeData);
}
if(!GlobalConfig.isH5){
this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
this.emitRosterChange();
}
} else {
//loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
this.rosterLen = Object.keys(this.rosters).length;
... ... @@ -1038,8 +1051,11 @@ class ConferApe extends Ape {
loger.log("人员更新信息->", newNodeData);
}
}
if(!GlobalConfig.isH5){
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
}
}
}
//踢出用户(_param是新进入的人的信息)
... ... @@ -1105,6 +1121,7 @@ class ConferApe extends Ape {
this.rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
if(!GlobalConfig.isH5) {
this.emitRosterChange();
this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId, "rosterLen": this.rosterLen});
... ... @@ -1124,11 +1141,14 @@ class ConferApe extends Ape {
}
}
}
}
//广播当前的人数
emitRosterChange() {
if(!GlobalConfig.isH5){
this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
}
}
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
... ... @@ -1206,6 +1226,7 @@ class ConferApe extends Ape {
GlobalConfig.rosterNumber = this.rosterLen;
GlobalConfig.rosters = this.rosters;
this.isLeave=true;
this.isSendInsterRoster=false;
}
}
... ...
... ... @@ -406,6 +406,12 @@ class VideoApe extends Ape {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
clearTimeout(this.releaseTimeId);
if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_ZHIBO&&GlobalConfig.isH5){
//直播时H5不处理
return;
}
loger.log("释放nodeId占用的所有频道->", nodeId);
let openingChannelInfo = this.mediaModule.getOpeningMediaChannelForNodeId(nodeId);
if (openingChannelInfo.channelId == 0) {
... ... @@ -423,10 +429,6 @@ class VideoApe extends Ape {
this.sendTableUpdateHandler(channelInfo);
//递归检查,800毫秒之后执行
clearTimeout(this.releaseTimeId);
if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_ZHIBO&&GlobalConfig.isH5){
return;
}
this.releaseTimeId = setTimeout(function () {
loger.warn(nodeId, "检查频道是否占用");
this._releaseNodeIdAllChannel(nodeId);
... ... @@ -501,7 +503,10 @@ class VideoApe extends Ape {
//已经离开课堂就不再做处理
return;
}
if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_ZHIBO&&GlobalConfig.isH5){
//直播时H5不做处理
return;
}
let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
if (updateModelPdu == null) {
... ...