李勇

1.修改视频模块推流播流地址的拼接

@@ -41,8 +41,6 @@ let _joinClassSuccessCallBackFun; @@ -41,8 +41,6 @@ let _joinClassSuccessCallBackFun;
41 //监听mcu所有错误异常回调函数 41 //监听mcu所有错误异常回调函数
42 let _mcuErrorCallBackFun; 42 let _mcuErrorCallBackFun;
43 43
44 -let leaveDelay;  
45 -  
46 //MCUClient 外部实例化主类 44 //MCUClient 外部实例化主类
47 export default class MessageEntrance extends Emiter { 45 export default class MessageEntrance extends Emiter {
48 constructor() { 46 constructor() {
@@ -54,10 +52,9 @@ export default class MessageEntrance extends Emiter { @@ -54,10 +52,9 @@ export default class MessageEntrance extends Emiter {
54 //初始化状态 52 //初始化状态
55 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_0); 53 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_0);
56 54
  55 + //全局的Error处理
57 this.on(MessageTypes.MCU_ERROR, this._mcuErrorHandler.bind(this)); 56 this.on(MessageTypes.MCU_ERROR, this._mcuErrorHandler.bind(this));
58 57
59 - //this.on(MessageTypes.DOC_SHOW, this.docShowHandler.bind(this));  
60 -  
61 // Sass平台层 58 // Sass平台层
62 _sass = Sass; 59 _sass = Sass;
63 _sass.on('*', (type, data) => this._emit(type, data)); 60 _sass.on('*', (type, data) => this._emit(type, data));
@@ -79,6 +76,7 @@ export default class MessageEntrance extends Emiter { @@ -79,6 +76,7 @@ export default class MessageEntrance extends Emiter {
79 _confer_ape.on('*', (type, data) => this._emit(type, data)); 76 _confer_ape.on('*', (type, data) => this._emit(type, data));
80 _confer_ape.on(MessageTypes.CLASS_EXIT, this._doClassExit.bind(this));//监听自己的关闭事件 77 _confer_ape.on(MessageTypes.CLASS_EXIT, this._doClassExit.bind(this));//监听自己的关闭事件
81 _confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变 78 _confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变
  79 + _confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前会议人员离开
82 80
83 _chat_ape = new ChatApe(); 81 _chat_ape = new ChatApe();
84 _chat_ape.on('*', (type, data) => this._emit(type, data)); 82 _chat_ape.on('*', (type, data) => this._emit(type, data));
@@ -174,6 +172,18 @@ export default class MessageEntrance extends Emiter { @@ -174,6 +172,18 @@ export default class MessageEntrance extends Emiter {
174 _onClassStatusInfoChange(_param) { 172 _onClassStatusInfoChange(_param) {
175 this._sassSaveClassStatusInfo(); 173 this._sassSaveClassStatusInfo();
176 } 174 }
  175 + //有人员离开
  176 + _onClassDeleteRoster(_data){
  177 + //{"nodeId":nodeId}
  178 + //当有人员离开的时候,如果离开的人员已经推流,那么需要停止推流,然后释放channel;
  179 + //只有自己是主持人的时候出才处理下面的事情
  180 + if(_data!=null&&_data.nodeId!=null&&GlobalConfig.isHost){
  181 + loger.log("有人员离开,检查一下离开的人员是否关闭推流");
  182 + if(_video_ape){
  183 + _video_ape.stopPublishVideo(_data.nodeId);
  184 + }
  185 + }
  186 + }
177 187
178 //Sass 188 //Sass
179 //初始化 189 //初始化
@@ -615,12 +625,15 @@ export default class MessageEntrance extends Emiter { @@ -615,12 +625,15 @@ export default class MessageEntrance extends Emiter {
615 } 625 }
616 // 离开会议 626 // 离开会议
617 _leaveClass() { 627 _leaveClass() {
  628 + //停止推流
618 if(_video_ape){ 629 if(_video_ape){
619 _video_ape.stopPublishVideo(); 630 _video_ape.stopPublishVideo();
620 } 631 }
  632 + //离开会议
621 if(_confer_ape){ 633 if(_confer_ape){
622 _confer_ape.leaveClass(); 634 _confer_ape.leaveClass();
623 } 635 }
  636 + //断开MCU连接
624 if(_mcu){ 637 if(_mcu){
625 _mcu.leaveMCU(); 638 _mcu.leaveMCU();
626 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3); 639 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
@@ -757,36 +770,6 @@ export default class MessageEntrance extends Emiter { @@ -757,36 +770,6 @@ export default class MessageEntrance extends Emiter {
757 _doc_ape.documentDeleteAll(_param); 770 _doc_ape.documentDeleteAll(_param);
758 } 771 }
759 } 772 }
760 -/* // 白板笔记更新(svg)  
761 - annoUpdateHandler(annoInfo) {  
762 - const activeDocId = _confer_ape.activeDocId;  
763 - const docItem = _doc_ape.docList[activeDocId];  
764 - if (docItem && annoInfo.id == docItem.wbid) {  
765 - this._emit(MessageTypes.DOC_ANNOTATION, annoInfo);  
766 - }  
767 - }*/  
768 -  
769 -/* // 文档变更-笔记处理  
770 - docShowHandler(docItem) {  
771 - loger.log('Doc Show ->' + docItem.id + '|' + docItem.curPageNo);  
772 - const annoInfo = _whiteboard_ape.annoInfos[docItem.wbid];  
773 - if (annoInfo) {  
774 - this._emit(MessageTypes.DOC_ANNOTATION, annoInfo);  
775 - } else {  
776 - this._emit(MessageTypes.DOC_ANNOTATION);  
777 -  
778 - }  
779 - }*/  
780 -  
781 -/* // 文档切换  
782 - docSwitchHandler() {  
783 - const activeDocId = _confer_ape.activeDocId;  
784 - loger.log('Switch Doc Active -> ' + activeDocId);  
785 - const docItem = _doc_ape.docList[activeDocId];  
786 - if (docItem) {  
787 - this._emit(MessageTypes.DOC_SHOW, docItem);  
788 - }  
789 - }*/  
790 773
791 //// 文档变更,白板也需要做处理 774 //// 文档变更,白板也需要做处理
792 docUpdateHandler(_data) { 775 docUpdateHandler(_data) {
@@ -804,7 +787,6 @@ export default class MessageEntrance extends Emiter { @@ -804,7 +787,6 @@ export default class MessageEntrance extends Emiter {
804 } 787 }
805 } 788 }
806 789
807 -  
808 //文档加入频道成功,同步到MCU服务器上的数据 790 //文档加入频道成功,同步到MCU服务器上的数据
809 docJoinChannelSuccess(){ 791 docJoinChannelSuccess(){
810 loger.log("docJoinChannelSuccess isHost=",GlobalConfig.isHost); 792 loger.log("docJoinChannelSuccess isHost=",GlobalConfig.isHost);
@@ -2,6 +2,7 @@ import EngineEntrance from 'EngineEntrance'; @@ -2,6 +2,7 @@ import EngineEntrance from 'EngineEntrance';
2 import MessageTypes from 'MessageTypes'; 2 import MessageTypes from 'MessageTypes';
3 3
4 const MCU_CLIENT=new EngineEntrance(); 4 const MCU_CLIENT=new EngineEntrance();
  5 +
5 export function createMcuClient() { 6 export function createMcuClient() {
6 return MCU_CLIENT; 7 return MCU_CLIENT;
7 } 8 }
@@ -460,7 +460,8 @@ class ConferApe extends Ape { @@ -460,7 +460,8 @@ class ConferApe extends Ape {
460 460
461 //视频模块发生更新,人员状态需要更新 461 //视频模块发生更新,人员状态需要更新
462 updaterRosterStatus(_param){ 462 updaterRosterStatus(_param){
463 - loger.log("视频模块发生更新,人员状态需要更新",_param); 463 + loger.log("视频模块发生更新,人员状态需要更新");
  464 + console.log(_param);
464 //如果是自己。改变自己的状态同步到MCU 465 //如果是自己。改变自己的状态同步到MCU
465 } 466 }
466 //删除用户 467 //删除用户
@@ -46,17 +46,35 @@ class VideoChat extends Ape { @@ -46,17 +46,35 @@ class VideoChat extends Ape {
46 //获取播流地址 46 //获取播流地址
47 getPlayVideoPath(_param) { 47 getPlayVideoPath(_param) {
48 loger.log('getPlayVideoPath'); 48 loger.log('getPlayVideoPath');
49 - if (_param == null||_param.classId == null||_param.channelId == null|| _param.timestamp==null) { 49 + if (_param == null||_param.siteId == null||
  50 + _param.classId == null||_param.userId == null||
  51 + _param.channelId == null|| _param.timestamp==null)
  52 + {
50 loger.warn('getPlayVideoPath,参数错误', _param); 53 loger.warn('getPlayVideoPath,参数错误', _param);
51 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 54 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
52 - return {"code": 1, "data": "getPlayVideoPath,参数错误"}; 55 + return {"code": 1, "data": ""};
53 } 56 }
  57 +
54 let path = ""; 58 let path = "";
55 if (_param.type == "m3u8") { 59 if (_param.type == "m3u8") {
56 - path = "http://" + GlobalConfig.MSServerIP + ":80" + "/hls/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp + ".m3u8"; 60 + //M3U8 默认用80端口
  61 + //http://123.56.73.119/hls/h5dev_403074980_0_983042_1487641745/index.m3u8
  62 + path = "http://" + GlobalConfig.MSServerIP
  63 + +"/hls/" + _param.siteId
  64 + + "_" + _param.classId
  65 + + "_" + _param.userId
  66 + + "_" + _param.channelId
  67 + + "_" + _param.timestamp
  68 + + "/index.m3u8";
57 } else { 69 } else {
58 let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort; 70 let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
59 - path = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp; 71 + path = "rtmp://" + GlobalConfig.MSServerIP
  72 + + port + "/live/"
  73 + + _param.siteId
  74 + + "_" + _param.classId
  75 + + "_" + _param.userId
  76 + + "_" + _param.channelId
  77 + + "_" + _param.timestamp;
60 } 78 }
61 return {"code": 0, "data": path}; 79 return {"code": 0, "data": path};
62 } 80 }
@@ -77,8 +95,8 @@ class VideoChat extends Ape { @@ -77,8 +95,8 @@ class VideoChat extends Ape {
77 95
78 let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort; 96 let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
79 let timestamp = EngineUtils.creatTimestamp(); 97 let timestamp = EngineUtils.creatTimestamp();
80 - let publishUrl = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + GlobalConfig.classId + "_" + freeChannel + "_" + timestamp;  
81 - return {"code": 0, "data": {"channelId": freeChannel, "timestamp": timestamp, "publishUrl": publishUrl}}; 98 + let publishUrl = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" +GlobalConfig.siteId+"_"+ GlobalConfig.classId + "_"+GlobalConfig.userId+"_" + freeChannel + "_" + timestamp;
  99 + return {"code": 0, "data": {"siteId":GlobalConfig.siteId,"classId":GlobalConfig.classId,"userId":GlobalConfig.userId,"channelId": freeChannel, "timestamp": timestamp, "publishUrl": publishUrl}};
82 } 100 }
83 101
84 //推流 102 //推流
@@ -107,13 +125,16 @@ class VideoChat extends Ape { @@ -107,13 +125,16 @@ class VideoChat extends Ape {
107 this.sendTableUpdateHandler(channelInfo); 125 this.sendTableUpdateHandler(channelInfo);
108 } 126 }
109 127
110 - //停止推流 128 + //停止推流
111 stopPublishVideo(_param) { 129 stopPublishVideo(_param) {
112 loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); 130 loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
113 - let openingChannel = this.getOpeningVideoChannel(GlobalConfig.nodeId); 131 + //_param如果为空,那么默认就是当前自己的nodeId,否则用_param
  132 + let nodeId=_param||GlobalConfig.nodeId;
  133 +
  134 + let openingChannel = this.getOpeningVideoChannel(nodeId);
114 if (openingChannel == 0) { 135 if (openingChannel == 0) {
115 - loger.warn("stopPublishVideo,没有打开的channel");  
116 - return {"code": 1, "data": "没有打开的设备channel"}; 136 + loger.warn(nodeId,"stopPublishVideo,没有打开的channel,不需要关闭");
  137 + return {"code": 1, "data": "没有打开的channel,不需要关闭"};
117 } 138 }
118 139
119 let channelInfo={}; 140 let channelInfo={};
@@ -196,6 +217,10 @@ class VideoChat extends Ape { @@ -196,6 +217,10 @@ class VideoChat extends Ape {
196 // return; 217 // return;
197 //} 218 //}
198 let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2); 219 let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
  220 + if(updateModelPdu==null){
  221 + loger.warn("sendTableUpdateHandler error,updateModelPdu=null");
  222 + return;
  223 + }
199 224
200 let tableItemPdu = new pdu['RCRegistryTableItemPdu']; 225 let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
201 tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2; 226 tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;