李勇

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,12 +83,7 @@ class EverSocket extends Emiter {
loger.warn('发送到MCU的数据文件超过10k-->byteLength->'+len,"type:"+type);
return;
}
this.sendToMcuList.push("c2s_"+EngineUtils.creatTimestampStr()+"_"+len+"_"+type);
if(this.sendToMcuList.length>80){
loger.log("发送到MCU数据统计->",this.sendToMcuList);
this.sendToMcuList=[];
}
this.send2mcu(len,type);
}
this.websocket.send(data);
} else {
... ... @@ -96,6 +91,32 @@ class EverSocket extends Emiter {
}
}
//统计发送到MCU的数据
/*
* len 长度
* type 类型
* */
send2mcu(len,type){
this.sendToMcuList.push(""+len+":"+type);
if(this.sendToMcuList.length>=50){
loger.log("发送到MCU数据统计->",this.sendToMcuList);
this.sendToMcuList=[];
}
}
//统计收到MCU的数据
/*
* len 长度
* type 类型
* */
mcu2client(len,type){
this.receiveFromMcuList.push(""+len+":"+type);
if(this.receiveFromMcuList.length>50){
loger.log("收到MCU数据统计->",this.receiveFromMcuList);
this.receiveFromMcuList=[];
}
}
_setConnected(isConn = true) {
this._connected = isConn;
if (this._connected) {
... ... @@ -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,7 +1240,10 @@ class RecordPlayBackParse extends Emiter {
}
}
this.videoPublishMessages.push(videoChannelInfo);
//****1310721是屏幕共享和外部流 不需要匹配*****
if(parseInt(videoChannelInfo.channelId)<1310721){
this.videoPublishMessages.push(videoChannelInfo);
}
}
this.mediaChannleList[videoChannelInfo.channelId][timestamp] = {
parseData: videoChannelInfo,
... ...
... ... @@ -28,393 +28,385 @@ import RecordPlayBackParse from 'RecordPlayBackParse';
const loger = Loger.getLoger('Ape');
export default class Ape extends Emiter {
constructor(session_id,
session_name,
session_tag) {
super();
this._session_id = session_id;
this._channel_id = session_id; // session_id === channel_id
this._session_name = session_name;
this._session_tag = session_tag;
this._session_channels = {};
this._adapter_pdu = new pdu['RCAdapterPdu'];
this._classInfo = null;
this._rCArrayBufferUtil = ArrayBufferUtil;
this._apeDelayed = true;
this._apeDelayedMsgs = [];
this._apeDelayedTimer = 0;
//Ape 通用消息处理
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CHANNEL_JOIN_RESPONSE, this._joinChannelHandler.bind(this));
this.on(pdu.RCPDU_REG_ADAPTER, this._pduMessageHandler.bind(this));
//先收到onJoinSessionHandlerSuccess 后收到 onJoinChannelHandlerSuccess
// 监听底层MCU课堂
this.mcu = McuObj;
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
//录制回放
this.recordPlayBackParse = RecordPlayBackParse;
this.recordPlayBackParse.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this));
this.recordPlayBackParse.registerApe(this);
constructor(session_id,
session_name,
session_tag) {
super();
this._session_id = session_id;
this._channel_id = session_id; // session_id === channel_id
this._session_name = session_name;
this._session_tag = session_tag;
this._session_channels = {};
this._adapter_pdu = new pdu['RCAdapterPdu'];
this._classInfo = null;
this._rCArrayBufferUtil = ArrayBufferUtil;
this._apeDelayed = true;
this._apeDelayedMsgs = [];
this._apeDelayedTimer = 0;
//Ape 通用消息处理
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CHANNEL_JOIN_RESPONSE, this._joinChannelHandler.bind(this));
this.on(pdu.RCPDU_REG_ADAPTER, this._pduMessageHandler.bind(this));
//先收到onJoinSessionHandlerSuccess 后收到 onJoinChannelHandlerSuccess
// 监听底层MCU课堂
this.mcu = McuObj;
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
//录制回放
this.recordPlayBackParse = RecordPlayBackParse;
this.recordPlayBackParse.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this));
this.recordPlayBackParse.registerApe(this);
}
regResponsePduHandler() {
}
//停止APE一切操作
stopApe() {
// loger.log("stopApe==============================");
}
// 消息处理
_pduMessageHandler(regBuffer, _seekTime) {
let seekTime = _seekTime || 0;//这个只有在录制回放的时候才有
this._pduRegAdapterHandler(regBuffer, seekTime);
}
// 数据同步处理
_pduRegAdapterHandler(regBuffer, seekTime) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
//console.log("RCAdapterPdu数据同步处理",regPdu);
//loger.log(this._session_name + '数据同步消息');
//loger.log(this._session_name + '数据同步消息.同步条数', regItemSize,"seekTime->",seekTime);
for (var i = 0; i < regItemSize; ++i) {
let regItem = regItems[i];
let regItemType = regItem.type;
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);
this.regResponsePduHandler(regResponsePdu);
}
// 只处理两种类型
continue;
}
//具体的数据包
let regUpdatedItem = pdu['RCRegistryUpdateObjPdu'].decode(regItemData);
let sub_type = regUpdatedItem.subType;
let object_id = regUpdatedItem.objId;
let user_data = regUpdatedItem.userData;
//loger.log('REG OBJECT EVENT ->', pdu.id2type(sub_type));
switch (sub_type) {
case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
//let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].decode(user_data);
//loger.log('RCPDU_REG_ROSTER_INSERT_PDU---->');
try{
let rosterInsertData = pdu['RCRegistryRosterInsertItemPdu'].decode(user_data);
let rosterInsertItems = rosterInsertData.items;
let rosterInsertItemsLen = rosterInsertItems.length;
for (let i = 0; i < rosterInsertItemsLen; ++i) {
let record = rosterInsertItems[i];
let recordId = record.item_id;
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);
this.rosterDelHandler(rosterDelData.nodeId);
break;
case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
let rosterUpdateItems = rosterUpdateData.items;
let rosterUpdateItemsLen = rosterUpdateItems.length;
for (let i = 0; i < rosterUpdateItemsLen; ++i) {
let node = rosterUpdateItems[i];
let nodeId = node.nodeId;
let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
this.rosterUpdateHandler(nodeId, nodeData);
}
break;
case pdu.RCPDU_REG_TABLE_INSERT_PDU:
let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
let tableInsertItems = tableInsertData.items;
let tableInsertItemsLen = tableInsertItems.length;
for (let i = 0; i < tableInsertItemsLen; ++i) {
let insertItem = tableInsertItems[i];
//loger.log("insertItem",insertItem);
this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
}
//文档数据数组内部自己处理数组
this.tableInsertApeHandler(tableInsertItems, seekTime);
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
//console.log("tableDeleteData",object_id,tableDeleteData);
this.tableDeleteHandler(object_id, tableDeleteData);
break;
case pdu.RCPDU_REG_TABLE_UPDATE_PDU:
let tableUpdateData = pdu['RCRegistryTableUpdateItemPdu'].decode(user_data);
let tableUpdateItems = tableUpdateData.items;
let tableUpdateItemsLen = tableUpdateItems.length;
//loger.log("RCRegistryTableUpdateItemPdu " + tableUpdateItemsLen);
//loger.log(tableUpdateData);
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData, seekTime);
}
//白板,文档数据数组内部自己处理数组
this.tableUpdateApeHandler(tableUpdateItems, seekTime);
break;
case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
case pdu.RCPDU_REG_QUEUE_INSERT_PDU:
loger.warn('REG QUEUE ARE IGNORED');
break;
}
}
}
regResponsePduHandler() {
rosterInsertHandler(recordId, recordData) {
// loger.warn(this._session_name + ' rosterInsertHandler 应有子类具体覆盖处理.');
}
}
rosterUpdateHandler(nodeId, nodeData) {
//loger.warn(this._session_name + ' rosterUpdateHandler 应有子类具体覆盖处理.');
}
//停止APE一切操作
stopApe() {
// loger.log("stopApe==============================");
}
rosterDelHandler(recordData) {
//loger.warn(this._session_name + ' rosterDelHandler 应有子类具体覆盖处理.');
}
// 消息处理
_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);
}
tableInsertHandler(tableId, record) {
//loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
// 数据同步处理
_pduRegAdapterHandler(regBuffer,seekTime) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
//console.log("RCAdapterPdu数据同步处理",regPdu);
//loger.log(this._session_name + '数据同步消息');
//loger.log(this._session_name + '数据同步消息.同步条数', regItemSize,"seekTime->",seekTime);
for (var i = 0; i < regItemSize; ++i) {
let regItem = regItems[i];
let regItemType = regItem.type;
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);
this.regResponsePduHandler(regResponsePdu);
}
// 只处理两种类型
continue;
}
tableUpdateHandler(ownerId, recordId, recordData, seekTime) {
//loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
//具体的数据包
let regUpdatedItem = pdu['RCRegistryUpdateObjPdu'].decode(regItemData);
let sub_type = regUpdatedItem.subType;
let object_id = regUpdatedItem.objId;
let user_data = regUpdatedItem.userData;
//loger.log('REG OBJECT EVENT ->', pdu.id2type(sub_type));
switch (sub_type) {
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);
let rosterInsertData = pdu['RCRegistryRosterInsertItemPdu'].decode(user_data);
let rosterInsertItems = rosterInsertData.items;
let rosterInsertItemsLen = rosterInsertItems.length;
for (let i = 0; i < rosterInsertItemsLen; ++i) {
let record = rosterInsertItems[i];
let recordId = record.item_id;
let recordData = pdu['RCNodeInfoRecordPdu'].decode(record.item_data);
this.rosterInsertHandler(recordId, recordData);
}
break;
case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
this.rosterDelHandler(rosterDelData.nodeId);
break;
case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
let rosterUpdateItems = rosterUpdateData.items;
let rosterUpdateItemsLen = rosterUpdateItems.length;
for (let i = 0; i < rosterUpdateItemsLen; ++i) {
let node = rosterUpdateItems[i];
let nodeId = node.nodeId;
let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
this.rosterUpdateHandler(nodeId, nodeData);
}
break;
case pdu.RCPDU_REG_TABLE_INSERT_PDU:
let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
let tableInsertItems = tableInsertData.items;
let tableInsertItemsLen = tableInsertItems.length;
for (let i = 0; i < tableInsertItemsLen; ++i) {
let insertItem = tableInsertItems[i];
//loger.log("insertItem",insertItem);
this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
}
//文档数据数组内部自己处理数组
this.tableInsertApeHandler(tableInsertItems,seekTime);
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
//console.log("tableDeleteData",object_id,tableDeleteData);
this.tableDeleteHandler(object_id, tableDeleteData);
break;
case pdu.RCPDU_REG_TABLE_UPDATE_PDU:
let tableUpdateData = pdu['RCRegistryTableUpdateItemPdu'].decode(user_data);
let tableUpdateItems = tableUpdateData.items;
let tableUpdateItemsLen = tableUpdateItems.length;
//loger.log("RCRegistryTableUpdateItemPdu " + tableUpdateItemsLen);
//loger.log(tableUpdateData);
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData,seekTime);
}
//白板,文档数据数组内部自己处理数组
this.tableUpdateApeHandler(tableUpdateItems,seekTime);
break;
case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
case pdu.RCPDU_REG_QUEUE_INSERT_PDU:
loger.warn('REG QUEUE ARE IGNORED');
break;
tableUpdateApeHandler(tableUpdateItems, seekTime) {
}
}
}
}
rosterInsertHandler(recordId, recordData) {
// loger.warn(this._session_name + ' rosterInsertHandler 应有子类具体覆盖处理.');
}
tableInsertApeHandler(tableInsertItems, seekTime) {
rosterUpdateHandler(nodeId, nodeData) {
//loger.warn(this._session_name + ' rosterUpdateHandler 应有子类具体覆盖处理.');
}
}
rosterDelHandler(recordData) {
//loger.warn(this._session_name + ' rosterDelHandler 应有子类具体覆盖处理.');
}
tableDeleteHandler(tableId, record) {
//loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
tableInsertHandler(tableId, record) {
//loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
onJoinChannelHandlerSuccess() {
//loger.warn(this._session_name + ' onJoinChannelHandlerSuccess 应有子类具体覆盖处理.');
}
tableUpdateHandler(ownerId, recordId, recordData,seekTime) {
//loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
tableUpdateApeHandler(tableUpdateItems,seekTime){
onJoinSessionHandlerSuccess() {
//loger.warn(this._session_name + ' onJoinSessionHandlerSuccess 应有子类具体覆盖处理.');
}
}
tableInsertApeHandler(tableInsertItems,seekTime){
//录制状态发生改变后ape模块数据更新
updaterRecordApeStatus(_data) {
loger.warn(this._session_name + 'updaterRecordApeStatus->应有子类具体覆盖处理.');
}
}
tableDeleteHandler(tableId, record) {
//loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
// 加入Session处理
_joinSessionHandler(data) {
//loger.log(this._session_name, ' -> 加入Session');
this.onJoinSessionHandlerSuccess();
}
onJoinChannelHandlerSuccess() {
//loger.warn(this._session_name + ' onJoinChannelHandlerSuccess 应有子类具体覆盖处理.');
// 加入Channel处理
_joinChannelHandler(data) {
let joinedChannel = pdu['RCChannelJoinResponsePdu'].decode(data);
if (joinedChannel.result === pdu.RET_SUCCESS) {
//loger.log(this._session_name, ' -> 加入Channel成功. ChannelId', joinedChannel.requestedChannelId);
this._session_channels[joinedChannel.requestedChannelId] = ApeConsts.CJS_JOINNED;
this.onJoinChannelHandlerSuccess();
} else {
loger.warn(this._session_name, ' -> 加入Channel失败.', joinedChannel);
}
onJoinSessionHandlerSuccess() {
//loger.warn(this._session_name + ' onJoinSessionHandlerSuccess 应有子类具体覆盖处理.');
}
// 依赖的课堂创建完毕 - 发起Ape加入
_mcuConferenceJoinSuccessHandler(_data) {
//loger.log('创建Ape->',
// 'SessionId',
// this._session_id,
// 'SessionName',
// this._session_name,
// 'SessionTag',
// this._session_tag);
// 课堂依赖底层课堂信息
//this._classInfo = classInfo;
this._classInfo = GlobalConfig.getClassInfo();
var joinSessionPdu = new pdu['RCSessionJoinRequestPdu'];
joinSessionPdu.id = this._session_id;
joinSessionPdu.name = this._session_name;
joinSessionPdu.tag = this._session_tag;
joinSessionPdu.sessionData = this._adapter_pdu.toArrayBuffer();
this.sendUniform(joinSessionPdu, true);
var joinChannelPdu = new pdu['RCChannelJoinRequestPdu'];
joinChannelPdu.initiator = this.mcu.classInfo.nodeId;
joinChannelPdu.channelId = this._session_id;
this.send(joinChannelPdu);
}
// 依赖的录制回放创建完毕 - 发起Ape加入
_joinRecordPlaybackSuccessHandler(_data) {
loger.log('录制回放->Ape已经创建完毕->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
}
// 注册Key对象
registerKey(id, name, tag, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_KEY;
// pack register key pdus
let registerKeyPdu = new pdu['RCRegistryRegisterKeyPdu'];
registerKeyPdu.id = id;
registerKeyPdu.name = name;
registerKeyPdu.tag = tag;
if (user_data.length) {
registerKeyPdu.userData = user_data;
}
//录制状态发生改变后ape模块数据更新
updaterRecordApeStatus(_data){
loger.warn(this._session_name + 'updaterRecordApeStatus->应有子类具体覆盖处理.');
adapterItemPdu.itemData = registerKeyPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
// 注册Object对象 等同于flash中的 RCRegistryOperator
registerObj(type, id, name, tag, owner, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_OBJ;
let registerObjPdu = new pdu['RCRegistryRegisterObjPdu'];
registerObjPdu.type = type;
registerObjPdu.objId = id;
registerObjPdu.name = name;
registerObjPdu.tag = tag;
if (owner) {
registerObjPdu.owner = owner;
}
// 加入Session处理
_joinSessionHandler(data) {
//loger.log(this._session_name, ' -> 加入Session');
this.onJoinSessionHandlerSuccess();
if (user_data.length) {
registerObjPdu.userData = user_data;
}
// 加入Channel处理
_joinChannelHandler(data) {
let joinedChannel = pdu['RCChannelJoinResponsePdu'].decode(data);
if (joinedChannel.result === pdu.RET_SUCCESS) {
//loger.log(this._session_name, ' -> 加入Channel成功. ChannelId', joinedChannel.requestedChannelId);
this._session_channels[joinedChannel.requestedChannelId] = ApeConsts.CJS_JOINNED;
this.onJoinChannelHandlerSuccess();
} else {
loger.warn(this._session_name, ' -> 加入Channel失败.', joinedChannel);
}
}
adapterItemPdu.itemData = registerObjPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
// 依赖的课堂创建完毕 - 发起Ape加入
_mcuConferenceJoinSuccessHandler(_data) {
//loger.log('创建Ape->',
// 'SessionId',
// this._session_id,
// 'SessionName',
// this._session_name,
// 'SessionTag',
// this._session_tag);
// 课堂依赖底层课堂信息
//this._classInfo = classInfo;
this._classInfo = GlobalConfig.getClassInfo();
var joinSessionPdu = new pdu['RCSessionJoinRequestPdu'];
joinSessionPdu.id = this._session_id;
joinSessionPdu.name = this._session_name;
joinSessionPdu.tag = this._session_tag;
joinSessionPdu.sessionData = this._adapter_pdu.toArrayBuffer();
this.sendUniform(joinSessionPdu, true);
var joinChannelPdu = new pdu['RCChannelJoinRequestPdu'];
joinChannelPdu.initiator = this.mcu.classInfo.nodeId;
joinChannelPdu.channelId = this._session_id;
this.send(joinChannelPdu);
send(appPdu) {
//loger.log('Ape发送数据NORMAL PDU');
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
// 依赖的录制回放创建完毕 - 发起Ape加入
_joinRecordPlaybackSuccessHandler(_data) {
loger.log('录制回放->Ape已经创建完毕->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
if (!this._classInfo) {
loger.warn('Ape发送数据NORMAL PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
let normalPdu = pdu.create_normal_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
this._channel_id,
true,
true,
PduConsts.DP_TOP,
this._classInfo.topNodeID,
PduConsts.SEG_ONCE
);
normalPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(normalPdu);
}
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
// 注册Key对象
registerKey(id, name, tag, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_KEY;
// pack register key pdus
let registerKeyPdu = new pdu['RCRegistryRegisterKeyPdu'];
registerKeyPdu.id = id;
registerKeyPdu.name = name;
registerKeyPdu.tag = tag;
if (user_data.length) {
registerKeyPdu.userData = user_data;
}
adapterItemPdu.itemData = registerKeyPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
// 注册Object对象 等同于flash中的 RCRegistryOperator
registerObj(type, id, name, tag, owner, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_OBJ;
let registerObjPdu = new pdu['RCRegistryRegisterObjPdu'];
registerObjPdu.type = type;
registerObjPdu.objId = id;
registerObjPdu.name = name;
registerObjPdu.tag = tag;
if (owner) {
registerObjPdu.owner = owner;
}
if (user_data.length) {
registerObjPdu.userData = user_data;
}
adapterItemPdu.itemData = registerObjPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
if (!this._classInfo) {
loger.warn('Ape发送数据UNIFORM PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
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){
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
if(!this._classInfo){
loger.warn('Ape发送数据NORMAL PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
let normalPdu = pdu.create_normal_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
this._channel_id,
true,
true,
PduConsts.DP_TOP,
this._classInfo.topNodeID,
PduConsts.SEG_ONCE
);
normalPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(normalPdu);
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
top ? this._classInfo.topNodeID : (appPdu.peer || 0),
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
if (this.mcu) {
this.mcu.send(uniformPdu);
} else {
loger.warn('MCU为空->无法发送消息', uniformPdu);
}
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
if(!this._classInfo){
loger.warn('Ape发送数据UNIFORM PDU->失败->ape课堂数据无效->', this._classInfo);
return;
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
top ? this._classInfo.topNodeID : (appPdu.peer || 0),
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
if(this.mcu){
this.mcu.send(uniformPdu);
}else {
loger.warn('MCU为空->无法发送消息',uniformPdu);
}
}
sendChatUniform(appPdu, top) {
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if (!this.mcu || !this.mcu.connected || GlobalConfig.classExit) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
sendChatUniform(appPdu, top) {
//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._classInfo){
loger.warn("课堂数据还未获取,不能发送消息");
return;
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
0,//flash中这个值设置为0
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
//loger.log('Ape发送数据UNIFORM PDU',uniformPdu);
// Mcu发送
this.mcu.send(uniformPdu);
if (!this._classInfo) {
loger.warn("课堂数据还未获取,不能发送消息");
return;
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
0,//flash中这个值设置为0
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
//loger.log('Ape发送数据UNIFORM PDU',uniformPdu);
// Mcu发送
this.mcu.send(uniformPdu);
}
}
... ...
... ... @@ -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,8 +58,11 @@ class ConferApe extends Ape {
//加入课堂
_joinSessionHandler(_data) {
//let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let nodeInfoRecordPdu = this.getNodeInfo();
if(this.isSendInsterRoster){
loger.warn("已经发送过insertRoster,不能再次发送");
return
}
let nodeInfoRecordPdu = this.getNodeInfo();
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
userDataPdu.qq = '';
... ... @@ -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);
}
this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
this.emitRosterChange();
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,7 +1051,10 @@ class ConferApe extends Ape {
loger.log("人员更新信息->", newNodeData);
}
}
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
if(!GlobalConfig.isH5){
this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
}
}
}
... ... @@ -1105,29 +1121,33 @@ class ConferApe extends Ape {
this.rosterLen = Object.keys(this.rosters).length;
GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
this.emitRosterChange();
this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId, "rosterLen": this.rosterLen});
//当前人员列表中抽一个人来检查离开人员是否占用频道
for (let key in this.rosters) {
let randNodeId = parseInt(key);
//判断是否是自己就处理以下操作
if (randNodeId == GlobalConfig.nodeId) {
loger.log("检查离开的人员是否占用channel");
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": nodeId, "rosterLen": this.rosterLen});
//如果离开的人员是老师,需要暂停当前的课堂
if (user && user.role == ApeConsts.NR_HOST) {
this.pauseClass();
if(!GlobalConfig.isH5) {
this.emitRosterChange();
this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId, "rosterLen": this.rosterLen});
//当前人员列表中抽一个人来检查离开人员是否占用频道
for (let key in this.rosters) {
let randNodeId = parseInt(key);
//判断是否是自己就处理以下操作
if (randNodeId == GlobalConfig.nodeId) {
loger.log("检查离开的人员是否占用channel");
this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": nodeId, "rosterLen": this.rosterLen});
//如果离开的人员是老师,需要暂停当前的课堂
if (user && user.role == ApeConsts.NR_HOST) {
this.pauseClass();
}
}
return;
}
return;
}
}
}
//广播当前的人数
emitRosterChange() {
this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
if(!GlobalConfig.isH5){
this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
}
}
///////数据的封包和解包/////////////////////////////////////////
... ... @@ -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) {
... ...