李勇

1.Sass增加保存开始录制信息的接口,储存录制文件名

2.增加录制的协议号和录制的pdu结构
3.会议模块增加开始录制和停止录制的接口
... ... @@ -65,6 +65,7 @@ export default class MessageEntrance extends Emiter {
_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息
_sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取会议的最全信息和历史保存的数据
_sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this));//保存会议状态信息
_sass.on(_sass.CLASS_SAVE_RECORD_INFO_SUCCESS, this._sassSaveClassRecordInfoSuccessHandler.bind(this));//保存会议录制信息
_sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this));//sass删除文档成功
// 底层MCU消息层
... ... @@ -80,6 +81,7 @@ export default class MessageEntrance extends Emiter {
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前会议人员离开
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER,this._onClassNonentityRoster.bind(this));//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START,this._onClassRecordStart.bind(this));//会议开始录制
_chat_ape = new ChatApe();
... ... @@ -117,6 +119,7 @@ export default class MessageEntrance extends Emiter {
this.sendPauseClass = this._sendPauseClass;
this.sendCloseClass = this._sendCloseClass;
//chatApe
this.sendChatMsg = this._sendChatMsg;
... ... @@ -197,6 +200,18 @@ export default class MessageEntrance extends Emiter {
this._sassSaveClassStatusInfo();
}
//如果是第一次点击开始上课,需要创建录制时的文件名
_onClassRecordStart(_param){
if(GlobalConfig.getCurrentStatus().code!=GlobalConfig.statusCode_2.code){
loger.warn("不能保存会议状态",GlobalConfig.getCurrentStatus());
return;
}
if(_sass){
_sass.saveClassRecordContrlInfo(_param);
}
}
//有人员离开
_onClassDeleteRoster(_data){
//{"nodeId":nodeId}
... ... @@ -507,7 +522,7 @@ export default class MessageEntrance extends Emiter {
//根据从Sass获取的数据信息,同步最后一次保存的会议状态信息
loger.log("同步最后一次保存过的会议状态信息");
GlobalConfig.setClassStatusInfo(_data.currentInfo);
console.log(GlobalConfig.classStatusInfo)
console.log(GlobalConfig.classStatusInfo);
} else {
loger.log("还没有保存过会议状信息");
}
... ... @@ -535,6 +550,9 @@ export default class MessageEntrance extends Emiter {
_sassSaveClassStatusInfoSuccessHandler(_data) {
loger.log('保存会议状态信息成功.', _data);
}
_sassSaveClassRecordInfoSuccessHandler(_data){
loger.log('保存会议录制信息成功.', _data);
}
//Sass校验流程结束之后,开始加入MCU
_joinMCU() {
... ... @@ -671,6 +689,7 @@ export default class MessageEntrance extends Emiter {
}
//离开会议
if(_confer_ape){
_confer_ape.stopRecord();
_confer_ape.leaveClass();
}
//断开MCU连接
... ... @@ -680,6 +699,7 @@ export default class MessageEntrance extends Emiter {
}
}
//ChatApe
// 发送聊天消息
_sendChatMsg(_messageInfo) {
... ...
... ... @@ -52,6 +52,21 @@ class EngineUtils{
return timeStr;
}
//生成时间戳 格式:"20170209"
static creatTimestampYMD(){
let curTime = new Date();
let year = "" + curTime.getFullYear();
let month = "" +(curTime.getMonth()+1);
let day = "" + curTime.getDate();
if(month.length<2){
month="0"+month;
}
if(day.length<2){
day="0"+day;
}
return year+month+day;
}
static objectToBase64(_object){
try{
let _objectStr=JSON.stringify(_object);
... ...
... ... @@ -307,7 +307,7 @@ GlobalConfig.classTimestamp=0;//从课堂开始到现在的时
GlobalConfig.recordStatus=false;//当前录制状态
GlobalConfig.recordTimestamp=0;//相对于首次开始录制的进行时间
GlobalConfig.recordFileName="";//录制的文件名
GlobalConfig.recordFileName="";//录制的文件名,如 果为空就创建一个
GlobalConfig.recordDownloadUrl="";//下载地址
GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快退
... ...
... ... @@ -26,6 +26,7 @@ MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态
MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间
MessageTypes.CLASS_RECORD_START='class.record.start';//开始录制
... ...
... ... @@ -47,7 +47,7 @@ class Sass extends Emiter {
return ret.json();
} else {
loger.error(`初始化init获取课堂校验信息-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_NETWORK);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_NETWORK);
throw '';
}
})
... ... @@ -59,26 +59,26 @@ class Sass extends Emiter {
//4 站点已过期
if (ret.code === 0) {
loger.log('初始化init获取课堂校验信息-完成');
this._emit(Sass.CLASS_INIT_SUCCESS,ret);
} else if(ret.code === 1) {
this._emit(Sass.CLASS_INIT_SUCCESS, ret);
} else if (ret.code === 1) {
//loger.warn('Sass获取课堂校验信息失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_1);
} else if(ret.code === 2) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_1);
} else if (ret.code === 2) {
//loger.warn('Sass获取课堂校验信息失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_2);
} else if(ret.code === 3) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_2);
} else if (ret.code === 3) {
//loger.warn('Sass获取课堂校验信息失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_3);
} else if(ret.code === 4) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_3);
} else if (ret.code === 4) {
//loger.warn('Sass获取课堂校验信息失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_4);
}else {
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED,ret);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_4);
} else {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED, ret);
}
})
.catch(err => {
loger.error(`初始化init获取课堂校验信息-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_PROTOCOL,err);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PROTOCOL, err);
});
}
... ... @@ -88,9 +88,9 @@ class Sass extends Emiter {
console.log(_param);
confInfo = _param;
// 密码校验
if (confInfo.passwordRequired === 'true'||confInfo.passwordRequired === true) {
if (confInfo.passwordRequired === 'true' || confInfo.passwordRequired === true) {
this.sendPWDChecking();
return ;
return;
}
// MD5校验
this.sendMD5Checking();
... ... @@ -108,9 +108,9 @@ class Sass extends Emiter {
// 请求格式 http://112.126.80.182/3m/api/meeting/signIn.do?siteId=h5test&classId=526661904&password=111111&isTeacher=0
*/
//判断是否是老师
let isTeacher=0;
if(confInfo.userRole==ApeConsts.host){
isTeacher=1
let isTeacher = 0;
if (confInfo.userRole == ApeConsts.host) {
isTeacher = 1
}
let url = `http://${confInfo.portal}/3m/api/meeting/signIn.do?siteId=${confInfo.siteId}&classId=${confInfo.classId}&isTeacher=${isTeacher}&password=${confInfo.password}`;
... ... @@ -123,28 +123,28 @@ class Sass extends Emiter {
return ret.text();
} else {
loger.error(`会议密码校验-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_NETWORK);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_NETWORK);
throw '';
}
})
.then(ret => {
let rectObj=JSON.parse(ret);
if (rectObj.flag === 'false'||rectObj.flag === false) {
let rectObj = JSON.parse(ret);
if (rectObj.flag === 'false' || rectObj.flag === false) {
loger.error(`会议密码校验-失败.`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_PASSWORD_WRONG);
return ;
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_PASSWORD_WRONG);
return;
}
if (rectObj.flag=== 'true'||rectObj.flag === true) {
if (rectObj.flag === 'true' || rectObj.flag === true) {
loger.log(`会议密码校验-成功.`);
this.sendMD5Checking();
return;
}
loger.error(`会议密码校验-协议异常.`,rectObj);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_PROTOCOL);
loger.error(`会议密码校验-协议异常.`, rectObj);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PROTOCOL);
})
.catch(err => {
loger.error(`会议密码校验-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FAILED);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FAILED);
});
}
... ... @@ -160,12 +160,12 @@ class Sass extends Emiter {
return ret.json();
} else {
loger.error(`MD5校验-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_NETWORK);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_NETWORK);
throw '';
}
})
.then(ret => {
if (ret.flag == "true"||ret.flag == true) {
if (ret.flag == "true" || ret.flag == true) {
/* if (ret.h5_mcu_list) {
let server = ret.h5_mcu_list.split(";")[0];
confInfo.MCUServerIP = server.split(":")[0];
... ... @@ -183,16 +183,16 @@ class Sass extends Emiter {
GlobalConfig.maxMediaChannels=confInfo.maxMediaChannels;*/
loger.log('MD5校验完成');
console.log(ret);
this._emit(Sass.SUCCESS,ret);
this._emit(Sass.SUCCESS, ret);
} else {
loger.log('MD5校验-失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_MD5_WRONG);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_MD5_WRONG);
}
})
.catch(err => {
loger.error(`MD5校验-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FAILED);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FAILED);
});
}
... ... @@ -208,7 +208,7 @@ class Sass extends Emiter {
return ret.json();
} else {
loger.error(`获取Class详情-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
throw '';
}
})
... ... @@ -218,17 +218,17 @@ class Sass extends Emiter {
this._emit(Sass.CLASS_GET_CLASS_DETAIL, ret);
} else {
loger.warn('获取Class详情失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
}
})
.catch(err => {
loger.error(`获取Class详情异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
});
}
//获取课堂会议的完整信息--------------------------------------------------------------------------------
getClassParam(){
getClassParam() {
/*
参数 (application/x-www-form-urlencoded):
名称 类型 可选 默认值 说明
... ... @@ -245,8 +245,8 @@ class Sass extends Emiter {
siteId String 站点号
meetingNumber String 课堂号 对应的是classId
*/
var timestamp=new Date().getTime();
var authId=MD5(confInfo.classId+""+timestamp);//课堂号+时间戳 的字符串,转成MD5
var timestamp = new Date().getTime();
var authId = MD5(confInfo.classId + "" + timestamp);//课堂号+时间戳 的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/meeting/detail.do?meetingNumber=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('5.获取课堂会议的完整信息 ');
console.log(url);
... ... @@ -258,7 +258,7 @@ class Sass extends Emiter {
return ret.json();
} else {
loger.error(`获取课堂会议的完整信息-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
throw '';
}
... ... @@ -269,12 +269,12 @@ class Sass extends Emiter {
this._emit(Sass.CLASS_GET_CLASS_PARAM, ret);
} else {
loger.warn('获取课堂会议的完整信息 失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
}
})
.catch(err => {
loger.error(`获取课堂会议的完整信息异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
});
}
... ... @@ -290,9 +290,9 @@ class Sass extends Emiter {
返回 (application/json):
0 成功, 1 验证信息错误
*/
sassDeleteDocument(_param){
var timestamp=new Date().getTime();
var authId=MD5(_param.docId+""+_param.classId+""+timestamp);// docId+classId+timestamp的字符串,转成MD5
sassDeleteDocument(_param) {
var timestamp = new Date().getTime();
var authId = MD5(_param.docId + "" + _param.classId + "" + timestamp);// docId+classId+timestamp的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('sassDeleteDocument', url);
... ... @@ -304,7 +304,7 @@ class Sass extends Emiter {
return ret.json();
} else {
loger.error(`sassDeleteDocument-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
throw '';
}
... ... @@ -315,12 +315,12 @@ class Sass extends Emiter {
this._emit(Sass.DELETE_DOCUMENT_SUCCESS, _param);
} else {
loger.warn('sassDeleteDocumnt 失败.');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
}
})
.catch(err => {
loger.error(`sassDeleteDocument异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
});
}
... ... @@ -336,11 +336,11 @@ class Sass extends Emiter {
返回 (application/json):
code 0 成功 1 课堂号为空 2 无效的课堂号 3 验证信息错误*/
saveClassStatusInfo(_param){
saveClassStatusInfo(_param) {
//{"classStatusInfo":classStatusInfo}
var timestamp=new Date().getTime();
var authId=MD5(confInfo.classId+""+timestamp);// (classId+timestamp)的字符串,转成MD5
let classStatusInfo=JSON.stringify(_param.classStatusInfo);
var timestamp = new Date().getTime();
var authId = MD5(confInfo.classId + "" + timestamp);// (classId+timestamp)的字符串,转成MD5
let classStatusInfo = JSON.stringify(_param.classStatusInfo);
let url = `http://${confInfo.portal}/3m/api/meeting/saveInfo.do`;
loger.log('saveClassStatusInfo', url);
fetch(url, {
... ... @@ -348,7 +348,7 @@ class Sass extends Emiter {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body:`classId=${confInfo.classId}&info=${classStatusInfo}&timestamp=${timestamp}&authId=${authId}`,
body: `classId=${confInfo.classId}&info=${classStatusInfo}&timestamp=${timestamp}&authId=${authId}`,
timeout: 5000
})
.then(ret => {
... ... @@ -364,14 +364,14 @@ class Sass extends Emiter {
if (ret.code === 0) {
loger.log('saveClassStatusInfo 完成');
this._emit(Sass.CLASS_SAVE_STATUS_INFO_SUCCESS, _param);
} else if (ret.code ===1) {
} else if (ret.code === 1) {
loger.log('saveClassStatusInfo 失败 课堂号为空');
}else if (ret.code === 2) {
} else if (ret.code === 2) {
loger.log('saveClassStatusInfo 失败 无效的课堂号');
}else if (ret.code === 3) {
} else if (ret.code === 3) {
loger.log('saveClassStatusInfo 失败 验证信息错误');
}else {
loger.warn('saveClassStatusInfo 失败.',ret);
} else {
loger.warn('saveClassStatusInfo 失败.', ret);
//this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
}
})
... ... @@ -381,14 +381,28 @@ class Sass extends Emiter {
});
}
/*
//用get的方式保存数据
saveClassStatusInfo(_param){
//{"classStatusInfo":"JSON数据的字符串"}
var timestamp=new Date().getTime();
var authId=MD5(confInfo.classId+""+timestamp);// (classId+timestamp)的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/meeting/saveInfo.do?classId=${confInfo.classId}&info=${_param.classStatusInfo}&timestamp=${timestamp}&authId=${authId}`;
loger.log('saveClassStatusInfo', url);
//保存录制的信息,主要是录制文件的名称,必须和MCU录制的文件名相同
saveClassRecordContrlInfo(_param) {
loger.log('保存开始录制信息');
let key = "3mang123A";
let siteID = GlobalConfig.siteId;
let meetingID = GlobalConfig.classId;
let userID = GlobalConfig.userId;
let userName = GlobalConfig.userName;
let meetingName = GlobalConfig.className;
let startTime =GlobalConfig.classBeginTime;
let endTime = GlobalConfig.classEndTime;
let playUrl = "";
let streamName = GlobalConfig.recordFileName;
let confRecordFileName=GlobalConfig.recordFileName;
let downloadUrl = "";
let recordStatus = GlobalConfig.classStatus;
let recordTimestamp =GlobalConfig.classTimestamp;
let timestamp = new Date().getTime();;
let authId = MD5(key + siteID + meetingID + timestamp);
let url = `http://${confInfo.portal}/3m/recordingMeeting/insertRecordingMeeting.do?siteID=${siteID}&meetingID=${meetingID}&userID=${userID}&userName=${userName}&meetingName=${meetingName}&startTime=${startTime}&endTime=${endTime}&playUrl=${playUrl}&streamName=${streamName}&downloadUrl=${downloadUrl}&configFile=${confRecordFileName}&timestamp=${timestamp}&recordTimestamp=${recordTimestamp}&authId=${authId}`;
loger.log('saveClassRecordContrlInfo', url);
fetch(url, {
timeout: 5000
... ... @@ -397,41 +411,35 @@ class Sass extends Emiter {
if (ret.ok) {
return ret.json();
} else {
loger.error(`saveClassStatusInfo-网络异常.状态码:${ret.status}`);
//this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
loger.error(`保存开始录制信息-网络异常.状态码:${ret.status}`);
throw '';
}
})
.then(ret => {
if (ret.code === 0) {
loger.log('saveClassStatusInfo 完成');
this._emit(Sass.CLASS_SAVE_STATUS_INFO_SUCCESS, _param);
} else if (ret.code ===1) {
loger.log('saveClassStatusInfo 失败 课堂号为空');
}else if (ret.code === 2) {
loger.log('saveClassStatusInfo 失败 无效的课堂号');
}else if (ret.code === 3) {
loger.log('saveClassStatusInfo 失败 验证信息错误');
}else {
loger.warn('saveClassStatusInfo 失败.',ret);
//this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
loger.log('保存开始录制信息 完成');
this._emit(Sass.CLASS_SAVE_RECORD_INFO_SUCCESS, _param);
} else {
loger.warn('保存开始录制信息 失败.');
}
})
.catch(err => {
loger.error(`saveClassStatusInfo.状态码:${err}`);
//this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
loger.error(`保存开始录制信息异常.状态码:${err}`);
});
}*/
}
}
Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass.success';
Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass.class.init.success';
Sass.prototype.CLASS_GET_CLASS_PARAM= Sass.CLASS_GET_CLASS_PARAM = 'class.getClassParam.message';
Sass.prototype.CLASS_GET_CLASS_DETAIL= Sass.CLASS_GET_CLASS_DETAIL = 'class.getClassDetail.message';
Sass.prototype.DELETE_DOCUMENT_SUCCESS= Sass.DELETE_DOCUMENT_SUCCESS = 'class.deleteDocumentSuccess.message';//删除文档成功
Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'class.getClassParam.message';
Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'class.getClassDetail.message';
Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'class.deleteDocumentSuccess.message';//删除文档成功
Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS = Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'class.saveClassStatusInfoSuccess.message';//保存会议状态信息
Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'class.saveClassRecordInfoSuccess.message';//保存录制会议信息
Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS= Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'class.saveClassStatusInfoSuccess.message';//保存会议状态信息
export default new Sass;
... ...
... ... @@ -2,25 +2,13 @@
// 计时器
// //////////////////////////////////////////////////////////////////////////////
//import ApeConsts from './ApeConsts';
//import Loger from 'Loger';
//import MessageTypes from 'MessageTypes';
//import GlobalConfig from 'GlobalConfig';
//import EngineUtils from 'EngineUtils';
//let loger = Loger.getLoger('MediaModule');
/*let counter=0;
let callBackDelay=1;
let callBackFun;
let isStart=false;*/
class TimerCounter {
constructor() {
this.timer=0;
this.delay=1000;
this.counter=0;
this.callBackDelay=1;
this.callBackFun=null;
this.callBackDelay=1;//回调间隔,单位(秒)
this.callBackFun=null;//回调函数
this.isStart=false;
}
... ...
... ... @@ -55,6 +55,7 @@ class ConferApe extends Ape {
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST,this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息
}
//加入会议
... ... @@ -114,27 +115,87 @@ class ConferApe extends Ape {
}
*/
let chatSendPdu = new pdu['RCConferenceSendDataRequestPdu'];
chatSendPdu.type = pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST;
chatSendPdu.initiator = this._classInfo.nodeId;//发起人
chatSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
chatSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
//chatSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
chatSendPdu.isPublic = true;
chatSendPdu.actionType=_messageInfo.actionType;
// if (!(chatSendPdu.isPublic || 0 === chatSendPdu.peer)) {
if (!chatSendPdu.isPublic && 0!=chatSendPdu.peer) {
let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu'];
conferSendPdu.type = pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST;
conferSendPdu.initiator = this._classInfo.nodeId;//发起人
conferSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
//conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
conferSendPdu.isPublic = true;
conferSendPdu.actionType=_messageInfo.actionType;
// if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
if (!conferSendPdu.isPublic && 0!=conferSendPdu.peer) {
//发送给制定的人
loger.log('发送私聊会议消息.');
this.send(chatSendPdu);
this.send(conferSendPdu);
} else {
//发送给所有人
loger.log('发送公聊会议消息.');
this.sendChatUniform(chatSendPdu);
this.sendChatUniform(conferSendPdu);
}
}
//发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
sendConferRecordMsg(_param) {
if(!this.mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
// to, message
loger.log('发送录制消息.', _param);
if(_param==null){
loger.warn("控制录制状的消息发送失败,参数错误",_param);
return;
}
/* message RCConferenceRecordRequestPdu {
optional uint32 initiator = 1; // 发起录像指令的node id
optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
optional uint32 class_time = 3; // 课堂进行时间(秒)
optional string filename = 4; // 录像文件名称,filename中增加目录部分
}*/
//保存当前的录制状态
GlobalConfig.recordStatus=_param.recordStatus||false;
let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
conferRecordSendPdu.peer = 0;//channel 为0
conferRecordSendPdu.isPublic = true;
conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人
conferRecordSendPdu.record =GlobalConfig.recordStatus;
conferRecordSendPdu.classTime=GlobalConfig.classTimestamp;
conferRecordSendPdu.filename=GlobalConfig.recordFileName||GlobalConfig.classId+"_"+EngineUtils.creatTimestampYMD()+".rec";
this.sendChatUniform(conferRecordSendPdu);
}
//开启录制
startRecord(){
loger.log('startRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus);
//如果是host
if(GlobalConfig.isHost){
GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus":true});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制
}
}
//停止录制
stopRecord(){
loger.log('stopRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus);
//如果是host,并且当前正在录制中
if(GlobalConfig.isHost&&GlobalConfig.recordStatus){
GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus":false});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
}
}
//主动离开会议,发送通知到服务器
leaveClass(){
let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
... ... @@ -169,32 +230,48 @@ class ConferApe extends Ape {
this.sendUniform(adapterPdu, true);
}
//还原课堂状态
restorClass(){
GlobalConfig.classTimestamp=0;
GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT;
GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
this.stopRecord();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({"actionType":0});
loger.log('restorClass');
}
//开始上课
startClass(_param){
if(GlobalConfig.isHost){
let timestamp=EngineUtils.creatTimestampStr();
GlobalConfig.classStopTime=timestamp;
//如果录制的文件名不存在,需要创建一个名字
let timestampYMD=EngineUtils.creatTimestampYMD();
GlobalConfig.recordFileName=GlobalConfig.recordFileName||
GlobalConfig.siteId+"/"+timestampYMD+"/"
+GlobalConfig.classId+"_"+timestampYMD+".rec";//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`
if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){
//之前是为开始状态,第一次点开始
GlobalConfig.classStartTime=timestamp;
}
GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED;
//_param.actionType=ACTION_TYPE_1;
//开始录制
this.startRecord();
//会议状态改变
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步会议状态
this.sendUpdaterClassStatusInfo({"actionType":1});
//开始计时
this.startTimerCounter();
}else {
loger.warn('没有权限');
}
}
//暂停上课
pauseClass(_param){
... ... @@ -205,7 +282,8 @@ class ConferApe extends Ape {
GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_PAUSE;
GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
//_param.actionType=ACTION_TYPE_2;
this.stopRecord();
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this.sendUpdaterClassStatusInfo({"actionType":2});
this.stopTimerCounter();
... ... @@ -280,12 +358,15 @@ class ConferApe extends Ape {
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
//加入channel成功
onJoinChannelHandlerSuccess(){
loger.log('ConferApe onJoinChannelHandlerSuccess');
loger.log('ConferApe.onJoinChannelHandlerSuccess',GlobalConfig.classStatus);
this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1);
//如果当前会议正在进行中,开启计时器
if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){
//开始计时
this.startTimerCounter();
//如果是host ,开始录制
this.startRecord();
}
}
//开启计时器
... ... @@ -307,7 +388,7 @@ class ConferApe extends Ape {
return;
}
GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时
loger.log('课堂进行时间',GlobalConfig.classTimestamp);
//loger.log('课堂进行时间',GlobalConfig.classTimestamp);
this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp});
if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){
... ... @@ -380,6 +461,17 @@ class ConferApe extends Ape {
}
}
onSendConferRecordRequestHandler(_data){
loger.log("onSendConferRecordRequestHandler");
try{
let conferRecordSendPdu =pdu['RCConferenceRecordRequestPdu'].decode(_data);
console.log(conferRecordSendPdu);
}catch (err){
loger.warn("onSendConferRecordRequestHandler err",err.message);
}
}
rosterInsertHandler(nodeId, nodeData) {
if(GlobalConfig.nodeId==nodeId){
loger.log("自己加入 rosterInsertHandler");
... ...
... ... @@ -25,7 +25,7 @@ class MediaModule {
_param.channelId == null|| _param.timestamp==null)
{
loger.warn('getMediaPlayPath,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
//this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
... ...
... ... @@ -88,6 +88,7 @@ RCPduPackage.RCPDU_AUDIO_SEND_DATA_REQUEST = 261;
RCPduPackage.RCPDU_GIFT_SEND_DATA_REQUEST = 262;
RCPduPackage.RCPDU_CHAT_SEND_DATA_REQUEST = 263;
RCPduPackage.RCPDU_VOTING_POLL_RECORD = 265;
RCPduPackage.RCPDU_CONFERENCE_RECORD_REQUEST = 270;//录制和停止录制的协议号
RCPduPackage.RCPDU_REG_REQUEST_OBJ = 290;
RCPduPackage.RCPDU_REG_RESPONSE_OBJ = 291;
... ...
... ... @@ -121,6 +121,7 @@ enum RCPduType_E {
RCPDU_GIFT_SEND_DATA_REQUEST = 262;
RCPDU_CHAT_SEND_DATA_REQUEST = 263;
RCPDU_VOTING_POLL_RECORD = 265;
RCPDU_CONFERENCE_RECORD_REQUEST = 270;
// Registry resource request or response PDU
RCPDU_REG_REQUEST_OBJ = 290;
... ... @@ -924,6 +925,12 @@ message RCClassStatusInfoPdu {
optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页
}
message RCConferenceRecordRequestPdu {
optional uint32 initiator = 1; // 发起录像指令的node id
optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
optional uint32 class_time = 3; // 课堂进行时间(秒)
optional string filename = 4; // 录像文件名称,filename中增加目录部分
}
//end
`;
... ...