李勇

1.调整视频模块,把视频和音频模块共用的功能单独分离出来

@@ -91,7 +91,7 @@ export default class MessageEntrance extends Emiter { @@ -91,7 +91,7 @@ export default class MessageEntrance extends Emiter {
91 91
92 _audio_ape= new AudioApe(); 92 _audio_ape= new AudioApe();
93 _audio_ape.on('*', (type, data) => this._emit(type, data)); 93 _audio_ape.on('*', (type, data) => this._emit(type, data));
94 - _audio_ape.on(MessageTypes.AUDIO_UPDATE, this.videoUpdate.bind(this)); 94 + _audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));
95 95
96 _whiteboard_ape = new WhiteBoardApe(); 96 _whiteboard_ape = new WhiteBoardApe();
97 _whiteboard_ape.on('*', (type, data) => this._emit(type, data)); 97 _whiteboard_ape.on('*', (type, data) => this._emit(type, data));
@@ -198,7 +198,7 @@ export default class MessageEntrance extends Emiter { @@ -198,7 +198,7 @@ export default class MessageEntrance extends Emiter {
198 _video_ape.stopPublishVideo(_data); 198 _video_ape.stopPublishVideo(_data);
199 } 199 }
200 if(_audio_ape){ 200 if(_audio_ape){
201 - _video_ape.stopPublishAudio(_data); 201 + _audio_ape.stopPublishAudio(_data);
202 } 202 }
203 } 203 }
204 } 204 }
@@ -206,15 +206,15 @@ export default class MessageEntrance extends Emiter { @@ -206,15 +206,15 @@ export default class MessageEntrance extends Emiter {
206 //当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel 206 //当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
207 //的占用状态导致,对于这种情况,需要释放掉 207 //的占用状态导致,对于这种情况,需要释放掉
208 _onClassNonentityRoster(_param){ 208 _onClassNonentityRoster(_param){
209 - if(_param==null||_param.fromNodeId==null){ 209 + if(_param==null||_param.nodeId==null){
210 loger.warn("onClassNonentityRoster.参数错误") 210 loger.warn("onClassNonentityRoster.参数错误")
211 return; 211 return;
212 } 212 }
213 if(_video_ape){ 213 if(_video_ape){
214 - _video_ape.stopPublishVideo({"nodeId":_param.fromNodeId}); 214 + _video_ape.stopPublishVideo({"nodeId":_param.nodeId});
215 } 215 }
216 if(_audio_ape){ 216 if(_audio_ape){
217 - _audio_ape.stopPublishAudio({"nodeId":_param.fromNodeId}); 217 + _audio_ape.stopPublishAudio({"nodeId":_param.nodeId});
218 } 218 }
219 } 219 }
220 220
@@ -738,7 +738,7 @@ export default class MessageEntrance extends Emiter { @@ -738,7 +738,7 @@ export default class MessageEntrance extends Emiter {
738 738
739 //AudioApe 739 //AudioApe
740 audioUpdate(_data){ 740 audioUpdate(_data){
741 - //频同步的消息发送改变,需要通知ferApe模块中的用户更新状态 741 + //频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
742 if(_confer_ape){ 742 if(_confer_ape){
743 _confer_ape.updaterRosterStatus(_data); 743 _confer_ape.updaterRosterStatus(_data);
744 } 744 }
  1 +//对外暴露的对象
  2 +
  3 +
1 import EngineEntrance from 'EngineEntrance'; 4 import EngineEntrance from 'EngineEntrance';
2 import MessageTypes from 'MessageTypes'; 5 import MessageTypes from 'MessageTypes';
3 6
4 -const MCU_CLIENT=new EngineEntrance(); 7 +const MCU_CLIENT=new EngineEntrance();//入口文件
5 8
6 export function createMcuClient() { 9 export function createMcuClient() {
7 return MCU_CLIENT; 10 return MCU_CLIENT;
8 } 11 }
9 12
  13 +//监听是事件名和异常定义
10 export {MessageTypes}; 14 export {MessageTypes};
@@ -454,7 +454,7 @@ class ConferApe extends Ape { @@ -454,7 +454,7 @@ class ConferApe extends Ape {
454 //视频模块发生更新,人员状态需要更新 454 //视频模块发生更新,人员状态需要更新
455 updaterRosterStatus(_param){ 455 updaterRosterStatus(_param){
456 if(_param){ 456 if(_param){
457 - loger.log("视频模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); 457 + loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId);
458 loger.log(_param.status,_param.fromNodeId,this.rosters[_param.fromNodeId]); 458 loger.log(_param.status,_param.fromNodeId,this.rosters[_param.fromNodeId]);
459 //console.log(_param.fromNodeId); 459 //console.log(_param.fromNodeId);
460 //如果是自己。改变自己的状态同步到MCU 460 //如果是自己。改变自己的状态同步到MCU
@@ -465,8 +465,8 @@ class ConferApe extends Ape { @@ -465,8 +465,8 @@ class ConferApe extends Ape {
465 465
466 //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 466 //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
467 if(_param.status==ApeConsts.CHANNEL_STATUS_OPENING&&this.rosters[_param.fromNodeId]==null){ 467 if(_param.status==ApeConsts.CHANNEL_STATUS_OPENING&&this.rosters[_param.fromNodeId]==null){
468 - loger.log("视频模块被占用,占有人已经不存在课堂中,释放Channel,_param->",_param);  
469 - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER,_param.fromNodeId); 468 + loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->",_param);
  469 + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER,{"nodeId":_param.fromNodeId});
470 } 470 }
471 } 471 }
472 } 472 }
1 // ////////////////////////////////////////////////////////////////////////////// 1 // //////////////////////////////////////////////////////////////////////////////
2 -//  
3 -// Copyright (C) 2016-present All Rights Reserved.  
4 -// Licensed under the Apache License, Version 2.0 (the "License");  
5 -// http://www.apache.org/licenses/LICENSE-2.0  
6 -//  
7 -// Github Home: https://github.com/AlexWang1987  
8 -// Author: AlexWang  
9 -// Date: 2016-08-23 18:07:28  
10 -// QQ Email: 1669499355@qq.com  
11 -// Last Modified time: 2016-09-06 11:13:59  
12 -// Description: LiveClass-VideoApe  
13 -// 2 +//视频模块
14 // ////////////////////////////////////////////////////////////////////////////// 3 // //////////////////////////////////////////////////////////////////////////////
15 4
16 import Ape from './Ape'; 5 import Ape from './Ape';
@@ -20,6 +9,7 @@ import Loger from 'Loger'; @@ -20,6 +9,7 @@ import Loger from 'Loger';
20 import MessageTypes from 'MessageTypes'; 9 import MessageTypes from 'MessageTypes';
21 import GlobalConfig from 'GlobalConfig'; 10 import GlobalConfig from 'GlobalConfig';
22 import EngineUtils from 'EngineUtils'; 11 import EngineUtils from 'EngineUtils';
  12 +import MediaModule from "./MediaModule";
23 13
24 let loger = Loger.getLoger('VideoApe'); 14 let loger = Loger.getLoger('VideoApe');
25 15
@@ -31,8 +21,9 @@ class VideoApe extends Ape { @@ -31,8 +21,9 @@ class VideoApe extends Ape {
31 ApeConsts.VIDEO_SESSION_TAG 21 ApeConsts.VIDEO_SESSION_TAG
32 ); 22 );
33 23
34 - //Attributes  
35 - this.videoChannels = {}; 24 + this.mediaModule=new MediaModule();
  25 + this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.VIDEO_OBJ_TABLE_ID;
  26 + this.mediaModule.mediaChannels={};
36 27
37 // Ape Models 28 // Ape Models
38 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); 29 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
@@ -41,84 +32,23 @@ class VideoApe extends Ape { @@ -41,84 +32,23 @@ class VideoApe extends Ape {
41 // videoApe 监听视频控制消息,用户之间的消息传递 32 // videoApe 监听视频控制消息,用户之间的消息传递
42 this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this)); 33 this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));
43 } 34 }
  35 + //ape加入成功
  36 + onJoinChannelHandlerSuccess(){
  37 + //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
  38 + this.mediaModule.maxMediaChannel=GlobalConfig.maxVideoChannels;
  39 + }
44 40
45 /////////////发送数据操作//////////////////////////////////////////// 41 /////////////发送数据操作////////////////////////////////////////////
46 //获取播流地址 42 //获取播流地址
47 getPlayVideoPath(_param) { 43 getPlayVideoPath(_param) {
48 loger.log('getPlayVideoPath'); 44 loger.log('getPlayVideoPath');
49 - if (_param == null||_param.siteId == null||  
50 - _param.classId == null||_param.userId == null||  
51 - _param.channelId == null|| _param.timestamp==null)  
52 - {  
53 - loger.warn('getPlayVideoPath,参数错误', _param);  
54 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
55 - return {"code": 1, "data": ""};  
56 - }  
57 -  
58 - let path = "";  
59 - let port="";  
60 - if (_param.type == "m3u8") {  
61 - //M3U8  
62 - //http://123.56.73.119:6001/hls/h5dev_403074980_0_983041_1487663265/index.m3u8  
63 - port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort;  
64 - path = "http://" + GlobalConfig.RSServerIP  
65 - + port + "/live/"  
66 - + _param.siteId  
67 - + "_" + _param.classId  
68 - + "_" + _param.userId  
69 - + "_" + _param.channelId  
70 - + "_" + _param.timestamp  
71 - + "/index.m3u8";  
72 - } else {  
73 - port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort;  
74 - path = "rtmp://" + GlobalConfig.MSServerIP  
75 - + port + "/live/"  
76 - + _param.siteId  
77 - + "_" + _param.classId  
78 - + "_" + _param.userId  
79 - + "_" + _param.channelId  
80 - + "_" + _param.timestamp;  
81 - }  
82 - return {"code": 0, "data": path}; 45 + return this.mediaModule.getMediaPlayPath(_param);
83 } 46 }
84 47
85 //获取推流地址 48 //获取推流地址
86 getPublishVideoPath(_param) { 49 getPublishVideoPath(_param) {
87 loger.log('getPublishVideoPath'); 50 loger.log('getPublishVideoPath');
88 -  
89 - //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启  
90 - let freeChannel = this.getFreeVideoChannel();  
91 - if (freeChannel == 0) {  
92 - return {"code": 1, "data": "不能再打开更多的设备"};  
93 - }  
94 -  
95 - //默认方式推流  
96 - let pubType="live";  
97 - //flash推流  
98 - if(_param&&_param.type=="flash"){  
99 - pubType ="flash";  
100 - }  
101 -  
102 - //端口,有端口就显示 ":xxx",没有端口就是""  
103 - let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort;  
104 - //时间戳  
105 - let timestamp = EngineUtils.creatTimestamp();  
106 -  
107 - //生成推流地址和推流数据(同步数据的时候用)  
108 - let publishUrl = "rtmp://" + GlobalConfig.MSServerIP  
109 - + port + "/"+pubType+"/" +GlobalConfig.siteId+"_"  
110 - + GlobalConfig.classId + "_"+GlobalConfig.userId  
111 - +"_" + freeChannel + "_" + timestamp;  
112 - return {"code": 0,  
113 - "data":  
114 - { "siteId":GlobalConfig.siteId,  
115 - "classId":GlobalConfig.classId,  
116 - "userId":GlobalConfig.userId,  
117 - "channelId": freeChannel,  
118 - "timestamp": timestamp,  
119 - "publishUrl": publishUrl  
120 - }  
121 - }; 51 + return this.mediaModule.getMediaPublishPath(_param);
122 } 52 }
123 53
124 //推流 54 //推流
@@ -135,20 +65,20 @@ class VideoApe extends Ape { @@ -135,20 +65,20 @@ class VideoApe extends Ape {
135 loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); 65 loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
136 66
137 //同一个nodeId只允许推一个流,如果已经推了就不能再推 67 //同一个nodeId只允许推一个流,如果已经推了就不能再推
138 - if(this.getOpeningVideoChannel(GlobalConfig.nodeId)!=0){ 68 + if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){
139 loger.warn("publishVideo,已经存在一个流,不能再推"); 69 loger.warn("publishVideo,已经存在一个流,不能再推");
140 return; 70 return;
141 } 71 }
142 72
143 //判断当前是否还有空闲的channle 73 //判断当前是否还有空闲的channle
144 - let freeChannel = this.getFreeVideoChannel(); 74 + let freeChannel = this.mediaModule.getFreeMediaChannel();
145 if (freeChannel == 0) { 75 if (freeChannel == 0) {
146 loger.warn("publishVideo,没有空闲的channel "); 76 loger.warn("publishVideo,没有空闲的channel ");
147 return {"code": 1, "data": "不能再打开更多的设备"}; 77 return {"code": 1, "data": "不能再打开更多的设备"};
148 } 78 }
149 79
150 //判断当前的频道是否已经占用 80 //判断当前的频道是否已经占用
151 - if(this.checkChannelIsOpening(_param.channelId)){ 81 + if(this.mediaModule.checkChannelIsOpening(_param.channelId)){
152 loger.warn(_param.channelId,"频道已经被占用"); 82 loger.warn(_param.channelId,"频道已经被占用");
153 return {"code":1,"data":"频道已经被占用!"}; 83 return {"code":1,"data":"频道已经被占用!"};
154 } 84 }
@@ -177,7 +107,7 @@ class VideoApe extends Ape { @@ -177,7 +107,7 @@ class VideoApe extends Ape {
177 nodeId=GlobalConfig.nodeId; 107 nodeId=GlobalConfig.nodeId;
178 } 108 }
179 109
180 - let openingChannel = this.getOpeningVideoChannel(nodeId); 110 + let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);
181 if (openingChannel == 0) { 111 if (openingChannel == 0) {
182 loger.warn(nodeId,"stopPublishVideo,没有打开的channel,不需要关闭"); 112 loger.warn(nodeId,"stopPublishVideo,没有打开的channel,不需要关闭");
183 return {"code": 1, "data": "没有打开的channel,不需要关闭"}; 113 return {"code": 1, "data": "没有打开的channel,不需要关闭"};
@@ -214,7 +144,7 @@ class VideoApe extends Ape { @@ -214,7 +144,7 @@ class VideoApe extends Ape {
214 144
215 if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) { 145 if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {
216 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 146 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
217 - let freeChannel = this.getFreeVideoChannel(); 147 + let freeChannel = this.mediaModule.getFreeMediaChannel();
218 if (freeChannel == 0) { 148 if (freeChannel == 0) {
219 loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param); 149 loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param);
220 return {"code": 1, "data": "不能再打开更多的设备"}; 150 return {"code": 1, "data": "不能再打开更多的设备"};
@@ -325,7 +255,7 @@ class VideoApe extends Ape { @@ -325,7 +255,7 @@ class VideoApe extends Ape {
325 //videoChannelInfo.channelId = itemIdx; 255 //videoChannelInfo.channelId = itemIdx;
326 //videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status; 256 //videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status;
327 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo); 257 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
328 - this.videoChannels[itemIdx] = videoChannelInfo; 258 + this.mediaModule.mediaChannels[itemIdx] = videoChannelInfo;
329 259
330 this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo); 260 this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
331 /* switch (videoChannelInfo.status) { 261 /* switch (videoChannelInfo.status) {
@@ -403,52 +333,6 @@ class VideoApe extends Ape { @@ -403,52 +333,6 @@ class VideoApe extends Ape {
403 } 333 }
404 return null; 334 return null;
405 } 335 }
406 -  
407 - //获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId  
408 - getFreeVideoChannel() {  
409 - loger.log("getFreeVideoChannel");  
410 - console.log(this.videoChannels);  
411 - let counter = 0;  
412 - for (let key in this.videoChannels) {  
413 - let item = this.videoChannels[key];  
414 - if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) {  
415 - return item.channelId;  
416 - }  
417 - counter++;  
418 - }  
419 - if (counter < GlobalConfig.maxVideoChannels) {  
420 - return ApeConsts.VIDEO_OBJ_TABLE_ID + (counter);  
421 - }  
422 - return 0;//没有空闲的  
423 - }  
424 -  
425 - //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId  
426 - getOpeningVideoChannel(_nodeId){  
427 - if(_nodeId==null||_nodeId==0){  
428 - return 0;  
429 - }  
430 - for (let key in this.videoChannels) {  
431 - let item = this.videoChannels[key];  
432 - if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) {  
433 - return item.channelId;  
434 - }  
435 - }  
436 - return 0;  
437 - }  
438 -  
439 - //检查频道是否已经被占用  
440 - checkChannelIsOpening(_channelId){  
441 - if(_channelId==null){  
442 - loger.warn("checkChannelIsOpening error,channel=",_channelId);  
443 - return true;  
444 - }  
445 -  
446 - let channelInfo=this.videoChannels[_channelId];  
447 - if(channelInfo==null||channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){  
448 - return false;  
449 - }  
450 - return true;  
451 - }  
452 } 336 }
453 337
454 export default VideoApe; 338 export default VideoApe;