李勇

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

2.增加录制的协议号和录制的pdu结构
3.会议模块增加开始录制和停止录制的接口
@@ -65,6 +65,7 @@ export default class MessageEntrance extends Emiter { @@ -65,6 +65,7 @@ export default class MessageEntrance extends Emiter {
65 _sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息 65 _sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息
66 _sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取会议的最全信息和历史保存的数据 66 _sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取会议的最全信息和历史保存的数据
67 _sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this));//保存会议状态信息 67 _sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this));//保存会议状态信息
  68 + _sass.on(_sass.CLASS_SAVE_RECORD_INFO_SUCCESS, this._sassSaveClassRecordInfoSuccessHandler.bind(this));//保存会议录制信息
68 _sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this));//sass删除文档成功 69 _sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this));//sass删除文档成功
69 70
70 // 底层MCU消息层 71 // 底层MCU消息层
@@ -80,6 +81,7 @@ export default class MessageEntrance extends Emiter { @@ -80,6 +81,7 @@ export default class MessageEntrance extends Emiter {
80 _confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变 81 _confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变
81 _confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前会议人员离开 82 _confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前会议人员离开
82 _confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER,this._onClassNonentityRoster.bind(this));//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在 83 _confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER,this._onClassNonentityRoster.bind(this));//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在
  84 + _confer_ape.on(MessageTypes.CLASS_RECORD_START,this._onClassRecordStart.bind(this));//会议开始录制
83 85
84 86
85 _chat_ape = new ChatApe(); 87 _chat_ape = new ChatApe();
@@ -117,6 +119,7 @@ export default class MessageEntrance extends Emiter { @@ -117,6 +119,7 @@ export default class MessageEntrance extends Emiter {
117 this.sendPauseClass = this._sendPauseClass; 119 this.sendPauseClass = this._sendPauseClass;
118 this.sendCloseClass = this._sendCloseClass; 120 this.sendCloseClass = this._sendCloseClass;
119 121
  122 +
120 //chatApe 123 //chatApe
121 this.sendChatMsg = this._sendChatMsg; 124 this.sendChatMsg = this._sendChatMsg;
122 125
@@ -197,6 +200,18 @@ export default class MessageEntrance extends Emiter { @@ -197,6 +200,18 @@ export default class MessageEntrance extends Emiter {
197 this._sassSaveClassStatusInfo(); 200 this._sassSaveClassStatusInfo();
198 } 201 }
199 202
  203 + //如果是第一次点击开始上课,需要创建录制时的文件名
  204 + _onClassRecordStart(_param){
  205 + if(GlobalConfig.getCurrentStatus().code!=GlobalConfig.statusCode_2.code){
  206 + loger.warn("不能保存会议状态",GlobalConfig.getCurrentStatus());
  207 + return;
  208 + }
  209 + if(_sass){
  210 + _sass.saveClassRecordContrlInfo(_param);
  211 + }
  212 + }
  213 +
  214 +
200 //有人员离开 215 //有人员离开
201 _onClassDeleteRoster(_data){ 216 _onClassDeleteRoster(_data){
202 //{"nodeId":nodeId} 217 //{"nodeId":nodeId}
@@ -507,7 +522,7 @@ export default class MessageEntrance extends Emiter { @@ -507,7 +522,7 @@ export default class MessageEntrance extends Emiter {
507 //根据从Sass获取的数据信息,同步最后一次保存的会议状态信息 522 //根据从Sass获取的数据信息,同步最后一次保存的会议状态信息
508 loger.log("同步最后一次保存过的会议状态信息"); 523 loger.log("同步最后一次保存过的会议状态信息");
509 GlobalConfig.setClassStatusInfo(_data.currentInfo); 524 GlobalConfig.setClassStatusInfo(_data.currentInfo);
510 - console.log(GlobalConfig.classStatusInfo) 525 + console.log(GlobalConfig.classStatusInfo);
511 } else { 526 } else {
512 loger.log("还没有保存过会议状信息"); 527 loger.log("还没有保存过会议状信息");
513 } 528 }
@@ -535,6 +550,9 @@ export default class MessageEntrance extends Emiter { @@ -535,6 +550,9 @@ export default class MessageEntrance extends Emiter {
535 _sassSaveClassStatusInfoSuccessHandler(_data) { 550 _sassSaveClassStatusInfoSuccessHandler(_data) {
536 loger.log('保存会议状态信息成功.', _data); 551 loger.log('保存会议状态信息成功.', _data);
537 } 552 }
  553 + _sassSaveClassRecordInfoSuccessHandler(_data){
  554 + loger.log('保存会议录制信息成功.', _data);
  555 + }
538 556
539 //Sass校验流程结束之后,开始加入MCU 557 //Sass校验流程结束之后,开始加入MCU
540 _joinMCU() { 558 _joinMCU() {
@@ -671,6 +689,7 @@ export default class MessageEntrance extends Emiter { @@ -671,6 +689,7 @@ export default class MessageEntrance extends Emiter {
671 } 689 }
672 //离开会议 690 //离开会议
673 if(_confer_ape){ 691 if(_confer_ape){
  692 + _confer_ape.stopRecord();
674 _confer_ape.leaveClass(); 693 _confer_ape.leaveClass();
675 } 694 }
676 //断开MCU连接 695 //断开MCU连接
@@ -680,6 +699,7 @@ export default class MessageEntrance extends Emiter { @@ -680,6 +699,7 @@ export default class MessageEntrance extends Emiter {
680 } 699 }
681 } 700 }
682 701
  702 +
683 //ChatApe 703 //ChatApe
684 // 发送聊天消息 704 // 发送聊天消息
685 _sendChatMsg(_messageInfo) { 705 _sendChatMsg(_messageInfo) {
@@ -52,6 +52,21 @@ class EngineUtils{ @@ -52,6 +52,21 @@ class EngineUtils{
52 return timeStr; 52 return timeStr;
53 } 53 }
54 54
  55 + //生成时间戳 格式:"20170209"
  56 + static creatTimestampYMD(){
  57 + let curTime = new Date();
  58 + let year = "" + curTime.getFullYear();
  59 + let month = "" +(curTime.getMonth()+1);
  60 + let day = "" + curTime.getDate();
  61 +
  62 + if(month.length<2){
  63 + month="0"+month;
  64 + }
  65 + if(day.length<2){
  66 + day="0"+day;
  67 + }
  68 + return year+month+day;
  69 + }
55 static objectToBase64(_object){ 70 static objectToBase64(_object){
56 try{ 71 try{
57 let _objectStr=JSON.stringify(_object); 72 let _objectStr=JSON.stringify(_object);
@@ -307,7 +307,7 @@ GlobalConfig.classTimestamp=0;//从课堂开始到现在的时 @@ -307,7 +307,7 @@ GlobalConfig.classTimestamp=0;//从课堂开始到现在的时
307 307
308 GlobalConfig.recordStatus=false;//当前录制状态 308 GlobalConfig.recordStatus=false;//当前录制状态
309 GlobalConfig.recordTimestamp=0;//相对于首次开始录制的进行时间 309 GlobalConfig.recordTimestamp=0;//相对于首次开始录制的进行时间
310 -GlobalConfig.recordFileName="";//录制的文件名 310 +GlobalConfig.recordFileName="";//录制的文件名,如 果为空就创建一个
311 GlobalConfig.recordDownloadUrl="";//下载地址 311 GlobalConfig.recordDownloadUrl="";//下载地址
312 GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快退 312 GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快退
313 313
@@ -26,6 +26,7 @@ MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态 @@ -26,6 +26,7 @@ MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态
26 26
27 MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间 27 MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间
28 28
  29 +MessageTypes.CLASS_RECORD_START='class.record.start';//开始录制
29 30
30 31
31 32
@@ -47,7 +47,7 @@ class Sass extends Emiter { @@ -47,7 +47,7 @@ class Sass extends Emiter {
47 return ret.json(); 47 return ret.json();
48 } else { 48 } else {
49 loger.error(`初始化init获取课堂校验信息-网络异常.状态码:${ret.status}`); 49 loger.error(`初始化init获取课堂校验信息-网络异常.状态码:${ret.status}`);
50 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_NETWORK); 50 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_NETWORK);
51 throw ''; 51 throw '';
52 } 52 }
53 }) 53 })
@@ -59,26 +59,26 @@ class Sass extends Emiter { @@ -59,26 +59,26 @@ class Sass extends Emiter {
59 //4 站点已过期 59 //4 站点已过期
60 if (ret.code === 0) { 60 if (ret.code === 0) {
61 loger.log('初始化init获取课堂校验信息-完成'); 61 loger.log('初始化init获取课堂校验信息-完成');
62 - this._emit(Sass.CLASS_INIT_SUCCESS,ret);  
63 - } else if(ret.code === 1) { 62 + this._emit(Sass.CLASS_INIT_SUCCESS, ret);
  63 + } else if (ret.code === 1) {
64 //loger.warn('Sass获取课堂校验信息失败.'); 64 //loger.warn('Sass获取课堂校验信息失败.');
65 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_1);  
66 - } else if(ret.code === 2) { 65 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_1);
  66 + } else if (ret.code === 2) {
67 //loger.warn('Sass获取课堂校验信息失败.'); 67 //loger.warn('Sass获取课堂校验信息失败.');
68 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_2);  
69 - } else if(ret.code === 3) { 68 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_2);
  69 + } else if (ret.code === 3) {
70 //loger.warn('Sass获取课堂校验信息失败.'); 70 //loger.warn('Sass获取课堂校验信息失败.');
71 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_3);  
72 - } else if(ret.code === 4) { 71 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_3);
  72 + } else if (ret.code === 4) {
73 //loger.warn('Sass获取课堂校验信息失败.'); 73 //loger.warn('Sass获取课堂校验信息失败.');
74 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED_4);  
75 - }else {  
76 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_FAILED,ret); 74 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED_4);
  75 + } else {
  76 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_FAILED, ret);
77 } 77 }
78 }) 78 })
79 .catch(err => { 79 .catch(err => {
80 loger.error(`初始化init获取课堂校验信息-异常.状态码:${err}`); 80 loger.error(`初始化init获取课堂校验信息-异常.状态码:${err}`);
81 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_INIT_PROTOCOL,err); 81 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PROTOCOL, err);
82 }); 82 });
83 } 83 }
84 84
@@ -88,9 +88,9 @@ class Sass extends Emiter { @@ -88,9 +88,9 @@ class Sass extends Emiter {
88 console.log(_param); 88 console.log(_param);
89 confInfo = _param; 89 confInfo = _param;
90 // 密码校验 90 // 密码校验
91 - if (confInfo.passwordRequired === 'true'||confInfo.passwordRequired === true) { 91 + if (confInfo.passwordRequired === 'true' || confInfo.passwordRequired === true) {
92 this.sendPWDChecking(); 92 this.sendPWDChecking();
93 - return ; 93 + return;
94 } 94 }
95 // MD5校验 95 // MD5校验
96 this.sendMD5Checking(); 96 this.sendMD5Checking();
@@ -108,9 +108,9 @@ class Sass extends Emiter { @@ -108,9 +108,9 @@ class Sass extends Emiter {
108 // 请求格式 http://112.126.80.182/3m/api/meeting/signIn.do?siteId=h5test&classId=526661904&password=111111&isTeacher=0 108 // 请求格式 http://112.126.80.182/3m/api/meeting/signIn.do?siteId=h5test&classId=526661904&password=111111&isTeacher=0
109 */ 109 */
110 //判断是否是老师 110 //判断是否是老师
111 - let isTeacher=0;  
112 - if(confInfo.userRole==ApeConsts.host){  
113 - isTeacher=1 111 + let isTeacher = 0;
  112 + if (confInfo.userRole == ApeConsts.host) {
  113 + isTeacher = 1
114 } 114 }
115 115
116 let url = `http://${confInfo.portal}/3m/api/meeting/signIn.do?siteId=${confInfo.siteId}&classId=${confInfo.classId}&isTeacher=${isTeacher}&password=${confInfo.password}`; 116 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 { @@ -123,28 +123,28 @@ class Sass extends Emiter {
123 return ret.text(); 123 return ret.text();
124 } else { 124 } else {
125 loger.error(`会议密码校验-网络异常.状态码:${ret.status}`); 125 loger.error(`会议密码校验-网络异常.状态码:${ret.status}`);
126 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_NETWORK); 126 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_NETWORK);
127 throw ''; 127 throw '';
128 } 128 }
129 }) 129 })
130 .then(ret => { 130 .then(ret => {
131 - let rectObj=JSON.parse(ret);  
132 - if (rectObj.flag === 'false'||rectObj.flag === false) { 131 + let rectObj = JSON.parse(ret);
  132 + if (rectObj.flag === 'false' || rectObj.flag === false) {
133 loger.error(`会议密码校验-失败.`); 133 loger.error(`会议密码校验-失败.`);
134 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_PASSWORD_WRONG);  
135 - return ; 134 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_PASSWORD_WRONG);
  135 + return;
136 } 136 }
137 - if (rectObj.flag=== 'true'||rectObj.flag === true) { 137 + if (rectObj.flag === 'true' || rectObj.flag === true) {
138 loger.log(`会议密码校验-成功.`); 138 loger.log(`会议密码校验-成功.`);
139 this.sendMD5Checking(); 139 this.sendMD5Checking();
140 return; 140 return;
141 } 141 }
142 - loger.error(`会议密码校验-协议异常.`,rectObj);  
143 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_PROTOCOL); 142 + loger.error(`会议密码校验-协议异常.`, rectObj);
  143 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PROTOCOL);
