李勇
5e3df8a2 2 parents d7d0e75e bde14b95 master ... 20170922-1 20171019-1 20171120-1w dev letv-20170426 ly20170622 ly20170622-2 ly20170622-3 ly20170627-2 ly20170706-1 ly20170708-2 ly20170708-3 ly20170710-1 ly20170717-1 ly20170719-1 ly20170723-1 ly20170724-2 ly20170726-1 ly20170731-1 ly20170731-2 ly20170801-2 ly20170802-1 ly20170818-1 ly20170818-2 ly20170820-1 ly20170821-1 ly20170824-1 ly20170829-1 ly20170925-1 ly20170926-1 ly20170927-1 ly20170929-1 ly20171011-1 ly20171013-1 ly20171013-2 ly20171016-1 ly20171021-1 ly20171023-1 ly20171024-1w ly20171025-1w ly20171026-1w ly20171027-1w ly20171030-1 ly20171030-2w ly20171107-1 ly20171110-1w ly20171113-1w ly20171204-1w ly20171208-1w ly20171211-1w ly20171211-2w ly20171214-1w webRtc-dev 1.7.0 v2.38.13.20171216 v2.38.11.20171214 v2.38.3.201712011 v2.38.1.201712011 v2.36.11.20171204 v2.36.8.20171206 v2.36.4.20171201 v2.35.11.20171130 v2.34.16.20171128 v2.34.5.20171127 v2.33.6.20171123 v2.32.1.20171123 v2.31.12.20171122 v2.31.10.20171122 v2.30.5.20171117 v2.30.2.20171117 v2.29.5.20171114 v2.28.1.20171110 v2.27.11.20171109 v2.26.9.20171107 v2.26.6.20171103 v2.26.2.20171102 v2.25.7.20171031 v2.25.6.20171031 v2.25.0.20171030 v2.24.2.20171030 v2.23.0.20171030 v2.22.7.20171026 v2.20.5.20171023 v2.20.0.20171021 v2.19.8.20171020 v2.18.14.20171020 v2.18.10.20171019 v2.17.11.20171014 v2.16.8.20171012 v2.16.5.20171012 v2.15.5.20171001 v2.15.3.20170929 v2.14.5.20170927 v2.13.5.20170927 v2.12.14.20170927 v2.12.8.20170926 v2.12.6.20170925 v2.11.13.20170925 v2.10.7.20170921 v2.10.6.20170921 v2.10.5.20170920 v2.10.4.20170920 v2.9.3.20170919 v2.8.17.20170918 v2.8.8.20170917 v2.8.2.20170916 v2.6.2.20170915 v2.5.12.20170915 v2.5.6.20170914 v2.5.5.20170914 v2.4.4.20170908 v2.4.2.20170908 v2.4.0.20170907 v2.3.6.20170907 v2.2.16.20170905 v2.1.22.20170904 v1.84.0.20170912 v1.83.2.20170831 v1.82.11.20170829 v1.81.19.20170828 v1.80.2.20170824 v1.79.6.20170822 v1.79.5.20170821 v1.79.4.20170821 v1.79.3.20170821 v1.78.4.20170820 v1.77.4.20170819 v1.76.2.20170818 v1.75.0.20170815 v1.74.0.20170814 v1.73.2.20170814 v1.73.1.20170814 v1.71.0.20170813 v1.70.5.20170812 v1.68.2.20170812 v1.66.1.20170809 v1.65.25.20170808 v1.65.24.20170806 v1.63.1.20170731 v1.62.3.20170731 v1.61.0.20170729 v1.60.0.20170729 v1.59.0.20170729 v1.58.0.20170729 v1.57.0.20170727 v1.56.1.20170727 v1.56.0.20170727 v1.52.1.20170726 v1.51.0.20170724 v1.50.7.20170724 v1.49.1.20170724 v1.48.2.20170723 v1.46.1.20170722 v1.45.1.20170717 v1.43.1.20170711 v1.42.1.20170708 v1.41.0.20170708 v1.40.0.20170706 v1.39.2.20170706 v1.39.1.20170705 v1.38.4.20170629 v1.37.5.20170627 v1.37.2.20170622 v1.36.7.20170620 v1.36.4.20170620 v1.36.1.20170619 v1.35.4.20170619 v1.34.2.20170615 v1.33.2.20170615 v1.32.1.20170614 v1.31.11.20170613 v1.30.20.20170607 v1.30.7.20170606 v1.30.6.20170606 v1.30.5.20170605 v1.30.3.20170602 v1.29.8.20170601 v1.28.0.201705031 v1.27.16.201705027 v1.27.14.201705027 v1.27.10.201705026 v1.25.2.201705025 v1.23.5.201705023 v1.23.4.201705018 v1.21.1.201705017 v1.20.1.201705015 v1.19.1.201705012 v1.19.0.201705011 v1.18.0.201705010 v1.16.1.201705010 v1.15.2.20170507 v1.14.1.20170505 v1.13.0.20170504 v1.11.3.20170504 v1.10.2.20170428 v1.10.0.20170427 v1.9.20.20170426 v1.9.19.20170425 v1.9.18.20170425 v1.9.17.20170421 v1.9.16.20170420 v1.9.15.20170420 v1.9.11.20170419 v1.9.6.20170418 v1.9.4.20170417 v.1.9.2.20170413 v.1.9.0.20170411 v.1.8.22.20170411 v.1.8.19.20170411 v.1.8.16.20170410 v.1.8.13.20170409 v.1.8.10.20170407 v.1.8.9.20170407 v1.8.8.20170406 v.1.8.7.20170405-1 v.1.8.6.20170401-2 v.1.8.5.20170331-1 v.1.8.3.20170329-4 v1.8.1.20170321 mcuClient_v1.8.0.20170314