144 }) 144 })
145 .catch(err => { 145 .catch(err => {
146 loger.error(`会议密码校验-异常.状态码:${err}`); 146 loger.error(`会议密码校验-异常.状态码:${err}`);
147 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FAILED); 147 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FAILED);
148 }); 148 });
149 } 149 }
150 150
@@ -160,12 +160,12 @@ class Sass extends Emiter { @@ -160,12 +160,12 @@ class Sass extends Emiter {
160 return ret.json(); 160 return ret.json();
161 } else { 161 } else {
162 loger.error(`MD5校验-网络异常.状态码:${ret.status}`); 162 loger.error(`MD5校验-网络异常.状态码:${ret.status}`);
163 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_NETWORK); 163 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_NETWORK);
164 throw ''; 164 throw '';
165 } 165 }
166 }) 166 })
167 .then(ret => { 167 .then(ret => {
168 - if (ret.flag == "true"||ret.flag == true) { 168 + if (ret.flag == "true" || ret.flag == true) {
169 /* if (ret.h5_mcu_list) { 169 /* if (ret.h5_mcu_list) {
170 let server = ret.h5_mcu_list.split(";")[0]; 170 let server = ret.h5_mcu_list.split(";")[0];
171 confInfo.MCUServerIP = server.split(":")[0]; 171 confInfo.MCUServerIP = server.split(":")[0];
@@ -183,16 +183,16 @@ class Sass extends Emiter { @@ -183,16 +183,16 @@ class Sass extends Emiter {
183 GlobalConfig.maxMediaChannels=confInfo.maxMediaChannels;*/ 183 GlobalConfig.maxMediaChannels=confInfo.maxMediaChannels;*/
184 loger.log('MD5校验完成'); 184 loger.log('MD5校验完成');
185 console.log(ret); 185 console.log(ret);
186 - this._emit(Sass.SUCCESS,ret); 186 + this._emit(Sass.SUCCESS, ret);
187 } else { 187 } else {
188 loger.log('MD5校验-失败.'); 188 loger.log('MD5校验-失败.');
189 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_MD5_WRONG); 189 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_MD5_WRONG);
190 190
191 } 191 }
192 }) 192 })
193 .catch(err => { 193 .catch(err => {
194 loger.error(`MD5校验-异常.状态码:${err}`); 194 loger.error(`MD5校验-异常.状态码:${err}`);
195 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FAILED); 195 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FAILED);
196 }); 196 });
197 } 197 }
198 198
@@ -208,7 +208,7 @@ class Sass extends Emiter { @@ -208,7 +208,7 @@ class Sass extends Emiter {
208 return ret.json(); 208 return ret.json();
209 } else { 209 } else {
210 loger.error(`获取Class详情-网络异常.状态码:${ret.status}`); 210 loger.error(`获取Class详情-网络异常.状态码:${ret.status}`);
211 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL); 211 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
212 throw ''; 212 throw '';
213 } 213 }
214 }) 214 })
@@ -218,17 +218,17 @@ class Sass extends Emiter { @@ -218,17 +218,17 @@ class Sass extends Emiter {
218 this._emit(Sass.CLASS_GET_CLASS_DETAIL, ret); 218 this._emit(Sass.CLASS_GET_CLASS_DETAIL, ret);
219 } else { 219 } else {
220 loger.warn('获取Class详情失败.'); 220 loger.warn('获取Class详情失败.');
221 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL); 221 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
222 } 222 }
223 }) 223 })
224 .catch(err => { 224 .catch(err => {
225 loger.error(`获取Class详情异常.状态码:${err}`); 225 loger.error(`获取Class详情异常.状态码:${err}`);
226 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_DETAIL); 226 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_DETAIL);
227 }); 227 });
228 } 228 }
229 229
230 //获取课堂会议的完整信息-------------------------------------------------------------------------------- 230 //获取课堂会议的完整信息--------------------------------------------------------------------------------
231 - getClassParam(){ 231 + getClassParam() {
232 /* 232 /*
233 参数 (application/x-www-form-urlencoded): 233 参数 (application/x-www-form-urlencoded):
234 名称 类型 可选 默认值 说明 234 名称 类型 可选 默认值 说明
@@ -245,8 +245,8 @@ class Sass extends Emiter { @@ -245,8 +245,8 @@ class Sass extends Emiter {
245 siteId String 站点号 245 siteId String 站点号
246 meetingNumber String 课堂号 对应的是classId 246 meetingNumber String 课堂号 对应的是classId
247 */ 247 */
248 - var timestamp=new Date().getTime();  
249 - var authId=MD5(confInfo.classId+""+timestamp);//课堂号+时间戳 的字符串,转成MD5 248 + var timestamp = new Date().getTime();
  249 + var authId = MD5(confInfo.classId + "" + timestamp);//课堂号+时间戳 的字符串,转成MD5
250 let url = `http://${confInfo.portal}/3m/api/meeting/detail.do?meetingNumber=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`; 250 let url = `http://${confInfo.portal}/3m/api/meeting/detail.do?meetingNumber=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
251 loger.log('5.获取课堂会议的完整信息 '); 251 loger.log('5.获取课堂会议的完整信息 ');
252 console.log(url); 252 console.log(url);
@@ -258,7 +258,7 @@ class Sass extends Emiter { @@ -258,7 +258,7 @@ class Sass extends Emiter {
258 return ret.json(); 258 return ret.json();
259 } else { 259 } else {
260 loger.error(`获取课堂会议的完整信息-网络异常.状态码:${ret.status}`); 260 loger.error(`获取课堂会议的完整信息-网络异常.状态码:${ret.status}`);
261 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML); 261 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
262 262
263 throw ''; 263 throw '';
264 } 264 }
@@ -269,12 +269,12 @@ class Sass extends Emiter { @@ -269,12 +269,12 @@ class Sass extends Emiter {
269 this._emit(Sass.CLASS_GET_CLASS_PARAM, ret); 269 this._emit(Sass.CLASS_GET_CLASS_PARAM, ret);
270 } else { 270 } else {
271 loger.warn('获取课堂会议的完整信息 失败.'); 271 loger.warn('获取课堂会议的完整信息 失败.');
272 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML); 272 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
273 } 273 }
274 }) 274 })
275 .catch(err => { 275 .catch(err => {
276 loger.error(`获取课堂会议的完整信息异常.状态码:${err}`); 276 loger.error(`获取课堂会议的完整信息异常.状态码:${err}`);
277 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_GET_CLASS_PARAML); 277 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
278 }); 278 });
279 } 279 }
280 280
@@ -290,9 +290,9 @@ class Sass extends Emiter { @@ -290,9 +290,9 @@ class Sass extends Emiter {
290 返回 (application/json): 290 返回 (application/json):
291 0 成功, 1 验证信息错误 291 0 成功, 1 验证信息错误
292 */ 292 */
293 - sassDeleteDocument(_param){  
294 - var timestamp=new Date().getTime();  
295 - var authId=MD5(_param.docId+""+_param.classId+""+timestamp);// docId+classId+timestamp的字符串,转成MD5 293 + sassDeleteDocument(_param) {
  294 + var timestamp = new Date().getTime();
  295 + var authId = MD5(_param.docId + "" + _param.classId + "" + timestamp);// docId+classId+timestamp的字符串,转成MD5
296 let url = `http://${confInfo.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`; 296 let url = `http://${confInfo.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
297 loger.log('sassDeleteDocument', url); 297 loger.log('sassDeleteDocument', url);
298 298
@@ -304,7 +304,7 @@ class Sass extends Emiter { @@ -304,7 +304,7 @@ class Sass extends Emiter {
304 return ret.json(); 304 return ret.json();
305 } else { 305 } else {
306 loger.error(`sassDeleteDocument-网络异常.状态码:${ret.status}`); 306 loger.error(`sassDeleteDocument-网络异常.状态码:${ret.status}`);
307 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 307 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
308 308
309 throw ''; 309 throw '';
310 } 310 }
@@ -315,12 +315,12 @@ class Sass extends Emiter { @@ -315,12 +315,12 @@ class Sass extends Emiter {
315 this._emit(Sass.DELETE_DOCUMENT_SUCCESS, _param); 315 this._emit(Sass.DELETE_DOCUMENT_SUCCESS, _param);
316 } else { 316 } else {
317 loger.warn('sassDeleteDocumnt 失败.'); 317 loger.warn('sassDeleteDocumnt 失败.');
318 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 318 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
319 } 319 }
320 }) 320 })
321 .catch(err => { 321 .catch(err => {
322 loger.error(`sassDeleteDocument异常.状态码:${err}`); 322 loger.error(`sassDeleteDocument异常.状态码:${err}`);
323 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 323 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
324 }); 324 });
325 } 325 }
326 326
@@ -336,11 +336,11 @@ class Sass extends Emiter { @@ -336,11 +336,11 @@ class Sass extends Emiter {
336 返回 (application/json): 336 返回 (application/json):
337 code 0 成功 1 课堂号为空 2 无效的课堂号 3 验证信息错误*/ 337 code 0 成功 1 课堂号为空 2 无效的课堂号 3 验证信息错误*/
338 338
339 - saveClassStatusInfo(_param){ 339 + saveClassStatusInfo(_param) {
340 //{"classStatusInfo":classStatusInfo} 340 //{"classStatusInfo":classStatusInfo}
341 - var timestamp=new Date().getTime();  
342 - var authId=MD5(confInfo.classId+""+timestamp);// (classId+timestamp)的字符串,转成MD5  
343 - let classStatusInfo=JSON.stringify(_param.classStatusInfo); 341 + var timestamp = new Date().getTime();
  342 + var authId = MD5(confInfo.classId + "" + timestamp);// (classId+timestamp)的字符串,转成MD5
  343 + let classStatusInfo = JSON.stringify(_param.classStatusInfo);
344 let url = `http://${confInfo.portal}/3m/api/meeting/saveInfo.do`; 344 let url = `http://${confInfo.portal}/3m/api/meeting/saveInfo.do`;
345 loger.log('saveClassStatusInfo', url); 345 loger.log('saveClassStatusInfo', url);
346 fetch(url, { 346 fetch(url, {
@@ -348,7 +348,7 @@ class Sass extends Emiter { @@ -348,7 +348,7 @@ class Sass extends Emiter {
348 headers: { 348 headers: {
349 "Content-Type": "application/x-www-form-urlencoded" 349 "Content-Type": "application/x-www-form-urlencoded"
350 }, 350 },
351 - body:`classId=${confInfo.classId}&info=${classStatusInfo}&timestamp=${timestamp}&authId=${authId}`, 351 + body: `classId=${confInfo.classId}&info=${classStatusInfo}&timestamp=${timestamp}&authId=${authId}`,
352 timeout: 5000 352 timeout: 5000
353 }) 353 })
354 .then(ret => { 354 .then(ret => {
@@ -364,14 +364,14 @@ class Sass extends Emiter { @@ -364,14 +364,14 @@ class Sass extends Emiter {
364 if (ret.code === 0) { 364 if (ret.code === 0) {
365 loger.log('saveClassStatusInfo 完成'); 365 loger.log('saveClassStatusInfo 完成');
366 this._emit(Sass.CLASS_SAVE_STATUS_INFO_SUCCESS, _param); 366 this._emit(Sass.CLASS_SAVE_STATUS_INFO_SUCCESS, _param);
367 - } else if (ret.code ===1) { 367 + } else if (ret.code === 1) {
368 loger.log('saveClassStatusInfo 失败 课堂号为空'); 368 loger.log('saveClassStatusInfo 失败 课堂号为空');
369 - }else if (ret.code === 2) { 369 + } else if (ret.code === 2) {
370 loger.log('saveClassStatusInfo 失败 无效的课堂号'); 370 loger.log('saveClassStatusInfo 失败 无效的课堂号');
371 - }else if (ret.code === 3) { 371 + } else if (ret.code === 3) {
372 loger.log('saveClassStatusInfo 失败 验证信息错误'); 372 loger.log('saveClassStatusInfo 失败 验证信息错误');
373 - }else {  
374 - loger.warn('saveClassStatusInfo 失败.',ret); 373 + } else {
  374 + loger.warn('saveClassStatusInfo 失败.', ret);
375 //this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 375 //this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED);
376 } 376 }
377 }) 377 })
@@ -381,14 +381,28 @@ class Sass extends Emiter { @@ -381,14 +381,28 @@ class Sass extends Emiter {
381 }); 381 });
382 } 382 }
383 383
384 - /*  
385 - //用get的方式保存数据  
386 - saveClassStatusInfo(_param){  
387 - //{"classStatusInfo":"JSON数据的字符串"}  
388 - var timestamp=new Date().getTime();  
389 - var authId=MD5(confInfo.classId+""+timestamp);// (classId+timestamp)的字符串,转成MD5  
390 - let url = `http://${confInfo.portal}/3m/api/meeting/saveInfo.do?classId=${confInfo.classId}&info=${_param.classStatusInfo}&timestamp=${timestamp}&authId=${authId}`;  
391 - loger.log('saveClassStatusInfo', url); 384 + //保存录制的信息,主要是录制文件的名称,必须和MCU录制的文件名相同
  385 + saveClassRecordContrlInfo(_param) {
  386 + loger.log('保存开始录制信息');
  387 + let key = "3mang123A";
  388 + let siteID = GlobalConfig.siteId;
  389 + let meetingID = GlobalConfig.classId;
  390 + let userID = GlobalConfig.userId;
  391 + let userName = GlobalConfig.userName;
  392 + let meetingName = GlobalConfig.className;
  393 + let startTime =GlobalConfig.classBeginTime;
  394 + let endTime = GlobalConfig.classEndTime;
  395 + let playUrl = "";
  396 + let streamName = GlobalConfig.recordFileName;
  397 + let confRecordFileName=GlobalConfig.recordFileName;
  398 + let downloadUrl = "";
  399 + let recordStatus = GlobalConfig.classStatus;
  400 + let recordTimestamp =GlobalConfig.classTimestamp;
  401 +
  402 + let timestamp = new Date().getTime();;
  403 + let authId = MD5(key + siteID + meetingID + timestamp);
  404 + 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}`;
  405 + loger.log('saveClassRecordContrlInfo', url);
392 406
393 fetch(url, { 407 fetch(url, {
394 timeout: 5000 408 timeout: 5000
@@ -397,41 +411,35 @@ class Sass extends Emiter { @@ -397,41 +411,35 @@ class Sass extends Emiter {
397 if (ret.ok) { 411 if (ret.ok) {
398 return ret.json(); 412 return ret.json();
399 } else { 413 } else {
400 - loger.error(`saveClassStatusInfo-网络异常.状态码:${ret.status}`);  
401 - //this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 414 + loger.error(`保存开始录制信息-网络异常.状态码:${ret.status}`);
402 throw ''; 415 throw '';
403 } 416 }
404 }) 417 })
405 .then(ret => { 418 .then(ret => {
406 if (ret.code === 0) { 419 if (ret.code === 0) {
407 - loger.log('saveClassStatusInfo 完成');  
408 - this._emit(Sass.CLASS_SAVE_STATUS_INFO_SUCCESS, _param);  
409 - } else if (ret.code ===1) {  
410 - loger.log('saveClassStatusInfo 失败 课堂号为空');  
411 - }else if (ret.code === 2) {  
412 - loger.log('saveClassStatusInfo 失败 无效的课堂号');  
413 - }else if (ret.code === 3) {  
414 - loger.log('saveClassStatusInfo 失败 验证信息错误');  
415 - }else {  
416 - loger.warn('saveClassStatusInfo 失败.',ret);  
417 - //this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 420 + loger.log('保存开始录制信息 完成');
  421 + this._emit(Sass.CLASS_SAVE_RECORD_INFO_SUCCESS, _param);
  422 + } else {
  423 + loger.warn('保存开始录制信息 失败.');
418 } 424 }
419 }) 425 })
420 .catch(err => { 426 .catch(err => {
421 - loger.error(`saveClassStatusInfo.状态码:${err}`);  
422 - //this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_DOC_DELETE_FAILED); 427 + loger.error(`保存开始录制信息异常.状态码:${err}`);
423 }); 428 });
424 - }*/  
425 429
  430 + }
426 431
427 } 432 }
428 433
429 Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass.success'; 434 Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass.success';
430 Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass.class.init.success'; 435 Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass.class.init.success';
431 -Sass.prototype.CLASS_GET_CLASS_PARAM= Sass.CLASS_GET_CLASS_PARAM = 'class.getClassParam.message';  
432 -Sass.prototype.CLASS_GET_CLASS_DETAIL= Sass.CLASS_GET_CLASS_DETAIL = 'class.getClassDetail.message';  
433 -Sass.prototype.DELETE_DOCUMENT_SUCCESS= Sass.DELETE_DOCUMENT_SUCCESS = 'class.deleteDocumentSuccess.message';//删除文档成功 436 +Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'class.getClassParam.message';
  437 +Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'class.getClassDetail.message';
  438 +Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'class.deleteDocumentSuccess.message';//删除文档成功
  439 +
  440 +Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS = Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'class.saveClassStatusInfoSuccess.message';//保存会议状态信息
  441 +Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'class.saveClassRecordInfoSuccess.message';//保存录制会议信息
  442 +
434 443
435 -Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS= Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'class.saveClassStatusInfoSuccess.message';//保存会议状态信息  
436 export default new Sass; 444 export default new Sass;
437 445
@@ -2,25 +2,13 @@ @@ -2,25 +2,13 @@
2 // 计时器 2 // 计时器
3 // ////////////////////////////////////////////////////////////////////////////// 3 // //////////////////////////////////////////////////////////////////////////////
4 4
5 -//import ApeConsts from './ApeConsts';  
6 -//import Loger from 'Loger';  
7 -//import MessageTypes from 'MessageTypes';  
8 -//import GlobalConfig from 'GlobalConfig';  
9 -//import EngineUtils from 'EngineUtils';  
10 -  
11 -//let loger = Loger.getLoger('MediaModule');  
12 -  
13 -/*let counter=0;  
14 -let callBackDelay=1;  
15 -let callBackFun;  
16 -let isStart=false;*/  
17 class TimerCounter { 5 class TimerCounter {
18 constructor() { 6 constructor() {
19 this.timer=0; 7 this.timer=0;
20 this.delay=1000; 8 this.delay=1000;
21 this.counter=0; 9 this.counter=0;
22 - this.callBackDelay=1;  
23 - this.callBackFun=null; 10 + this.callBackDelay=1;//回调间隔,单位(秒)
  11 + this.callBackFun=null;//回调函数
24 this.isStart=false; 12 this.isStart=false;
25 } 13 }
26 14
@@ -55,6 +55,7 @@ class ConferApe extends Ape { @@ -55,6 +55,7 @@ class ConferApe extends Ape {
55 this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this)); 55 this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
56 56
57 this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理 57 this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
  58 + this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST,this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息
58 } 59 }
59 60
60 //加入会议 61 //加入会议
@@ -114,27 +115,87 @@ class ConferApe extends Ape { @@ -114,27 +115,87 @@ class ConferApe extends Ape {
114 } 115 }
115 */ 116 */
116 117
117 - let chatSendPdu = new pdu['RCConferenceSendDataRequestPdu'];  
118 - chatSendPdu.type = pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST;  
119 - chatSendPdu.initiator = this._classInfo.nodeId;//发起人  
120 - chatSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id  
121 -  
122 - chatSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);  
123 - //chatSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);  
124 - chatSendPdu.isPublic = true;  
125 - chatSendPdu.actionType=_messageInfo.actionType;  
126 - // if (!(chatSendPdu.isPublic || 0 === chatSendPdu.peer)) {  
127 - if (!chatSendPdu.isPublic && 0!=chatSendPdu.peer) { 118 + let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu'];
  119 + conferSendPdu.type = pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST;
  120 + conferSendPdu.initiator = this._classInfo.nodeId;//发起人
  121 + conferSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id
  122 +
  123 + conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
  124 + //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
  125 + conferSendPdu.isPublic = true;
  126 + conferSendPdu.actionType=_messageInfo.actionType;
  127 + // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
  128 + if (!conferSendPdu.isPublic && 0!=conferSendPdu.peer) {
128 //发送给制定的人 129 //发送给制定的人
129 loger.log('发送私聊会议消息.'); 130 loger.log('发送私聊会议消息.');
130 - this.send(chatSendPdu); 131 + this.send(conferSendPdu);
131 } else { 132 } else {
132 //发送给所有人 133 //发送给所有人
133 loger.log('发送公聊会议消息.'); 134 loger.log('发送公聊会议消息.');
134 - this.sendChatUniform(chatSendPdu); 135 + this.sendChatUniform(conferSendPdu);
135 } 136 }
136 } 137 }
137 138
  139 + //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
  140 + sendConferRecordMsg(_param) {
  141 + if(!this.mcu.connected){
  142 + loger.warn(GlobalConfig.getCurrentStatus());
  143 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  144 + }
  145 + // to, message
  146 + loger.log('发送录制消息.', _param);
  147 +
  148 + if(_param==null){
  149 + loger.warn("控制录制状的消息发送失败,参数错误",_param);
  150 + return;
  151 + }
  152 +
  153 + /* message RCConferenceRecordRequestPdu {
  154 + optional uint32 initiator = 1; // 发起录像指令的node id
  155 + optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
  156 + optional uint32 class_time = 3; // 课堂进行时间(秒)
  157 + optional string filename = 4; // 录像文件名称,filename中增加目录部分
  158 + }*/
  159 +
  160 + //保存当前的录制状态
  161 + GlobalConfig.recordStatus=_param.recordStatus||false;
  162 +
  163 + let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
  164 + conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
  165 + conferRecordSendPdu.peer = 0;//channel 为0
  166 + conferRecordSendPdu.isPublic = true;
  167 +
  168 + conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人
  169 + conferRecordSendPdu.record =GlobalConfig.recordStatus;
  170 + conferRecordSendPdu.classTime=GlobalConfig.classTimestamp;
  171 + conferRecordSendPdu.filename=GlobalConfig.recordFileName||GlobalConfig.classId+"_"+EngineUtils.creatTimestampYMD()+".rec";
  172 + this.sendChatUniform(conferRecordSendPdu);
  173 + }
  174 +
  175 + //开启录制
  176 + startRecord(){
  177 + loger.log('startRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus);
  178 + //如果是host
  179 + if(GlobalConfig.isHost){
  180 + GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
  181 + this.sendConferRecordMsg({"recordStatus":true});
  182 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  183 + this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制
  184 + }
  185 + }
  186 +
  187 + //停止录制
  188 + stopRecord(){
  189 + loger.log('stopRecord',"isHost",GlobalConfig.isHost,"recordStatus",GlobalConfig.recordStatus);
  190 + //如果是host,并且当前正在录制中
  191 + if(GlobalConfig.isHost&&GlobalConfig.recordStatus){
  192 + GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
  193 + this.sendConferRecordMsg({"recordStatus":false});
  194 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  195 + }
  196 + }
  197 +
  198 +
138 //主动离开会议,发送通知到服务器 199 //主动离开会议,发送通知到服务器
139 leaveClass(){ 200 leaveClass(){
140 let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self; 201 let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
@@ -169,32 +230,48 @@ class ConferApe extends Ape { @@ -169,32 +230,48 @@ class ConferApe extends Ape {
169 this.sendUniform(adapterPdu, true); 230 this.sendUniform(adapterPdu, true);
170 } 231 }
171 232
172 -  
173 //还原课堂状态 233 //还原课堂状态
174 restorClass(){ 234 restorClass(){
175 GlobalConfig.classTimestamp=0; 235 GlobalConfig.classTimestamp=0;
176 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT; 236 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_WAIT;
177 GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); 237 GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
  238 + this.stopRecord();
178 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 239 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
179 this.sendUpdaterClassStatusInfo({"actionType":0}); 240 this.sendUpdaterClassStatusInfo({"actionType":0});
  241 + loger.log('restorClass');
180 } 242 }
181 243
182 //开始上课 244 //开始上课
183 startClass(_param){ 245 startClass(_param){
  246 + if(GlobalConfig.isHost){
  247 +
184 let timestamp=EngineUtils.creatTimestampStr(); 248 let timestamp=EngineUtils.creatTimestampStr();
185 GlobalConfig.classStopTime=timestamp; 249 GlobalConfig.classStopTime=timestamp;
186 250
  251 + //如果录制的文件名不存在,需要创建一个名字
  252 + let timestampYMD=EngineUtils.creatTimestampYMD();
  253 + GlobalConfig.recordFileName=GlobalConfig.recordFileName||
  254 + GlobalConfig.siteId+"/"+timestampYMD+"/"
  255 + +GlobalConfig.classId+"_"+timestampYMD+".rec";//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`
  256 +
187 if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){ 257 if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_WAIT){
  258 + //之前是为开始状态,第一次点开始
188 GlobalConfig.classStartTime=timestamp; 259 GlobalConfig.classStartTime=timestamp;
189 } 260 }
190 261
191 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED; 262 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_STARTED;
192 - //_param.actionType=ACTION_TYPE_1; 263 + //开始录制
  264 + this.startRecord();
  265 + //会议状态改变
193 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 266 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  267 + //同步会议状态
194 this.sendUpdaterClassStatusInfo({"actionType":1}); 268 this.sendUpdaterClassStatusInfo({"actionType":1});
195 269
196 //开始计时 270 //开始计时
197 this.startTimerCounter(); 271 this.startTimerCounter();
  272 + }else {
  273 + loger.warn('没有权限');
  274 + }
198 } 275 }
199 //暂停上课 276 //暂停上课
200 pauseClass(_param){ 277 pauseClass(_param){
@@ -205,7 +282,8 @@ class ConferApe extends Ape { @@ -205,7 +282,8 @@ class ConferApe extends Ape {
205 282
206 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_PAUSE; 283 GlobalConfig.classStatus=ApeConsts.CLASS_STATUS_PAUSE;
207 GlobalConfig.classStopTime=EngineUtils.creatTimestampStr(); 284 GlobalConfig.classStopTime=EngineUtils.creatTimestampStr();
208 - //_param.actionType=ACTION_TYPE_2; 285 +
  286 + this.stopRecord();
209 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 287 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
210 this.sendUpdaterClassStatusInfo({"actionType":2}); 288 this.sendUpdaterClassStatusInfo({"actionType":2});
211 this.stopTimerCounter(); 289 this.stopTimerCounter();
@@ -280,12 +358,15 @@ class ConferApe extends Ape { @@ -280,12 +358,15 @@ class ConferApe extends Ape {
280 /////收到消息处理///////////////////////////////////////////////////////////////////////////////// 358 /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
281 //加入channel成功 359 //加入channel成功
282 onJoinChannelHandlerSuccess(){ 360 onJoinChannelHandlerSuccess(){
283 - loger.log('ConferApe onJoinChannelHandlerSuccess'); 361 + loger.log('ConferApe.onJoinChannelHandlerSuccess',GlobalConfig.classStatus);
284 this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1); 362 this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this),1);
285 //如果当前会议正在进行中,开启计时器 363 //如果当前会议正在进行中,开启计时器
286 if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){ 364 if(GlobalConfig.classStatus==ApeConsts.CLASS_STATUS_STARTED){
287 //开始计时 365 //开始计时
288 this.startTimerCounter(); 366 this.startTimerCounter();
  367 +
  368 + //如果是host ,开始录制
  369 + this.startRecord();
289 } 370 }
290 } 371 }
291 //开启计时器 372 //开启计时器
@@ -307,7 +388,7 @@ class ConferApe extends Ape { @@ -307,7 +388,7 @@ class ConferApe extends Ape {
307 return; 388 return;
308 } 389 }
309 GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时 390 GlobalConfig.classTimestamp=GlobalConfig.classTimestamp+1;//计时
310 - loger.log('课堂进行时间',GlobalConfig.classTimestamp); 391 + //loger.log('课堂进行时间',GlobalConfig.classTimestamp);
311 this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp}); 392 this._emit(MessageTypes.CLASS_UPDATE_TIMER,{"classTimestamp":GlobalConfig.classTimestamp});
312 393
313 if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){ 394 if(GlobalConfig.classTimestamp%GlobalConfig.updateClassInfoDelay==0){
@@ -380,6 +461,17 @@ class ConferApe extends Ape { @@ -380,6 +461,17 @@ class ConferApe extends Ape {
380 } 461 }
381 } 462 }
382 463
  464 + onSendConferRecordRequestHandler(_data){
  465 + loger.log("onSendConferRecordRequestHandler");
  466 + try{
  467 + let conferRecordSendPdu =pdu['RCConferenceRecordRequestPdu'].decode(_data);
  468 + console.log(conferRecordSendPdu);
  469 + }catch (err){
  470 + loger.warn("onSendConferRecordRequestHandler err",err.message);
  471 + }
  472 +
  473 + }
  474 +
383 rosterInsertHandler(nodeId, nodeData) { 475 rosterInsertHandler(nodeId, nodeData) {
384 if(GlobalConfig.nodeId==nodeId){ 476 if(GlobalConfig.nodeId==nodeId){
385 loger.log("自己加入 rosterInsertHandler"); 477 loger.log("自己加入 rosterInsertHandler");
@@ -25,7 +25,7 @@ class MediaModule { @@ -25,7 +25,7 @@ class MediaModule {
25 _param.channelId == null|| _param.timestamp==null) 25 _param.channelId == null|| _param.timestamp==null)
26 { 26 {
27 loger.warn('getMediaPlayPath,参数错误', _param); 27 loger.warn('getMediaPlayPath,参数错误', _param);
28 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 28 + //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
29 return {"code": ApeConsts.RETURN_FAILED, "data": ""}; 29 return {"code": ApeConsts.RETURN_FAILED, "data": ""};
30 } 30 }
31 31
@@ -88,6 +88,7 @@ RCPduPackage.RCPDU_AUDIO_SEND_DATA_REQUEST = 261; @@ -88,6 +88,7 @@ RCPduPackage.RCPDU_AUDIO_SEND_DATA_REQUEST = 261;
88 RCPduPackage.RCPDU_GIFT_SEND_DATA_REQUEST = 262; 88 RCPduPackage.RCPDU_GIFT_SEND_DATA_REQUEST = 262;
89 RCPduPackage.RCPDU_CHAT_SEND_DATA_REQUEST = 263; 89 RCPduPackage.RCPDU_CHAT_SEND_DATA_REQUEST = 263;
90 RCPduPackage.RCPDU_VOTING_POLL_RECORD = 265; 90 RCPduPackage.RCPDU_VOTING_POLL_RECORD = 265;
  91 +RCPduPackage.RCPDU_CONFERENCE_RECORD_REQUEST = 270;//录制和停止录制的协议号
91 92
92 RCPduPackage.RCPDU_REG_REQUEST_OBJ = 290; 93 RCPduPackage.RCPDU_REG_REQUEST_OBJ = 290;
93 RCPduPackage.RCPDU_REG_RESPONSE_OBJ = 291; 94 RCPduPackage.RCPDU_REG_RESPONSE_OBJ = 291;
@@ -121,6 +121,7 @@ enum RCPduType_E { @@ -121,6 +121,7 @@ enum RCPduType_E {
121 RCPDU_GIFT_SEND_DATA_REQUEST = 262; 121 RCPDU_GIFT_SEND_DATA_REQUEST = 262;
122 RCPDU_CHAT_SEND_DATA_REQUEST = 263; 122 RCPDU_CHAT_SEND_DATA_REQUEST = 263;
123 RCPDU_VOTING_POLL_RECORD = 265; 123 RCPDU_VOTING_POLL_RECORD = 265;
  124 + RCPDU_CONFERENCE_RECORD_REQUEST = 270;
124 125
125 // Registry resource request or response PDU 126 // Registry resource request or response PDU
126 RCPDU_REG_REQUEST_OBJ = 290; 127 RCPDU_REG_REQUEST_OBJ = 290;
@@ -924,6 +925,12 @@ message RCClassStatusInfoPdu { @@ -924,6 +925,12 @@ message RCClassStatusInfoPdu {
924 optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页 925 optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页
925 } 926 }
926 927
  928 +message RCConferenceRecordRequestPdu {
  929 + optional uint32 initiator = 1; // 发起录像指令的node id
  930 + optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
  931 + optional uint32 class_time = 3; // 课堂进行时间(秒)
  932 + optional string filename = 4; // 录像文件名称,filename中增加目录部分
  933 +}
927 934
928 //end 935 //end
929 `; 936 `;