1.简化了音视频模块的推流和播流接口,收到的音视频消息分为(播放、停止)

2.修改事件消息定义
... ... @@ -34,14 +34,14 @@ let _audio_ape;
let _doc_ape;
let _whiteboard_ape;
//初始化成功回调函数
let _initSuccessCallBackFun;
//加入会议成功回调函数
let _joinClassSuccessCallBackFun;
//监听mcu所有错误异常回调函数
let _mcuErrorCallBackFun;
////初始化成功回调函数
//let _initSuccessCallBackFun;
//
////加入会议成功回调函数
//let _joinClassSuccessCallBackFun;
//
////监听mcu所有错误异常回调函数
//let _mcuErrorCallBackFun;
//MCUClient 外部实例化主类
export default class MessageEntrance extends Emiter {
... ... @@ -71,7 +71,7 @@ export default class MessageEntrance extends Emiter {
// 底层MCU消息层
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
_mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._mcuJoinClassSuccessHandler.bind(this));//加入MCU会议完成
_mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this));//加入MCU会议完成
// 注册所有应用Ape
... ... @@ -89,11 +89,11 @@ export default class MessageEntrance extends Emiter {
_video_ape = new VideoApe();
_video_ape.on('*', (type, data) => this._emit(type, data));
_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));
//_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));
_audio_ape= new AudioApe();
_audio_ape.on('*', (type, data) => this._emit(type, data));
_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));
//_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));
_whiteboard_ape = new WhiteBoardApe();
_whiteboard_ape.on('*', (type, data) => this._emit(type, data));
... ... @@ -109,62 +109,65 @@ export default class MessageEntrance extends Emiter {
//公开外部调用的方法
//class
this.init = this._init;
this.joinClass = this._joinClass;
this.leaveClass = this._leaveClass;
this.getMcuClientStatus = this._getMcuClientStatus;
this.init = this._init.bind(this);
this.joinClass = this._joinClass.bind(this);
this.leaveClass = this._leaveClass.bind(this);
this.getMcuClientStatus = this._getMcuClientStatus.bind(this);
//this.getClassDetail = this._getClassDetail;//停用
this.getClassStatusInfo = this._getClassStatusInfo;
this.sendStartClass = this._sendStartClass;
this.sendPauseClass = this._sendPauseClass;
this.sendCloseClass = this._sendCloseClass;
this.getClassStatusInfo = this._getClassStatusInfo.bind(this);
this.sendStartClass = this._sendStartClass.bind(this);
this.sendPauseClass = this._sendPauseClass.bind(this);
this.sendCloseClass = this._sendCloseClass.bind(this);
//chatApe
this.sendChatMsg = this._sendChatMsg;
this.sendChatMsg = this._sendChatMsg.bind(this);
//videoApe
this.getVideoPlayPath = this._getVideoPlayPath;
this.getVideoPublishPath = this._getVideoPublishPath;
this.publishVideo = this._publishVideo;
this.stopPublishVideo = this._stopPublishVideo;
this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg;
this.getVideoPlayPath = this._getVideoPlayPath.bind(this);
this.getVideoPublishPath = this._getVideoPublishPath.bind(this);
this.publishVideo = this._publishVideo.bind(this);
this.stopPublishVideo = this._stopPublishVideo.bind(this);
this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg.bind(this);
//audioApe
this.getAudioPlayPath = this._getPlayAudioPath;
this.getAudioPublishPath = this._getPublishAudioPath;
this.publishAudio = this._publishAudio;
this.stopPublishAudio = this._stopPublishAudio;
this.sendAudioBroadcastMsg=this.sendAudioCommandMsg;
this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
this.publishAudio = this._publishAudio.bind(this);
this.stopPublishAudio = this._stopPublishAudio.bind(this);
this.sendAudioBroadcastMsg=this.sendAudioCommandMsg.bind(this);
//whiteBoradApe
this.sendInsertAnnotaion = this._sendInsertAnnotaion;
this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this);
//this.sendDeleteAnnotaion=this._sendDeleteAnnotaion;
this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation;
this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation;
this.sendGotoPrev = this._sendGotoPrev;
this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this);
this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this);
this.sendGotoPrev = this._sendGotoPrev.bind(this);
//DocApe
this.sendDocumentUpload = this._sendDocumentUpload;//上传文档
this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc; //切换文档
this.sendDocumentSwitchPage = this._sendDocumentSwitchPage;//翻页
this.sendDocumentDelete = this._sassDeleteDocument;//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
this.sendDocumentUpload = this._sendDocumentUpload.bind(this);;//上传文档
this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this);; //切换文档
this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this);;//翻页
this.sendDocumentDelete = this._sassDeleteDocument.bind(this);;//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
//this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档
this.sendDocumentCommand = this._sendDocumentCommand;//操作文档(翻页、缩放、滚动...)
this.getDocImageFullPath=this._getDocImageFullPath;//获取文档图片的完整路径
this.getDocPDFFullPath=this._getDocPDFFullPath;//获取文档的完整路径
this.sendDocumentCommand = this._sendDocumentCommand.bind(this);;//操作文档(翻页、缩放、滚动...)
this.getDocImageFullPath=this._getDocImageFullPath.bind(this);;//获取文档图片的完整路径
this.getDocPDFFullPath=this._getDocPDFFullPath.bind(this);;//获取文档的完整路径
}
//mcu异常监听
_mcuErrorHandler(_data, _option) {
if (_mcuErrorCallBackFun) {
let option = _option || "";
let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
loger.error("MCU_ERROR", errorMessage);
let option = _option || "";
let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
loger.error("MCU_ERROR", errorMessage);
this._emit(MessageTypes.ERROR_EVENT,errorMessage);
/* if (_mcuErrorCallBackFun) {
_mcuErrorCallBackFun(errorMessage);
}
}*/
}
//获取当前的状态
... ... @@ -248,12 +251,10 @@ export default class MessageEntrance extends Emiter {
//Sass
//初始化
_init(_param, _onSuccess, _mcuErrorCallBack) {
_initSuccessCallBackFun = _onSuccess;
_mcuErrorCallBackFun = _mcuErrorCallBack;
_init(_param) {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param) || _onSuccess == null || _mcuErrorCallBack == null) {
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('init初始化失败,参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
... ... @@ -280,10 +281,10 @@ export default class MessageEntrance extends Emiter {
}
//外部请求加入会议
_joinClass(_param, _onSuccess) {
_joinClassSuccessCallBackFun = _onSuccess;
_joinClass(_param) {
//_joinClassSuccessCallBackFun = _onSuccess;
//{"userName":"名字","password":""}
if (_param == null || EngineUtils.isEmptyObject(_param) || _onSuccess == null) {
if (_param == null || EngineUtils.isEmptyObject(_param)) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
loger.log('不能进入会议,传递的参数不对.', _param);
return;
... ... @@ -324,25 +325,27 @@ export default class MessageEntrance extends Emiter {
//设置当前的会议状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1);
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.classType = GlobalConfig.classType;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
if (GlobalConfig.userRole== ApeConsts.host) {
initSuccessCallBackData.passwordRequired =true;
} else {
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
}
if (_initSuccessCallBackFun) {
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.classType = GlobalConfig.classType;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
if (GlobalConfig.userRole== ApeConsts.host) {
initSuccessCallBackData.passwordRequired =true;
} else {
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
}
this._emit(MessageTypes.CLASS_INIT_SUCCESS,initSuccessCallBackData);
/* if (_initSuccessCallBackFun) {
_initSuccessCallBackFun(initSuccessCallBackData);
}
}*/
}
// 通过SASS平台验证(密码和MD5)
... ... @@ -549,10 +552,12 @@ export default class MessageEntrance extends Emiter {
//保存会态信息成功
_sassSaveClassStatusInfoSuccessHandler(_data) {
loger.log('保存会议状态信息成功.', _data);
loger.log('保存会议状态信息成功.');
console.log(_data);
}
_sassSaveClassRecordInfoSuccessHandler(_data){
loger.log('保存会议录制信息成功.', _data);
loger.log('保存会议录制信息成功.');
console.log(_data);
}
//Sass校验流程结束之后,开始加入MCU
... ... @@ -564,50 +569,54 @@ export default class MessageEntrance extends Emiter {
}
// MCU 会议成功
_mcuJoinClassSuccessHandler(_data) {
_mcuJoinMCUClassSuccessHandler(_data) {
loger.log('MCU 会议成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户数据
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP;
initSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.className = GlobalConfig.className;
initSuccessCallBackData.h5Module = GlobalConfig.h5Module;
initSuccessCallBackData.isHost = GlobalConfig.isHost;
initSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
initSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
initSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
initSuccessCallBackData.msType = GlobalConfig.msType;
initSuccessCallBackData.nodeId = GlobalConfig.nodeId;
initSuccessCallBackData.password = GlobalConfig.password;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
initSuccessCallBackData.role = GlobalConfig.role;
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName = GlobalConfig.userName;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userType = GlobalConfig.userType;
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
loger.log('加入会议成功');
console.log(initSuccessCallBackData);
//加入会议成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS,initSuccessCallBackData);
/* //返回给客户数据
if (_joinClassSuccessCallBackFun) {
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP;
initSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.className = GlobalConfig.className;
initSuccessCallBackData.h5Module = GlobalConfig.h5Module;
initSuccessCallBackData.isHost = GlobalConfig.isHost;
initSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
initSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
initSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
initSuccessCallBackData.msType = GlobalConfig.msType;
initSuccessCallBackData.nodeId = GlobalConfig.nodeId;
initSuccessCallBackData.password = GlobalConfig.password;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
initSuccessCallBackData.role = GlobalConfig.role;
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName = GlobalConfig.userName;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userType = GlobalConfig.userType;
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
loger.log('加入会议成功');
console.log(initSuccessCallBackData);
_joinClassSuccessCallBackFun(initSuccessCallBackData);
}
}*/
}
//Sass删除文档数据
... ...
... ... @@ -42,7 +42,11 @@ class EverSocket extends Emiter {
send(data) {
if (this._connected) {
loger.log('SEND MESSAGE---->');
if(data){
loger.log('SEND MESSAGE,byteLength---->',data.byteLength);
}else {
loger.log('SEND MESSAGE---->');
}
this.websocket.send(data);
} else {
loger.warn('WebSocket未建立连接.消息忽略');
... ... @@ -85,6 +89,7 @@ class EverSocket extends Emiter {
loger.log('WebSocket,Timers已经销毁');
return;
}
this._setConnected(false);//先设置状态
this.websocket.onopen = undefined;
this.websocket.onclose = undefined;
this.websocket.onerror = undefined;
... ... @@ -96,7 +101,6 @@ class EverSocket extends Emiter {
}
this.websocket = undefined;
this._enableEverSocket = false;
this._setConnected(false);
}
_onOpen() {
... ...
/**
*事件定义和错误码定义
*事件消息ID和错误码 定义
*/
function MessageTypes() {}
//--------------------事件相关的定义--------------------------------------
//初始化相关事件定义
//MessageTypes.CLASS_INIT_SUCCESS='class.init.success';//初始化成功
MessageTypes.CLASS_INIT_SUCCESS="class_init_success";//'class.init.success';//初始化成功
//MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败
//加入会议相关事件定义
MessageTypes.CLASS_JOIN_SUCCESS = 'join.class.success';
MessageTypes.CLASS_JOIN_MCU_SUCCESS ="class_join_mcu_success"// 'join.mcu.success';
//MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed';
//会议信息和操作事件定义
//MessageTypes.CLASS_SHOW_DETAIL = 'class_detail.message';
MessageTypes.CLASS_SHOW_ROSTER_NUM = 'roster_num.message';
MessageTypes.CLASS_INSERT_ROSTER = 'roster.insert.message';
MessageTypes.CLASS_DELETE_ROSTER = 'roster.delete.message';
MessageTypes.CLASS_NONENTITY_ROSTER = 'roster.nonentity.message';
MessageTypes.CLASS_JOIN_SUCCESS ="class_join_success"// 'join.class.success';
MessageTypes.CLASS_UPDATE_ROSTER_NUM ="class_update_roster_num";// 'roster_num.message';
MessageTypes.CLASS_INSERT_ROSTER ="class_insert_roster";// 'roster.insert.message';
MessageTypes.CLASS_DELETE_ROSTER ="class_delete_roster"// 'roster.delete.message';
MessageTypes.CLASS_NONENTITY_ROSTER ="class_nonenetity_roster";// 'roster.nonentity.message';
MessageTypes.CLASS_EXIT = 'class.exit';//退出 关闭会议
MessageTypes.CLASS_UPTATE_STATUS = 'class.update.status';//更新会议状态信息
MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU
MessageTypes.CLASS_EXIT ="class_exit";// 'class.exit';//退出 关闭会议
MessageTypes.CLASS_UPTATE_STATUS ="class_update_status";// 'class.update.status';//更新会议状态信息
MessageTypes.CLASS_STATUS_INFO_CHANGE="class_status_info_change";// 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU
MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间
MessageTypes.CLASS_UPDATE_TIMER="class_update_timer";//'class.update.timer';//更新当前上课的时间
MessageTypes.CLASS_RECORD_START='class.record.start';//开始录制
MessageTypes.CLASS_RECORD_START="class_record_start";//'class.record.start';//开始录制
//聊天模块事件定义
MessageTypes.CHAT_RECEIVE = 'chat.receive';
MessageTypes.CHAT_RECEIVE ="chat_receive_message";// 'chat.receive';
//视频模块事件定义
MessageTypes.VIDEO_UPDATE = 'video.update';
MessageTypes.VIDEO_BROADCAST= 'video.broadcast';
MessageTypes.VIDEO_PLAY ="video_play";// 'video.play';//播放视频
MessageTypes.VIDEO_STOP ="video_stop"; //'video.stop';//停止视频
//MessageTypes.VIDEO_UPDATE ="video.update";// 'video.update';//废弃,400、401取代
MessageTypes.VIDEO_BROADCAST= "video_broadcast";//'video.broadcast';
//音频模块事件定义
MessageTypes.AUDIO_UPDATE = 'audio.update';
MessageTypes.AUDIO_BROADCAST= 'audio.broadcast';
MessageTypes.AUDIO_PLAY ="audio_play";// 'audio.play';//播放
MessageTypes.AUDIO_STOP = "audio_stop";//'audio.stop';//停止
//MessageTypes.AUDIO_UPDATE = "502";//'audio.update';
MessageTypes.AUDIO_BROADCAST= "audio_broadcast";//'audio.broadcast';
//文档模块事件定义
MessageTypes.DOC_DELETE='document.delete';//删除文档
MessageTypes.DOC_UPDATE = 'document.update';//更新文档(添加、变更)
MessageTypes.DOC_DELETE="document_delete";//'document.delete';//删除文档
MessageTypes.DOC_UPDATE ="document_update";// 'document.update';//更新文档(添加、变更)
//MessageTypes.DOC_SHOW = 'document.show';
//MessageTypes.DOC_UPLOAD='document.upload';//上传文档
//MessageTypes.DOC_COMMAND='document.command';//操作文档
... ... @@ -55,18 +60,15 @@ MessageTypes.DOC_UPDATE = 'document.update';//鏇存柊鏂囨。(娣诲姞銆佸彉鏇)
//白板笔记事件定义
MessageTypes.WHITEBOARD_ANNOTATION_UPDATE = 'whiteboard.annotation.update';
MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'whiteboard.annotation.update';
//MessageTypes.WHITEBOARD_ANNOTAION_INSERT = 'whiteboard.annotation.insert';
//MessageTypes.WHITEBOARD_ANNOTAION_DELETE = 'whiteboard.annotation.delete';
//MessageTypes.WHITEBOARD_ANNOTATION_CLEAR = 'whiteboard.annotation.clear';
//音频
MessageTypes.AUDIO_RECEIVE='audio.receive';
//错误事件定义
MessageTypes.MCU_ERROR ="mcuError";//MCU错误
MessageTypes.MCU_ERROR ="mcu_error";//"mcuError";//MCU错误(内部使用)
MessageTypes.ERROR_EVENT="error_event";//外部监听错误的消息ID(外部使用)
//---------------错误消息 ErrorCode 定义-------------------------------------------------
... ... @@ -103,6 +105,11 @@ MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG=501;//APE鍦ㄦ帴鍙h皟鐢ㄦ椂鍙傛暟閿欒
MessageTypes.ERR_DOC_DELETE_FAILED=600;//删除文档失败
MessageTypes.ERR_DOC_DELETE_FAILED_PARAM=601;//删除文档失败,参数错误
MessageTypes.ERR_SDK_FAILED=700;// sdk还没初始化
MessageTypes.ERR_INTERFACE_NONE=701;//调用的接口不存在
MessageTypes.ERR_INTERFACE_PARAMS_ERROR=702;//调用的接口,传递的参数不正确
MessageTypes.ERR_NETWORK=10000;//网络错误
MessageTypes.ERR_UNKNOWN=10001;//未知错误
... ... @@ -143,6 +150,9 @@ MessageTypes.ErrorReson[MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG]="APE鍦ㄦ帴鍙
MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED]="删除文档失败";
MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED_PARAM]="删除文档失败,参数错误";
MessageTypes.ErrorReson[MessageTypes.ERR_SDK_FAILED]="sdk还没初始化";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_NONE]="调用的接口不存在";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_PARAMS_ERROR]="调用的接口,传递的参数不正确";
MessageTypes.ErrorReson[MessageTypes.ERR_NETWORK]="网络错误";
MessageTypes.ErrorReson[MessageTypes.ERR_UNKNOWN]="未知错误";
... ...
... ... @@ -431,14 +431,14 @@ class Sass extends Emiter {
}
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.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 = 'sass_class_getClassParam.message';
Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'sass_class_getClassDetail_message';
Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'sass_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 = 'sass_class_saveClassStatusInfoSuccess_message';//保存会议状态信息
Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'sass_class_saveClassRecordInfoSuccess_message';//保存录制会议信息
export default new Sass;
... ...
... ... @@ -54,7 +54,7 @@ export default class Ape extends Emiter {
// 监听底层MCU会议
this.mcu = mcu;
this.mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
}
... ...
... ... @@ -57,15 +57,21 @@ class AudioApe extends Ape {
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (_param == null||_param.channelId == null||
_param.classId == null||_param.userId == null||_param.userId==""||
_param.siteId == null|| _param.timestamp==null)
if (_param == null||_param.publishUrl == null)
{
loger.warn('publishAudio,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
}
//根据推流的地址获取对应的频道信息
let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
if(needPublishChannelInfo==null){
loger.warn('publishVideo,推流数据已经无效', _param);
return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
}
//同一个nodeId只允许推一个流,如果已经推了就不能再推
if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){
loger.warn("publishAudio,已经存在一个流,不能再推");
... ... @@ -80,20 +86,20 @@ class AudioApe extends Ape {
}
//判断当前的频道是否已经占用
if(this.mediaModule.checkChannelIsOpening(_param.channelId)){
loger.warn(_param.channelId,"频道已经被占用");
if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){
loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");
return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"};
}
let channelInfo={};
channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=_param.channelId;//freeChannel
channelInfo.timestamp=_param.timestamp;//EngineUtils.creatTimestamp();
channelInfo.classId=_param.classId;//GlobalConfig.classId;
channelInfo.siteId=_param.siteId;//GlobalConfig.siteId;
channelInfo.channelId=needPublishChannelInfo.channelId;//freeChannel
channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称
channelInfo.timestamp=needPublishChannelInfo.timestamp;//EngineUtils.creatTimestamp();
channelInfo.classId=GlobalConfig.classId;//GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;//GlobalConfig.siteId;
channelInfo.toNodeId=0;
channelInfo.userId=_param.userId;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO;
this.sendTableUpdateHandler(channelInfo);
return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"}
... ... @@ -106,9 +112,9 @@ class AudioApe extends Ape {
loger.warn(GlobalConfig.getCurrentStatus());
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
//_param如果为空,那么默认就是当前自己的nodeId,否则用_param
//_param如果为空或者0,那么默认就是当前自己的nodeId,否则用_param
let nodeId;
if(_param&&parseInt(_param.nodeId)>=0){
if(_param&&parseInt(_param.nodeId)>0){
nodeId=parseInt(_param.nodeId);
}else {
nodeId=GlobalConfig.nodeId;
... ... @@ -116,8 +122,8 @@ class AudioApe extends Ape {
let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);
if (openingChannel == 0) {
loger.warn(nodeId,"stopPublishAudio,没有占用channel,不需要关闭");
return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"};
loger.warn(nodeId,"没有占用channel不需要处理");
return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
}
let channelInfo={};
... ... @@ -244,11 +250,47 @@ class AudioApe extends Ape {
tableUpdateHandler(owner, itemIdx, itemData) {
// debugger;
let updateChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
this.mediaModule.mediaChannels[itemIdx] = updateChannelInfo;
/* let updateChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
this.mediaModule.mediaChannels[itemIdx] = updateChannelInfo;
this._emit(MessageTypes.AUDIO_UPDATE, updateChannelInfo);*/
let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
let receiveChannelInfo={};
receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
//消息不是自己同步的,需要处理
if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
//正在推流
receiveChannelInfo.m3u8Url="";
receiveChannelInfo.rtmpUrl="";
let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
if(m3u8Stream.code==0){
receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
}
if(rtmpStream.code==0){
receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
}
loger.log("AUDIO_PLAY");
console.log(receiveChannelInfo);
//广播播放视频的消息
this._emit(MessageTypes.AUDIO_PLAY, receiveChannelInfo);
}else {
loger.log("AUDIO_STOP");
console.log(receiveChannelInfo);
//流已经停止
this._emit(MessageTypes.AUDIO_STOP, receiveChannelInfo);
}
}else {
loger.warn("消息是自己发送的或者是消息无效,不需要处理,消息内容如下:");
console.log(unpackChannelInfo);
this._emit(MessageTypes.AUDIO_UPDATE, updateChannelInfo);
}
}
///////数据的封包和解包/////////////////////////////////////////
... ... @@ -264,6 +306,7 @@ class AudioApe extends Ape {
let packPduModel = new pdu['RCAudioChannelInfoPdu'];
packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
packPduModel.channelId = _itemIdx;
packPduModel.streamId = _param.streamId||"";
packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;
packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
packPduModel.userId =_param.userId||"0";
... ... @@ -283,7 +326,7 @@ class AudioApe extends Ape {
}
try {
let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData);
loger.log("unPackPdu",packChannelInfo);
console.log(packChannelInfo);
return packChannelInfo;
} catch (err) {
loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
... ...
... ... @@ -548,7 +548,7 @@ class ConferApe extends Ape {
//广播当前的人数
emitRosterChange() {
this._emit(MessageTypes.CLASS_SHOW_ROSTER_NUM, Object.keys(this.rosters).length);
this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
}
///////数据的封包和解包/////////////////////////////////////////
... ...
... ... @@ -171,6 +171,7 @@ class DocApe extends Ape {
if(lastIndex>0){
let newPath=fullPath.substr(0,lastIndex);
let pathArr=[];
//页数从1开始
for(let i=1;i<=_param.pageNum;i++){
pathArr.push(newPath+"/"+i+"."+fileType);
}
... ... @@ -210,6 +211,8 @@ class DocApe extends Ape {
//切换文档
documentSwitchDoc(paramInfo){
loger.log('切换文档,documentSwitchDoc');
console.log(paramInfo);
if(paramInfo==null||paramInfo.itemIdx==null){
loger.warn('documentSwitch失败,参数错误',paramInfo);
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -257,6 +260,8 @@ class DocApe extends Ape {
//文档翻页
documentSwitchPage(paramInfo){
loger.log('文档翻页,documentSwitchPage');
console.log(paramInfo);
//console.log(this.docList);
//获取已经存在的数据
let docDataModel= this.docList[paramInfo.itemIdx];
... ...
... ... @@ -12,6 +12,7 @@ let loger = Loger.getLoger('MediaModule');
class MediaModule {
constructor() {
this.needPublishMediaChannel={};//记录准备推流的频道信息
this.mediaChannels = {};
this.maxMediaChannel=0;
this.MEDIA_OBJ_TABLE_ID=0;
... ... @@ -20,9 +21,7 @@ class MediaModule {
//获取播流地址
getMediaPlayPath(_param) {
loger.log('getMediaPlayPath');
if (_param == null||_param.siteId == null||
_param.classId == null||_param.userId == null||
_param.channelId == null|| _param.timestamp==null)
if (_param == null||_param.streamId == null)
{
loger.warn('getMediaPlayPath,参数错误', _param);
//this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -37,21 +36,13 @@ class MediaModule {
port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort;
path = "http://" + GlobalConfig.RSServerIP
+ port + "/live/"
+ _param.siteId
+ "_" + _param.classId
+ "_" + _param.userId
+ "_" + _param.channelId
+ "_" + _param.timestamp
+ _param.streamId
+ "/index.m3u8";
} else {
port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort;
path = "rtmp://" + GlobalConfig.MSServerIP
+ port + "/live/"
+ _param.siteId
+ "_" + _param.classId
+ "_" + _param.userId
+ "_" + _param.channelId
+ "_" + _param.timestamp;
+ _param.streamId;
}
return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
}
... ... @@ -77,18 +68,21 @@ class MediaModule {
//时间戳
let timestamp = EngineUtils.creatTimestamp();
//生成推流地址和推流数据(同步数据的时候用)
let publishUrl = "rtmp://" + GlobalConfig.MSServerIP
+ port + "/"+pubType+"/" +GlobalConfig.siteId+"_"
let streamId=GlobalConfig.siteId+"_"
+ GlobalConfig.classId + "_"+GlobalConfig.userId
+"_" + freeChannel + "_" + timestamp;
//生成推流地址和推流数据(同步数据的时候用)
let publishUrl = "rtmp://" + GlobalConfig.MSServerIP
+ port + "/"+pubType+"/" +streamId;
this.needPublishMediaChannel[publishUrl]={
"channelId":freeChannel,
"publishUrl":publishUrl,
"streamId":streamId
};
return {"code": ApeConsts.RETURN_SUCCESS,
"data":"",
"siteId":GlobalConfig.siteId,
"classId":GlobalConfig.classId,
"userId":GlobalConfig.userId,
"channelId": freeChannel,
"timestamp": timestamp,
"publishUrl": publishUrl
};
}
... ... @@ -111,6 +105,11 @@ class MediaModule {
return 0;//没有空闲的
}
//获取准备推流的频道信息
getNeedPublishMediaChannel(_publishUrl){
return this.needPublishMediaChannel[_publishUrl];
}
//获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
getOpeningMediaChannel(_nodeId){
if(_nodeId==null||_nodeId==0){
... ...
... ... @@ -58,16 +58,19 @@ class VideoApe extends Ape {
return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
}
if (_param == null||_param.channelId == null||
_param.classId == null||_param.userId == null||_param.userId == ""||
_param.siteId == null|| _param.timestamp==null)
if (_param == null||_param.publishUrl == null)
{
loger.warn('publishVideo,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
}
loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
//根据推流的地址获取对应的频道信息
let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
if(needPublishChannelInfo==null){
loger.warn('publishVideo,推流数据已经无效', _param);
return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
}
//同一个nodeId只允许推一个流,如果已经推了就不能再推
if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){
... ... @@ -82,23 +85,22 @@ class VideoApe extends Ape {
return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"};
}
//判断当前的频道是否已经占用
if(this.mediaModule.checkChannelIsOpening(_param.channelId)){
loger.warn(_param.channelId,"频道已经被占用");
if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){
loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");
return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"};
}
let channelInfo={};
channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=_param.channelId;//freeChannel
channelInfo.timestamp=_param.timestamp;//EngineUtils.creatTimestamp();
channelInfo.classId=_param.classId;//GlobalConfig.classId;
channelInfo.siteId=_param.siteId;//GlobalConfig.siteId;
channelInfo.channelId=needPublishChannelInfo.channelId;
channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
channelInfo.toNodeId=0;
channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
channelInfo.userId=_param.userId;
this.sendTableUpdateHandler(channelInfo);
return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"}
}
... ... @@ -113,7 +115,7 @@ class VideoApe extends Ape {
loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
//_param如果为空,那么默认就是当前自己的nodeId,否则用_param
let nodeId;
if(_param&&parseInt(_param.nodeId)>=0){
if(_param&&parseInt(_param.nodeId)>0){
nodeId=parseInt(_param.nodeId);
}else {
nodeId=GlobalConfig.nodeId;
... ... @@ -121,8 +123,8 @@ class VideoApe extends Ape {
let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);
if (openingChannel == 0) {
loger.warn(nodeId,"stopPublishVideo,没有占用channel,不需要关闭");
return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"};
loger.warn(nodeId,"没有占用channel不需要处理");
return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
}
let channelInfo={};
... ... @@ -267,9 +269,44 @@ class VideoApe extends Ape {
tableUpdateHandler(owner, itemIdx, itemData) {
// debugger;
let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
this.mediaModule.mediaChannels[itemIdx] = videoChannelInfo;
this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
let receiveChannelInfo={};
receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
//消息不是自己同步的,需要处理
if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
//正在推流
receiveChannelInfo.m3u8Url="";
receiveChannelInfo.rtmpUrl="";
let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
if(m3u8Stream.code==0){
receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
}
if(rtmpStream.code==0){
receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
}
loger.log("VIDEO_PLAY");
console.log(receiveChannelInfo);
//广播播放视频的消息
this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);
}else {
loger.log("VIDEO_STOP");
console.log(receiveChannelInfo);
//流已经停止
this._emit(MessageTypes.VIDEO_STOP, receiveChannelInfo);
}
}else {
loger.warn("视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:");
console.log(unpackChannelInfo);
}
//this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
}
///////数据的封包和解包/////////////////////////////////////////
... ... @@ -285,6 +322,7 @@ class VideoApe extends Ape {
let packPduModel = new pdu['RCVideoChannelInfoPdu'];
packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
packPduModel.channelId = _itemIdx;
packPduModel.streamId = _param.streamId||"";
packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;
packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
packPduModel.userId =_param.userId||"0";
... ... @@ -305,7 +343,7 @@ class VideoApe extends Ape {
try {
let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
loger.log("unPackPdu",videoChannelInfo);
console.log(videoChannelInfo);
return videoChannelInfo;
} catch (err) {
loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
... ...
... ... @@ -98,7 +98,7 @@ class MCU extends Emiter {
case PduConsts.RET_SUCCESS:
//加入成功
this._updateMCUConfInfoDescription(joinConfPdu.classDescription);
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, this.classInfo);
this._emit(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this.classInfo);
break;
case PduConsts.RET_FULL_CAPACITY:
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FULL);
... ...
... ... @@ -776,6 +776,7 @@ message RCAudioChannelInfoPdu {
optional uint32 class_id = 7;//课堂号
optional string site_id = 8;//站点号
optional string user_id = 9;//用户的userId
optional string stream_id = 10;//流名称
}
message RCVideoChannelInfoPdu {
... ... @@ -788,6 +789,7 @@ message RCVideoChannelInfoPdu {
optional uint32 class_id = 7;//课堂号
optional string site_id = 8;//站点号
optional string user_id = 9;//用户的userId
optional string stream_id = 10;//流名称
}
message RCVideoChannelInfoRecordPdu {
... ...