李勇

1.音视频模块推流接口增加optionJsonData:{"bufferTime":0}} 用于设置播放流的时候的bufferTime

@@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter { @@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter {
58 constructor() { 58 constructor() {
59 super(); 59 super();
60 //sdk 信息 60 //sdk 信息
61 - GlobalConfig.sdkVersion = "v1.79.4.20170821"; 61 + GlobalConfig.sdkVersion = "v1.79.5.20170821";
62 loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); 62 loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
63 63
64 //设置 64 //设置
@@ -1796,7 +1796,6 @@ export default class MessageEntrance extends Emiter { @@ -1796,7 +1796,6 @@ export default class MessageEntrance extends Emiter {
1796 return {"code": ApeConsts.RETURN_FAILED, "data": ""}; 1796 return {"code": ApeConsts.RETURN_FAILED, "data": ""};
1797 } 1797 }
1798 if (_video_ape) { 1798 if (_video_ape) {
1799 - GlobalConfig.optionJsonData=_param.optionJsonData||"";  
1800 return _video_ape.publishVideo(_param); 1799 return _video_ape.publishVideo(_param);
1801 } 1800 }
1802 } 1801 }
@@ -1853,7 +1852,6 @@ export default class MessageEntrance extends Emiter { @@ -1853,7 +1852,6 @@ export default class MessageEntrance extends Emiter {
1853 return {"code": ApeConsts.RETURN_FAILED, "data": ""}; 1852 return {"code": ApeConsts.RETURN_FAILED, "data": ""};
1854 } 1853 }
1855 if (_audio_ape) { 1854 if (_audio_ape) {
1856 - GlobalConfig.optionJsonData=_param.optionJsonData||"";  
1857 return _audio_ape.publishAudio(_param); 1855 return _audio_ape.publishAudio(_param);
1858 } 1856 }
1859 } 1857 }
@@ -14,484 +14,521 @@ import MediaModule from "./MediaModule"; @@ -14,484 +14,521 @@ import MediaModule from "./MediaModule";
14 let loger = Loger.getLoger('AudioApe'); 14 let loger = Loger.getLoger('AudioApe');
15 15
16 class AudioApe extends Ape { 16 class AudioApe extends Ape {
17 - constructor() {  
18 - super(  
19 - ApeConsts.AUDIO_SESSION_ID,  
20 - ApeConsts.AUDIO_SESSION_NAME,  
21 - ApeConsts.AUDIO_SESSION_TAG  
22 - );  
23 -  
24 - this.releaseTimeId=0  
25 - this.mediaModule=new MediaModule();  
26 - this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.AUDIO_OBJ_TABLE_ID;  
27 - this.mediaModule.mediaChannels={};  
28 - this.mediaModule.mediaType=ApeConsts.MEDIA_TYPE_AUDIO;  
29 - // Ape Models  
30 - this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);  
31 - this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.AUDIO_OBJ_TABLE_ID, ApeConsts.AUDIO_OBJ_TABLE_NAME, ApeConsts.AUDIO_OBJ_TABLE_TAG, 0, new ArrayBuffer);  
32 -  
33 - // 广播消息,用户之间的消息传递  
34 - this.on(pdu.RCPDU_SEND_AUDIO_DATA_REQUEST, this.receiveAudiooCommandHandler.bind(this));  
35 - }  
36 - //ape加入成功  
37 - onJoinChannelHandlerSuccess(){  
38 - //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据  
39 - this.mediaModule.maxMediaChannel=GlobalConfig.maxAudioChannels;  
40 - }  
41 -  
42 - /////////////发送数据操作////////////////////////////////////////////  
43 - //获取播流地址  
44 - getAudioPlayPath(_param) {  
45 - loger.log('获取播流地址->');  
46 - return this.mediaModule.getMediaPlayPath(_param);  
47 - }  
48 -  
49 - //获取推流地址  
50 - getAudioPublishPath(_param) {  
51 - loger.log('获取推流地址->');  
52 - if(!this.mcu.connected){  
53 - loger.warn(GlobalConfig.getCurrentStatus());  
54 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};;  
55 - }  
56 - //监课比较特殊,不占用课堂内的音视频路数,额外创建  
57 - if(GlobalConfig.userRole==ApeConsts.invisible){  
58 - let result=this.mediaModule.getMediaPublishPathForInVisible(_param);  
59 - this._emit( MessageTypes.AUDIO_GET_PUBLISH_PATH,result);  
60 - return result;  
61 - }  
62 -  
63 - //非监课的身份,需要判断是否可以继续推流  
64 - //需要判断当前已经使用的流路数  
65 - let openChannel=0;  
66 - let allChannels= MediaModule.allMediaChannelsList;  
67 - for(let i in allChannels){  
68 - let channel=allChannels[i];  
69 - if(channel&&channel.status==ApeConsts.CHANNEL_STATUS_OPENING&&channel.userRole!=ApeConsts.invisible){  
70 - //正在开启的才计数,监课开启的不计算在内  
71 - openChannel++;  
72 - }  
73 - }  
74 - //如果已经开启的数量大于等于最大允许开启的数量,不允许再推流  
75 - if(openChannel>=GlobalConfig.maxMediaChannels){  
76 - loger.warn('不能再打开设备->当前开启的设备数量->',openChannel);  
77 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开设备,当前开启的设备数量"};  
78 - }  
79 -  
80 - let result=this.mediaModule.getMediaPublishPath(_param);  
81 - this._emit( MessageTypes.AUDIO_GET_PUBLISH_PATH,result);  
82 - return result; 17 + constructor() {
  18 + super(
  19 + ApeConsts.AUDIO_SESSION_ID,
  20 + ApeConsts.AUDIO_SESSION_NAME,
  21 + ApeConsts.AUDIO_SESSION_TAG
  22 + );
  23 +
  24 + this.releaseTimeId = 0
  25 + this.mediaModule = new MediaModule();
  26 + this.mediaModule.MEDIA_OBJ_TABLE_ID = ApeConsts.AUDIO_OBJ_TABLE_ID;
  27 + this.mediaModule.mediaChannels = {};
  28 + this.mediaModule.mediaType = ApeConsts.MEDIA_TYPE_AUDIO;
  29 + // Ape Models
  30 + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
  31 + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.AUDIO_OBJ_TABLE_ID, ApeConsts.AUDIO_OBJ_TABLE_NAME, ApeConsts.AUDIO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
  32 +
  33 + // 广播消息,用户之间的消息传递
  34 + this.on(pdu.RCPDU_SEND_AUDIO_DATA_REQUEST, this.receiveAudiooCommandHandler.bind(this));
  35 + }
  36 +
  37 + //ape加入成功
  38 + onJoinChannelHandlerSuccess() {
  39 + //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
  40 + this.mediaModule.maxMediaChannel = GlobalConfig.maxAudioChannels;
  41 + }
  42 +
  43 + /////////////发送数据操作////////////////////////////////////////////
  44 + //获取播流地址
  45 + getAudioPlayPath(_param) {
  46 + loger.log('获取播流地址->');
  47 + return this.mediaModule.getMediaPlayPath(_param);
  48 + }
  49 +
  50 + //获取推流地址
  51 + getAudioPublishPath(_param) {
  52 + loger.log('获取推流地址->');
  53 + if (!this.mcu.connected) {
  54 + loger.warn(GlobalConfig.getCurrentStatus());
  55 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  56 + ;
83 } 57 }
84 -  
85 - //获取当前所有频道信息  
86 - getAllChannelInfo(_param){  
87 - loger.log('获取当前所有频道信息->');  
88 - return this.mediaModule.getAllMediaChannelInfo(); 58 + //监课比较特殊,不占用课堂内的音视频路数,额外创建
  59 + if (GlobalConfig.userRole == ApeConsts.invisible) {
  60 + let result = this.mediaModule.getMediaPublishPathForInVisible(_param);
  61 + this._emit(MessageTypes.AUDIO_GET_PUBLISH_PATH, result);
  62 + return result;
89 } 63 }
90 64
91 - //推流  
92 - publishAudio(_param) {  
93 - if(!this.mcu.connected){  
94 - loger.warn(GlobalConfig.getCurrentStatus());  
95 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"已经断开连接!","mediaId":0});  
96 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接","mediaId":0};  
97 - }  
98 -  
99 - if (_param == null||_param.publishUrl == null)  
100 - {  
101 - loger.warn('推流->参数错误', _param);  
102 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
103 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"参数错误!","mediaId":0});  
104 - return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};  
105 - }  
106 -  
107 - //根据推流的地址获取对应的频道信息  
108 - let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);  
109 - if(needPublishChannelInfo==null){  
110 - loger.warn('推流->推流数据已经无效', _param);  
111 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"推流数据已经无效!","mediaId":0});  
112 - return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};  
113 - } 65 + //非监课的身份,需要判断是否可以继续推流
  66 + //需要判断当前已经使用的流路数
  67 + let openChannel = 0;
  68 + let allChannels = MediaModule.allMediaChannelsList;
  69 + for (let i in allChannels) {
  70 + let channel = allChannels[i];
  71 + if (channel && channel.status == ApeConsts.CHANNEL_STATUS_OPENING && channel.userRole != ApeConsts.invisible) {
  72 + //正在开启的才计数,监课开启的不计算在内
  73 + openChannel++;
  74 + }
  75 + }
  76 + //如果已经开启的数量大于等于最大允许开启的数量,不允许再推流
  77 + if (openChannel >= GlobalConfig.maxMediaChannels) {
  78 + loger.warn('不能再打开设备->当前开启的设备数量->', openChannel);
  79 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开设备,当前开启的设备数量"};
  80 + }
114 81
115 - //判断当前是否还有空闲的channle  
116 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
117 - if (freeChannel == 0) {  
118 - loger.warn("推流->不能再打开更多的设备");  
119 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaId":0});  
120 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
121 - } 82 + let result = this.mediaModule.getMediaPublishPath(_param);
  83 + this._emit(MessageTypes.AUDIO_GET_PUBLISH_PATH, result);
  84 + return result;
  85 + }
  86 +
  87 + //获取当前所有频道信息
  88 + getAllChannelInfo(_param) {
  89 + loger.log('获取当前所有频道信息->');
  90 + return this.mediaModule.getAllMediaChannelInfo();
  91 + }
  92 +
  93 + //推流
  94 + publishAudio(_param) {
  95 + if (!this.mcu.connected) {
  96 + loger.warn(GlobalConfig.getCurrentStatus());
  97 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接!", "mediaId": 0});
  98 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接", "mediaId": 0};
  99 + }
122 100
123 - //判断当前的频道是否已经占用  
124 - if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){  
125 - if(needPublishChannelInfo.nodeId==GlobalConfig.nodeId){  
126 - loger.warn(needPublishChannelInfo.channelId,"已经推送过消息,不需要再次推送!");  
127 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId});  
128 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId};  
129 - }else {  
130 - loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");  
131 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!","mediaId":0});  
132 - return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"};  
133 - } 101 + if (_param == null || _param.publishUrl == null) {
  102 + loger.warn('推流->参数错误', _param);
  103 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  104 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {"code": ApeConsts.RETURN_FAILED, "data": "参数错误!", "mediaId": 0});
  105 + return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
  106 + }
134 107
  108 + //获取可选参数,转换为JSON字符串
  109 + try {
  110 + GlobalConfig.optionJsonData = JSON.stringify(_param.optionJsonData) || ""
  111 + } catch (err) {
  112 + GlobalConfig.optionJsonData = "";
  113 + }
135 114
136 - } 115 + //根据推流的地址获取对应的频道信息
  116 + let needPublishChannelInfo = this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
  117 + if (needPublishChannelInfo == null) {
  118 + loger.warn('推流->推流数据已经无效', _param);
  119 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {
  120 + "code": ApeConsts.RETURN_FAILED,
  121 + "data": "推流数据已经无效!",
  122 + "mediaId": 0
  123 + });
  124 + return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
  125 + }
137 126
138 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
139 - channelInfo.owner=GlobalConfig.nodeId;  
140 - channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;  
141 - channelInfo.channelId=needPublishChannelInfo.channelId;//freeChannel  
142 - channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称  
143 - channelInfo.timestamp=needPublishChannelInfo.timestamp;//EngineUtils.creatTimestamp();  
144 - channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO;  
145 - this.sendTableUpdateHandler(channelInfo);  
146 - this._emit( MessageTypes.AUDIO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId});  
147 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId}; 127 + //判断当前是否还有空闲的channle
  128 + let freeChannel = this.mediaModule.getFreeMediaChannel();
  129 + if (freeChannel == 0) {
  130 + loger.warn("推流->不能再打开更多的设备");
  131 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {
  132 + "code": ApeConsts.RETURN_FAILED,
  133 + "data": "不能再打开更多的设备",
  134 + "mediaId": 0
  135 + });
  136 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备", "mediaChannels": this.mediaModule.mediaChannels};
148 } 137 }
149 138
150 - //停止推流,  
151 - stopPublishAudio(_param) {  
152 - loger.log('停止推流 ->',_param);  
153 - if(!this.mcu.connected){  
154 - loger.warn(GlobalConfig.getCurrentStatus());  
155 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
156 - } 139 + //判断当前的频道是否已经占用
  140 + if (this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)) {
  141 + if (needPublishChannelInfo.nodeId == GlobalConfig.nodeId) {
  142 + loger.warn(needPublishChannelInfo.channelId, "已经推送过消息,不需要再次推送!");
  143 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {
  144 + "code": ApeConsts.RETURN_SUCCESS,
  145 + "data": "已经推送过消息,不需要再次推送!",
  146 + "mediaId": needPublishChannelInfo.channelId
  147 + });
  148 + return {
  149 + "code": ApeConsts.RETURN_SUCCESS,
  150 + "data": "已经推送过消息,不需要再次推送!",
  151 + "mediaId": needPublishChannelInfo.channelId
  152 + };
  153 + } else {
  154 + loger.warn(needPublishChannelInfo.channelId, "频道已经被占用");
  155 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {
  156 + "code": ApeConsts.RETURN_FAILED,
  157 + "data": "频道已经被占用!",
  158 + "mediaId": 0
  159 + });
  160 + return {"code": ApeConsts.RETURN_FAILED, "data": "频道已经被占用!"};
  161 + }
157 162
158 - //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param  
159 - let nodeId=GlobalConfig.nodeId;  
160 - if(_param&&parseInt(_param.nodeId)>0){  
161 - nodeId=parseInt(_param.nodeId);  
162 - }  
163 163
164 - //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道  
165 - let releaseChannelId=0;  
166 - if(_param&&parseInt(_param.mediaId)>0){  
167 - releaseChannelId=parseInt(_param.mediaId);  
168 - } 164 + }
169 165
170 - //释放channelId 的占用  
171 - if(releaseChannelId>0){  
172 - //第一种情况,释放nodeId占用的指定mediaId (channelId)  
173 - this._releaseChannelForNodeId(nodeId,releaseChannelId);  
174 - }else {  
175 - //第二种情况,释放nodeId占用的所有channelId  
176 - this._releaseNodeIdAllChannel(nodeId);  
177 - } 166 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  167 + channelInfo.owner = GlobalConfig.nodeId;
  168 + channelInfo.status = ApeConsts.CHANNEL_STATUS_OPENING;
  169 + channelInfo.channelId = needPublishChannelInfo.channelId;//freeChannel
  170 + channelInfo.streamId = needPublishChannelInfo.streamId;//按规则拼接的流名称
  171 + channelInfo.timestamp = needPublishChannelInfo.timestamp;//EngineUtils.creatTimestamp();
  172 + channelInfo.mediaType = ApeConsts.MEDIA_TYPE_AUDIO;
  173 + this.sendTableUpdateHandler(channelInfo);
  174 + this._emit(MessageTypes.AUDIO_PUBLISH_RESULT, {
  175 + "code": ApeConsts.RETURN_SUCCESS,
  176 + "data": "推流成功!",
  177 + "mediaId": needPublishChannelInfo.channelId
  178 + });
  179 + return {"code": ApeConsts.RETURN_SUCCESS, "data": "推流成功!", "mediaId": needPublishChannelInfo.channelId};
  180 + }
  181 +
  182 + //停止推流,
  183 + stopPublishAudio(_param) {
  184 + loger.log('停止推流 ->', _param);
  185 + if (!this.mcu.connected) {
  186 + loger.warn(GlobalConfig.getCurrentStatus());
  187 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
178 } 188 }
179 189
180 - //释放nodeId占用的指定的channelId频道  
181 - _releaseChannelForNodeId(nodeId,channelId){  
182 - loger.log(nodeId,"释放占用的频道-->",channelId);  
183 - let channelInfo=this.mediaModule.mediaChannels[channelId];  
184 - if(channelInfo&&channelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
185 - if(channelInfo.fromNodeId==nodeId){ 190 + //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param
  191 + let nodeId = GlobalConfig.nodeId;
  192 + if (_param && parseInt(_param.nodeId) > 0) {
  193 + nodeId = parseInt(_param.nodeId);
  194 + }
186 195
187 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
188 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
189 - channelInfo.channelId=channelId; 196 + //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道
  197 + let releaseChannelId = 0;
  198 + if (_param && parseInt(_param.mediaId) > 0) {
  199 + releaseChannelId = parseInt(_param.mediaId);
  200 + }
190 201
191 - this.sendTableUpdateHandler(channelInfo);  
192 - }else {  
193 - loger.warn(channelId,"不属于nodeId",nodeId,"不能释放",channelInfo);  
194 - }  
195 - }else {  
196 - loger.warn(nodeId,"要释放的频道不存在或者已经释放-->channelId",channelInfo);  
197 - } 202 + //释放channelId 的占用
  203 + if (releaseChannelId > 0) {
  204 + //第一种情况,释放nodeId占用的指定mediaId (channelId)
  205 + this._releaseChannelForNodeId(nodeId, releaseChannelId);
  206 + } else {
  207 + //第二种情况,释放nodeId占用的所有channelId
  208 + this._releaseNodeIdAllChannel(nodeId);
198 } 209 }
199 - //释放nodeId占用的所有频道  
200 - _releaseNodeIdAllChannel(nodeId){  
201 - loger.log(nodeId,"_releaseNodeIdAllChannel",this.mcu.connected);  
202 - if(!this.mcu.connected){  
203 - clearTimeout(this.releaseTimeId);  
204 - loger.warn(GlobalConfig.getCurrentStatus());  
205 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
206 - } 210 + }
207 211
208 - let openingChannelInfo = this.mediaModule.getOpeningMediaChannelForNodeId(nodeId);  
209 - if (openingChannelInfo.channelId == 0) {  
210 - loger.warn(nodeId,"没有占用频道不需要处理");  
211 - return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};  
212 - } 212 + //释放nodeId占用的指定的channelId频道
  213 + _releaseChannelForNodeId(nodeId, channelId) {
  214 + loger.log(nodeId, "释放占用的频道-->", channelId);
  215 + let channelInfo = this.mediaModule.mediaChannels[channelId];
  216 + if (channelInfo && channelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  217 + if (channelInfo.fromNodeId == nodeId) {
213 218
214 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
215 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
216 - channelInfo.channelId=openingChannelInfo.channelId;  
217 - channelInfo.nodeId=openingChannelInfo.fromNodeId;  
218 - channelInfo.userRole=openingChannelInfo.userRole;  
219 - channelInfo.userName=openingChannelInfo.userName;  
220 - channelInfo.userId=openingChannelInfo.userId; 219 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  220 + channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  221 + channelInfo.channelId = channelId;
221 222
222 this.sendTableUpdateHandler(channelInfo); 223 this.sendTableUpdateHandler(channelInfo);
223 - //递归检查,800毫秒之后执行  
224 - this.releaseTimeId=setTimeout(function(){  
225 - loger.warn(nodeId,"检查频道是否占用");  
226 - this._releaseNodeIdAllChannel(nodeId);  
227 - }.bind(this),800); 224 + } else {
  225 + loger.warn(channelId, "不属于nodeId", nodeId, "不能释放", channelInfo);
  226 + }
  227 + } else {
  228 + loger.warn(nodeId, "要释放的频道不存在或者已经释放-->channelId", channelInfo);
  229 + }
  230 + }
  231 +
  232 + //释放nodeId占用的所有频道
  233 + _releaseNodeIdAllChannel(nodeId) {
  234 + loger.log(nodeId, "_releaseNodeIdAllChannel", this.mcu.connected);
  235 + if (!this.mcu.connected) {
  236 + clearTimeout(this.releaseTimeId);
  237 + loger.warn(GlobalConfig.getCurrentStatus());
  238 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
228 } 239 }
229 - sendAudioBroadcastMsg(_param) {  
230 -  
231 - if(!this.mcu.connected){  
232 - loger.warn(GlobalConfig.getCurrentStatus());  
233 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
234 - }  
235 - if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {  
236 - loger.log('音频模块广播->失败->还未初始化数据!');  
237 - if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {  
238 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
239 - return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"};  
240 - }  
241 - return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"};  
242 - }  
243 - if (_param == null) {  
244 - loger.warn('音频模块广播->失败->,参数错误', _param);  
245 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
246 - return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg,参数错误"};  
247 - }  
248 - // to, message  
249 - loger.log('音频模块广播->',_param);  
250 - if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {  
251 - //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启  
252 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
253 - if (freeChannel == 0) {  
254 - loger.warn('不能再打开更多的设备', _param);  
255 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
256 - }  
257 - }  
258 -  
259 -  
260 - let audioSendPdu = new pdu['RCAudioSendDataRequestPdu'];  
261 - audioSendPdu.type = pdu.RCPDU_SEND_AUDIO_DATA_REQUEST;  
262 - audioSendPdu.isPublic = true;  
263 -  
264 - audioSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人  
265 - audioSendPdu.toNodeId = parseInt(_param.toNodeId) || 0;//接收者,0就是所有人  
266 - audioSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;  
267 -  
268 - let dataStr='';  
269 - try{  
270 - dataStr=JSON.stringify(_param.data);  
271 - }catch (err){  
272 - loger.warn('控制消息->JSON转换失败');  
273 - dataStr=_param.data;  
274 - }  
275 240
276 - audioSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" +dataStr);//开头两个字会乱码,需要加上h5两个字符 241 + let openingChannelInfo = this.mediaModule.getOpeningMediaChannelForNodeId(nodeId);
  242 + if (openingChannelInfo.channelId == 0) {
  243 + loger.warn(nodeId, "没有占用频道不需要处理");
  244 + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
  245 + }
277 246
278 - if (!audioSendPdu.isPublic && 0 != audioSendPdu.toNodeId) {  
279 - //发送给制定的人  
280 - //loger.log('发送私聊消息.');  
281 - this.send(audioSendPdu);  
282 - } else {  
283 - //发送给所有人  
284 - //loger.log('音频模块广播->.');  
285 - this.sendChatUniform(audioSendPdu);  
286 - }  
287 - return {"code": ApeConsts.RETURN_SUCCESS, "data": ""}; 247 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  248 + channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  249 + channelInfo.channelId = openingChannelInfo.channelId;
  250 + channelInfo.nodeId = openingChannelInfo.fromNodeId;
  251 + channelInfo.userRole = openingChannelInfo.userRole;
  252 + channelInfo.userName = openingChannelInfo.userName;
  253 + channelInfo.userId = openingChannelInfo.userId;
  254 +
  255 + this.sendTableUpdateHandler(channelInfo);
  256 + //递归检查,800毫秒之后执行
  257 + this.releaseTimeId = setTimeout(function () {
  258 + loger.warn(nodeId, "检查频道是否占用");
  259 + this._releaseNodeIdAllChannel(nodeId);
  260 + }.bind(this), 800);
  261 + }
  262 +
  263 + sendAudioBroadcastMsg(_param) {
  264 +
  265 + if (!this.mcu.connected) {
  266 + loger.warn(GlobalConfig.getCurrentStatus());
  267 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  268 + }
  269 + if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
  270 + loger.log('音频模块广播->失败->还未初始化数据!');
  271 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  272 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
  273 + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"};
  274 + }
  275 + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"};
  276 + }
  277 + if (_param == null) {
  278 + loger.warn('音频模块广播->失败->,参数错误', _param);
  279 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  280 + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg,参数错误"};
  281 + }
  282 + // to, message
  283 + loger.log('音频模块广播->', _param);
  284 + if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {
  285 + //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
  286 + let freeChannel = this.mediaModule.getFreeMediaChannel();
  287 + if (freeChannel == 0) {
  288 + loger.warn('不能再打开更多的设备', _param);
  289 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备", "mediaChannels": this.mediaModule.mediaChannels};
  290 + }
288 } 291 }
289 292
290 - sendTableUpdateHandler(_channelInfo) {  
291 - //loger.log("audio,sendTableUpdateHandler ");  
292 - let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);  
293 - if(updateModelPdu==null){  
294 - loger.warn("音频模块更新数据-> 失败->数据无效",_channelInfo);  
295 - return;  
296 - }  
297 293
298 - let tableItemPdu = new pdu['RCRegistryTableItemPdu'];  
299 - tableItemPdu.itemIdx = _channelInfo.channelId;  
300 - tableItemPdu.owner = _channelInfo.owner;//0收到flash的是这个值,MCU做了了用户掉线处理,30秒之后会清理owner为0  
301 - tableItemPdu.itemData = updateModelPdu.toArrayBuffer(); 294 + let audioSendPdu = new pdu['RCAudioSendDataRequestPdu'];
  295 + audioSendPdu.type = pdu.RCPDU_SEND_AUDIO_DATA_REQUEST;
  296 + audioSendPdu.isPublic = true;
302 297
303 - //insert  
304 - let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];  
305 - tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;  
306 - tableInsertItemPdu.items.push(tableItemPdu); 298 + audioSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
  299 + audioSendPdu.toNodeId = parseInt(_param.toNodeId) || 0;//接收者,0就是所有人
  300 + audioSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;
307 301
308 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
309 - updateObjPdu.objId = ApeConsts.AUDIO_OBJ_TABLE_ID;//  
310 - updateObjPdu.subType = tableInsertItemPdu.type;  
311 - updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer(); 302 + let dataStr = '';
  303 + try {
  304 + dataStr = JSON.stringify(_param.data);
  305 + } catch (err) {
  306 + loger.warn('控制消息->JSON转换失败');
  307 + dataStr = _param.data;
  308 + }
312 309
313 - //同步  
314 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
315 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
316 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); 310 + audioSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + dataStr);//开头两个字会乱码,需要加上h5两个字符
317 311
318 - let adapterPdu = new pdu['RCAdapterPdu'];  
319 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
320 - adapterPdu.item.push(adapterItemPdu); 312 + if (!audioSendPdu.isPublic && 0 != audioSendPdu.toNodeId) {
  313 + //发送给制定的人
  314 + //loger.log('发送私聊消息.');
  315 + this.send(audioSendPdu);
  316 + } else {
  317 + //发送给所有人
  318 + //loger.log('音频模块广播->.');
  319 + this.sendChatUniform(audioSendPdu);
  320 + }
  321 + return {"code": ApeConsts.RETURN_SUCCESS, "data": ""};
  322 + }
  323 +
  324 + sendTableUpdateHandler(_channelInfo) {
  325 + //loger.log("audio,sendTableUpdateHandler ");
  326 + let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);
  327 + if (updateModelPdu == null) {
  328 + loger.warn("音频模块更新数据-> 失败->数据无效", _channelInfo);
  329 + return;
  330 + }
321 331
322 - loger.log("音频模块更新数据->itemIdx=" + tableItemPdu.itemIdx);  
323 - this.sendUniform(adapterPdu, true); 332 + let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
  333 + tableItemPdu.itemIdx = _channelInfo.channelId;
  334 + tableItemPdu.owner = _channelInfo.owner;//0收到flash的是这个值,MCU做了了用户掉线处理,30秒之后会清理owner为0
  335 + tableItemPdu.itemData = updateModelPdu.toArrayBuffer();
  336 +
  337 + //insert
  338 + let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
  339 + tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;
  340 + tableInsertItemPdu.items.push(tableItemPdu);
  341 +
  342 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  343 + updateObjPdu.objId = ApeConsts.AUDIO_OBJ_TABLE_ID;//
  344 + updateObjPdu.subType = tableInsertItemPdu.type;
  345 + updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
  346 +
  347 + //同步
  348 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  349 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  350 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  351 +
  352 + let adapterPdu = new pdu['RCAdapterPdu'];
  353 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  354 + adapterPdu.item.push(adapterItemPdu);
  355 +
  356 + loger.log("音频模块更新数据->itemIdx=" + tableItemPdu.itemIdx);
  357 + this.sendUniform(adapterPdu, true);
  358 + }
  359 +
  360 + /////收到消息处理//////////////////////////////////////////////////
  361 +
  362 + // 消息处理,内部处理,不需要告诉应用层
  363 + receiveAudiooCommandHandler(_data) {
  364 + let audioReceivePdu = pdu['RCAudioSendDataRequestPdu'].decode(_data);
  365 + if (audioReceivePdu == null) {
  366 + loger.warn("音频消息处理,收到的消息为null,不做处理");
  367 + return;
  368 + }
  369 + audioReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(audioReceivePdu.data, 2);//开头两个字会乱码
  370 +
  371 + let dataObj = {};
  372 + try {
  373 + dataObj = JSON.parse(audioReceivePdu.data);
  374 + } catch (err) {
  375 + loger.warn('控制消息->JSON转换失败');
  376 + dataObj = audioReceivePdu.data;
  377 + }
  378 + audioReceivePdu.data = dataObj;
  379 + //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
  380 + if (audioReceivePdu.toNodeId != 0 && audioReceivePdu.toNodeId != GlobalConfig.nodeId) {
  381 + loger.log('音频消息不处理 toNodeId=', audioReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId);
  382 + } else {
  383 + loger.log('音频控制消息处理 .', audioReceivePdu);
  384 + this._emit(MessageTypes.AUDIO_BROADCAST, audioReceivePdu);
  385 + }
  386 + }
  387 +
  388 + tableUpdateHandler(owner, itemIdx, itemData, seek) {
  389 + let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
  390 + loger.log("tableUpdateHandler->channel", itemIdx, 'status->', unpackChannelInfo.status, "seek->", seek);
  391 + //****很重要********
  392 + //如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)
  393 + if (owner == 0) {
  394 + loger.log("释放占用的频道,channel", itemIdx);
  395 + unpackChannelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  396 + unpackChannelInfo.streamId = "";
324 } 397 }
325 398
326 - /////收到消息处理////////////////////////////////////////////////// 399 + this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
  400 +
  401 + if (unpackChannelInfo && unpackChannelInfo.fromNodeId != GlobalConfig.nodeId) {
  402 + let receiveChannelInfo = {};
  403 + receiveChannelInfo.mediaId = unpackChannelInfo.channelId;
  404 + receiveChannelInfo.fromNodeId = unpackChannelInfo.fromNodeId;
  405 + receiveChannelInfo.userName = unpackChannelInfo.userName || "";
  406 + receiveChannelInfo.userRole = unpackChannelInfo.userRole || ApeConsts.normal;
  407 + receiveChannelInfo.mediaType = unpackChannelInfo.mediaType || ApeConsts.MEDIA_TYPE_DEFAULT;
  408 + receiveChannelInfo.screenWidth = unpackChannelInfo.screenWidth || GlobalConfig.screenWidth;
  409 + receiveChannelInfo.screenHeight = unpackChannelInfo.screenHeight || GlobalConfig.screenHeight;
  410 + receiveChannelInfo.deviceType = unpackChannelInfo.deviceType || 0;
  411 + receiveChannelInfo.optionJsonData = unpackChannelInfo.optionJsonData || "";
  412 +
  413 + //消息不是自己同步的,需要处理
  414 + if (unpackChannelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  415 + //正在推流
  416 + receiveChannelInfo.m3u8Url = "";
  417 + receiveChannelInfo.rtmpUrl = "";
  418 + receiveChannelInfo.replay = "";
  419 +
  420 + receiveChannelInfo.seek = seek || 0;//这个是录制回放时使用的seek
  421 +
  422 + let m3u8Stream = this.mediaModule.getMediaPlayPath({"type": "m3u8", "streamId": unpackChannelInfo.streamId});
  423 + let rtmpStream = this.mediaModule.getMediaPlayPath({"type": "rtmp", "streamId": unpackChannelInfo.streamId});
  424 + let replay = this.mediaModule.getMediaRecordPlaybackPath({
  425 + "type": "m3u8",
  426 + "streamId": unpackChannelInfo.streamId
  427 + });
  428 +
  429 + if (m3u8Stream.code == 0) {
  430 + receiveChannelInfo.m3u8Url = m3u8Stream.playUrl;
  431 + }
  432 + if (rtmpStream.code == 0) {
  433 + receiveChannelInfo.rtmpUrl = rtmpStream.playUrl;
  434 + }
  435 + if (replay.code == 0) {
  436 + receiveChannelInfo.replay = replay.playUrl;
  437 + }
  438 + loger.log("AUDIO_PLAY->", receiveChannelInfo);
  439 + //广播播放视频的消息
  440 + this._emit(MessageTypes.AUDIO_PLAY, receiveChannelInfo);
  441 + } else {
  442 + loger.log("AUDIO_STOP->", receiveChannelInfo);
  443 + //流已经停止
  444 + this._emit(MessageTypes.AUDIO_STOP, receiveChannelInfo);
  445 + }
  446 + } else {
  447 + loger.warn("消息是自己发送的或者是消息无效,不需要处理,消息内容如下:");
  448 + loger.log(unpackChannelInfo);
  449 + if (unpackChannelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  450 + GlobalConfig.openMicrophones = EngineUtils.creatTimestamp();
  451 + GlobalConfig.openCamera = 0;
  452 + } else {
  453 + GlobalConfig.openCamera = 0;
  454 + GlobalConfig.openMicrophones = 0;
  455 + }
  456 + this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
  457 + nodeId: GlobalConfig.nodeId,
  458 + userRole: GlobalConfig.userRole,
  459 + userName: GlobalConfig.userName,
  460 + userId: GlobalConfig.userId,
  461 + openCamera: GlobalConfig.openCamera,
  462 + openMicrophones: GlobalConfig.openMicrophones
  463 + });
  464 + }
327 465
328 - // 消息处理,内部处理,不需要告诉应用层  
329 - receiveAudiooCommandHandler(_data) {  
330 - let audioReceivePdu = pdu['RCAudioSendDataRequestPdu'].decode(_data);  
331 - if (audioReceivePdu == null) {  
332 - loger.warn("音频消息处理,收到的消息为null,不做处理");  
333 - return;  
334 - }  
335 - audioReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(audioReceivePdu.data, 2);//开头两个字会乱码  
336 -  
337 - let dataObj= {};  
338 - try{  
339 - dataObj=JSON.parse(audioReceivePdu.data);  
340 - }catch (err){  
341 - loger.warn('控制消息->JSON转换失败');  
342 - dataObj= audioReceivePdu.data;  
343 - }  
344 - audioReceivePdu.data=dataObj;  
345 - //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理  
346 - if (audioReceivePdu.toNodeId != 0 && audioReceivePdu.toNodeId != GlobalConfig.nodeId) {  
347 - loger.log('音频消息不处理 toNodeId=', audioReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId); 466 + MediaModule.allMediaChannelsList[itemIdx] = unpackChannelInfo;
  467 + console.log('MediaModule.allMediaChannelsList', MediaModule.allMediaChannelsList);
  468 + this._emit(MessageTypes.AUDIO_UPDATE, unpackChannelInfo);
  469 + }
  470 +
  471 + //更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
  472 + updaterRecordApeStatus(_param) {
  473 + console.warn("录制状态发送改变->更新当前的状态->", this.mediaModule.mediaChannels);
  474 + for (let i in this.mediaModule.mediaChannels) {
  475 + let channelInfo = this.mediaModule.mediaChannels[i];
  476 + if (channelInfo) {
  477 + if (channelInfo.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
  478 + channelInfo.owner = 0;
348 } else { 479 } else {
349 - loger.log('音频控制消息处理 .',audioReceivePdu);  
350 - this._emit(MessageTypes.AUDIO_BROADCAST, audioReceivePdu); 480 + channelInfo.owner = channelInfo.fromNodeId;
351 } 481 }
  482 + this.sendTableUpdateHandler(channelInfo);
  483 + }
352 } 484 }
353 -  
354 - tableUpdateHandler(owner, itemIdx, itemData,seek) {  
355 - let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);  
356 - loger.log("tableUpdateHandler->channel",itemIdx,'status->',unpackChannelInfo.status,"seek->",seek);  
357 - //****很重要********  
358 - //如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)  
359 - if(owner==0){  
360 - loger.log("释放占用的频道,channel",itemIdx);  
361 - unpackChannelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
362 - unpackChannelInfo.streamId="";  
363 - }  
364 -  
365 - this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;  
366 -  
367 - if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){  
368 - let receiveChannelInfo={};  
369 - receiveChannelInfo.mediaId=unpackChannelInfo.channelId;  
370 - receiveChannelInfo.fromNodeId=unpackChannelInfo.fromNodeId;  
371 - receiveChannelInfo.userName=unpackChannelInfo.userName||"";  
372 - receiveChannelInfo.userRole=unpackChannelInfo.userRole||ApeConsts.normal;  
373 - receiveChannelInfo.mediaType=unpackChannelInfo.mediaType||ApeConsts.MEDIA_TYPE_DEFAULT;  
374 - receiveChannelInfo.screenWidth=unpackChannelInfo.screenWidth||GlobalConfig.screenWidth;  
375 - receiveChannelInfo.screenHeight=unpackChannelInfo.screenHeight||GlobalConfig.screenHeight;  
376 - receiveChannelInfo.deviceType=unpackChannelInfo.deviceType||0;  
377 - receiveChannelInfo.optionJsonData=unpackChannelInfo.optionJsonData||"";  
378 -  
379 - //消息不是自己同步的,需要处理  
380 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
381 - //正在推流  
382 - receiveChannelInfo.m3u8Url="";  
383 - receiveChannelInfo.rtmpUrl="";  
384 - receiveChannelInfo.replay="";  
385 -  
386 - receiveChannelInfo.seek=seek||0;//这个是录制回放时使用的seek  
387 -  
388 - let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
389 - let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});  
390 - let replay=this.mediaModule.getMediaRecordPlaybackPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
391 -  
392 - if(m3u8Stream.code==0){  
393 - receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;  
394 - }  
395 - if(rtmpStream.code==0){  
396 - receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;  
397 - }  
398 - if(replay.code==0){  
399 - receiveChannelInfo.replay=replay.playUrl;  
400 - }  
401 - loger.log("AUDIO_PLAY->",receiveChannelInfo);  
402 - //广播播放视频的消息  
403 - this._emit(MessageTypes.AUDIO_PLAY, receiveChannelInfo);  
404 - }else {  
405 - loger.log("AUDIO_STOP->",receiveChannelInfo);  
406 - //流已经停止  
407 - this._emit(MessageTypes.AUDIO_STOP, receiveChannelInfo);  
408 - }  
409 - }else {  
410 - loger.warn("消息是自己发送的或者是消息无效,不需要处理,消息内容如下:");  
411 - loger.log(unpackChannelInfo);  
412 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
413 - GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();  
414 - GlobalConfig.openCamera=0;  
415 - }else {  
416 - GlobalConfig.openCamera=0;  
417 - GlobalConfig.openMicrophones=0;  
418 - }  
419 - this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE,{  
420 - nodeId:GlobalConfig.nodeId,  
421 - userRole:GlobalConfig.userRole,  
422 - userName:GlobalConfig.userName,  
423 - userId:GlobalConfig.userId,  
424 - openCamera:GlobalConfig.openCamera,  
425 - openMicrophones:GlobalConfig.openMicrophones  
426 - });  
427 - }  
428 -  
429 - MediaModule.allMediaChannelsList[itemIdx]=unpackChannelInfo;  
430 - console.log('MediaModule.allMediaChannelsList',MediaModule.allMediaChannelsList);  
431 - this._emit(MessageTypes.AUDIO_UPDATE, unpackChannelInfo);  
432 - }  
433 -  
434 - //更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次  
435 - updaterRecordApeStatus(_param){  
436 - console.warn("录制状态发送改变->更新当前的状态->",this.mediaModule.mediaChannels);  
437 - for (let i in this.mediaModule.mediaChannels){  
438 - let channelInfo=this.mediaModule.mediaChannels[i];  
439 - if(channelInfo){  
440 - if(channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){  
441 - channelInfo.owner=0;  
442 - }else {  
443 - channelInfo.owner=channelInfo.fromNodeId;  
444 - }  
445 - this.sendTableUpdateHandler(channelInfo);  
446 - }  
447 - } 485 + }
  486 +
  487 + ///////数据的封包和解包/////////////////////////////////////////
  488 + packPdu(_param, _itemIdx) {
  489 + //验证坐标点集合数组是否合法
  490 + if (_param == null || _itemIdx == null) {
  491 + loger.warn("packPdu->失败");
  492 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  493 + return null;
448 } 494 }
449 495
450 - ///////数据的封包和解包/////////////////////////////////////////  
451 - packPdu(_param, _itemIdx) {  
452 - //验证坐标点集合数组是否合法  
453 - if (_param == null || _itemIdx == null) {  
454 - loger.warn("packPdu->失败");  
455 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
456 - return null;  
457 - }  
458 -  
459 - //判断type类型,根据type设置不同的参数  
460 - let packPduModel = new pdu['RCAudioChannelInfoPdu'];  
461 - packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;  
462 - packPduModel.channelId = _itemIdx;  
463 - packPduModel.streamId = _param.streamId||"";  
464 - packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;  
465 - packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);  
466 - packPduModel.userId =_param.userId||"0";  
467 - packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_AUDIO;  
468 - packPduModel.timestamp =_param.timestamp||EngineUtils.creatTimestamp();  
469 - packPduModel.fromNodeId =_param.nodeId|| GlobalConfig.nodeId;  
470 - packPduModel.userName=_param.userName||GlobalConfig.userName||"";  
471 - packPduModel.toNodeId = 0;  
472 - packPduModel.userRole=_param.userRole||GlobalConfig.userRole;  
473 - packPduModel.screenWidth=_param.screenWidth||GlobalConfig.screenWidth;  
474 - packPduModel.screenHeight=_param.screenHeight||GlobalConfig.screenHeight;  
475 - packPduModel.deviceType=_param.deviceType||GlobalConfig.deviceType;  
476 - packPduModel.optionJsonData=_param.optionJsonData||GlobalConfig.optionJsonData;  
477 - loger.log("packPdu->",packPduModel);  
478 - return packPduModel;  
479 - }  
480 -  
481 - unPackPdu(owner, itemIdx, itemData) {  
482 - if (owner == null || itemIdx == null || itemData == null) {  
483 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
484 - return null;  
485 - }  
486 - try {  
487 - let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData);  
488 - loger.log("unPackPdu->",packChannelInfo);  
489 - return packChannelInfo;  
490 - } catch (err) {  
491 - loger.log("unPackPdu error->itemIdx=" + itemIdx + " err:" + err.message);  
492 - }  
493 - return null; 496 + //判断type类型,根据type设置不同的参数
  497 + let packPduModel = new pdu['RCAudioChannelInfoPdu'];
  498 + packPduModel.status = _param.status || ApeConsts.CHANNEL_STATUS_RELEASED;
  499 + packPduModel.channelId = _itemIdx;
  500 + packPduModel.streamId = _param.streamId || "";
  501 + packPduModel.siteId = _param.siteId || GlobalConfig.siteId;//GlobalConfig.siteId;
  502 + packPduModel.classId = parseInt(_param.classId) || parseInt(GlobalConfig.classId);
  503 + packPduModel.userId = _param.userId || "0";
  504 + packPduModel.mediaType = _param.mediaType || ApeConsts.MEDIA_TYPE_AUDIO;
  505 + packPduModel.timestamp = _param.timestamp || EngineUtils.creatTimestamp();
  506 + packPduModel.fromNodeId = _param.nodeId || GlobalConfig.nodeId;
  507 + packPduModel.userName = _param.userName || GlobalConfig.userName || "";
  508 + packPduModel.toNodeId = 0;
  509 + packPduModel.userRole = _param.userRole || GlobalConfig.userRole;
  510 + packPduModel.screenWidth = _param.screenWidth || GlobalConfig.screenWidth;
  511 + packPduModel.screenHeight = _param.screenHeight || GlobalConfig.screenHeight;
  512 + packPduModel.deviceType = _param.deviceType || GlobalConfig.deviceType;
  513 + packPduModel.optionJsonData = GlobalConfig.optionJsonData;
  514 + loger.log("packPdu->", packPduModel);
  515 + return packPduModel;
  516 + }
  517 +
  518 + unPackPdu(owner, itemIdx, itemData) {
  519 + if (owner == null || itemIdx == null || itemData == null) {
  520 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  521 + return null;
  522 + }
  523 + try {
  524 + let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData);
  525 + loger.log("unPackPdu->", packChannelInfo);
  526 + return packChannelInfo;
  527 + } catch (err) {
  528 + loger.log("unPackPdu error->itemIdx=" + itemIdx + " err:" + err.message);
494 } 529 }
  530 + return null;
  531 + }
495 532
496 } 533 }
497 534
@@ -14,609 +14,656 @@ import ShareApe from './ShareApe'; @@ -14,609 +14,656 @@ import ShareApe from './ShareApe';
14 let loger = Loger.getLoger('VideoApe'); 14 let loger = Loger.getLoger('VideoApe');
15 15
16 class VideoApe extends Ape { 16 class VideoApe extends Ape {
17 - constructor() {  
18 - super(  
19 - ApeConsts.VIDEO_SESSION_ID,  
20 - ApeConsts.VIDEO_SESSION_NAME,  
21 - ApeConsts.VIDEO_SESSION_TAG  
22 - );  
23 -  
24 - this.mediaModule=new MediaModule();  
25 - this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.VIDEO_OBJ_TABLE_ID;  
26 - this.mediaModule.mediaChannels={};  
27 - this.mediaModule.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;  
28 - this.shareApe=new ShareApe();  
29 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS,this.onPublishScreenShareSuccess.bind(this));  
30 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE,this.onPublishScreenShareFaile.bind(this));  
31 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_CLOSE,this.onPublishScreenShareClose.bind(this));  
32 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT,this.onPublishScreenShareDisconnect.bind(this));  
33 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED,this.onPublishScreenShareConnected.bind(this));  
34 - this.shareApe.on( MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE,this.onPublishScreenMovieInfoChange.bind(this));  
35 - this.shareApe.on(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE,this.onPublishScreenVideoInfoChange.bind(this));  
36 -  
37 - // Ape Models  
38 - this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);  
39 - this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);  
40 -  
41 - // videoApe 监听视频控制消息,用户之间的消息传递  
42 - this.on(pdu.RCPDU_SEND_VIDEO_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));  
43 - }  
44 - //ape加入成功  
45 - onJoinChannelHandlerSuccess(){  
46 - //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据  
47 - this.mediaModule.maxMediaChannel=GlobalConfig.maxVideoChannels;  
48 - }  
49 -  
50 - /////////////发送数据操作////////////////////////////////////////////  
51 - //获取播流地址  
52 - getPlayVideoPath(_param) {  
53 - loger.log('getPlayVideoPath');  
54 - return this.mediaModule.getMediaPlayPath(_param);  
55 - }  
56 -  
57 - //获取推流地址  
58 - getPublishVideoPath(_param) {  
59 - loger.log('获取推流地址->');  
60 - if(!this.mcu.connected){  
61 - loger.warn(GlobalConfig.getCurrentStatus());  
62 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
63 - }  
64 - //监课比较特殊,不占用课堂内的音视频路数,额外创建  
65 - if(GlobalConfig.userRole==ApeConsts.invisible){  
66 - let result=this.mediaModule.getMediaPublishPathForInVisible(_param);  
67 - this._emit( MessageTypes.VIDEO_GET_PUBLISH_PATH,result);  
68 - return result;  
69 - }  
70 -  
71 - //非监课的身份,需要判断是否可以继续推流  
72 - //需要判断当前已经使用的流路数  
73 - let openChannel=0;  
74 - let allChannels= MediaModule.allMediaChannelsList;  
75 - for(let i in allChannels){  
76 - let channel=allChannels[i];  
77 - if(channel&&channel.status==ApeConsts.CHANNEL_STATUS_OPENING&&channel.userRole!=ApeConsts.invisible){  
78 - //正在开启的才计数,监课开启的不计算在内  
79 - openChannel++;  
80 - }  
81 - }  
82 - //如果已经开启的数量大于等于最大允许开启的数量,不允许再推流  
83 - if(openChannel>=GlobalConfig.maxMediaChannels){  
84 - loger.warn('不能再打开设备->当前开启的设备数量->',openChannel);  
85 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开设备,当前开启的设备数量"};  
86 - }  
87 -  
88 - let result=this.mediaModule.getMediaPublishPath(_param);  
89 - this._emit( MessageTypes.VIDEO_GET_PUBLISH_PATH,result);  
90 - return result; 17 + constructor() {
  18 + super(
  19 + ApeConsts.VIDEO_SESSION_ID,
  20 + ApeConsts.VIDEO_SESSION_NAME,
  21 + ApeConsts.VIDEO_SESSION_TAG
  22 + );
  23 +
  24 + this.mediaModule = new MediaModule();
  25 + this.mediaModule.MEDIA_OBJ_TABLE_ID = ApeConsts.VIDEO_OBJ_TABLE_ID;
  26 + this.mediaModule.mediaChannels = {};
  27 + this.mediaModule.mediaType = ApeConsts.MEDIA_TYPE_VIDEO;
  28 + this.shareApe = new ShareApe();
  29 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS, this.onPublishScreenShareSuccess.bind(this));
  30 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE, this.onPublishScreenShareFaile.bind(this));
  31 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_CLOSE, this.onPublishScreenShareClose.bind(this));
  32 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT, this.onPublishScreenShareDisconnect.bind(this));
  33 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED, this.onPublishScreenShareConnected.bind(this));
  34 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE, this.onPublishScreenMovieInfoChange.bind(this));
  35 + this.shareApe.on(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE, this.onPublishScreenVideoInfoChange.bind(this));
  36 +
  37 + // Ape Models
  38 + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
  39 + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
  40 +
  41 + // videoApe 监听视频控制消息,用户之间的消息传递
  42 + this.on(pdu.RCPDU_SEND_VIDEO_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));
  43 + }
  44 +
  45 + //ape加入成功
  46 + onJoinChannelHandlerSuccess() {
  47 + //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据
  48 + this.mediaModule.maxMediaChannel = GlobalConfig.maxVideoChannels;
  49 + }
  50 +
  51 + /////////////发送数据操作////////////////////////////////////////////
  52 + //获取播流地址
  53 + getPlayVideoPath(_param) {
  54 + loger.log('getPlayVideoPath');
  55 + return this.mediaModule.getMediaPlayPath(_param);
  56 + }
  57 +
  58 + //获取推流地址
  59 + getPublishVideoPath(_param) {
  60 + loger.log('获取推流地址->');
  61 + if (!this.mcu.connected) {
  62 + loger.warn(GlobalConfig.getCurrentStatus());
  63 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
91 } 64 }
92 -  
93 - //获取当前所有频道信息  
94 - getAllChannelInfo(_param){  
95 - loger.log('获取当前所有频道信息->');  
96 - return this.mediaModule.getAllMediaChannelInfo(); 65 + //监课比较特殊,不占用课堂内的音视频路数,额外创建
  66 + if (GlobalConfig.userRole == ApeConsts.invisible) {
  67 + let result = this.mediaModule.getMediaPublishPathForInVisible(_param);
  68 + this._emit(MessageTypes.VIDEO_GET_PUBLISH_PATH, result);
  69 + return result;
97 } 70 }
98 71
99 - //推流  
100 - publishVideo(_param) {  
101 - if(!this.mcu.connected){  
102 - loger.warn(GlobalConfig.getCurrentStatus());  
103 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"已经断开连接!","mediaId":0});  
104 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
105 - }  
106 -  
107 - if (_param == null||_param.publishUrl == null)  
108 - {  
109 - loger.warn('推流->参数错误', _param);  
110 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
111 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"参数错误!","mediaId":0});  
112 - return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};  
113 - }  
114 -  
115 - //根据推流的地址获取对应的频道信息  
116 - let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);  
117 - if(needPublishChannelInfo==null){  
118 - loger.warn('推流->推流数据已经无效', _param);  
119 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"推流数据已经无效!","mediaId":0});  
120 - return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};  
121 - }  
122 -  
123 - //判断当前是否还有空闲的channle  
124 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
125 - if (freeChannel == 0) {  
126 - loger.warn("推流->不能再打开更多的设备 ");  
127 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"不能再打开更多的设备!","mediaId":0});  
128 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
129 - }  
130 - 72 + //非监课的身份,需要判断是否可以继续推流
  73 + //需要判断当前已经使用的流路数
  74 + let openChannel = 0;
  75 + let allChannels = MediaModule.allMediaChannelsList;
  76 + for (let i in allChannels) {
  77 + let channel = allChannels[i];
  78 + if (channel && channel.status == ApeConsts.CHANNEL_STATUS_OPENING && channel.userRole != ApeConsts.invisible) {
  79 + //正在开启的才计数,监课开启的不计算在内
  80 + openChannel++;
  81 + }
  82 + }
  83 + //如果已经开启的数量大于等于最大允许开启的数量,不允许再推流
  84 + if (openChannel >= GlobalConfig.maxMediaChannels) {
  85 + loger.warn('不能再打开设备->当前开启的设备数量->', openChannel);
  86 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开设备,当前开启的设备数量"};
  87 + }
131 88
132 - //判断当前的频道是否已经占用  
133 - if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){  
134 - if(needPublishChannelInfo.nodeId==GlobalConfig.nodeId){  
135 - loger.warn(needPublishChannelInfo.channelId,"已经推送过消息,不需要再次推送");  
136 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId});  
137 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId};  
138 - }else {  
139 - loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");  
140 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!","mediaId":0});  
141 - return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!","mediaChannels":this.mediaModule.mediaChannels};  
142 - }  
143 - } 89 + let result = this.mediaModule.getMediaPublishPath(_param);
  90 + this._emit(MessageTypes.VIDEO_GET_PUBLISH_PATH, result);
  91 + return result;
  92 + }
  93 +
  94 + //获取当前所有频道信息
  95 + getAllChannelInfo(_param) {
  96 + loger.log('获取当前所有频道信息->');
  97 + return this.mediaModule.getAllMediaChannelInfo();
  98 + }
  99 +
  100 + //推流
  101 + publishVideo(_param) {
  102 + if (!this.mcu.connected) {
  103 + loger.warn(GlobalConfig.getCurrentStatus());
  104 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接!", "mediaId": 0});
  105 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  106 + }
144 107
145 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
146 - channelInfo.owner=GlobalConfig.nodeId;  
147 - channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;  
148 - channelInfo.channelId=needPublishChannelInfo.channelId;  
149 - channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称  
150 - channelInfo.timestamp=needPublishChannelInfo.timestamp;//时间戳  
151 - channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;  
152 - this.sendTableUpdateHandler(channelInfo); 108 + if (_param == null || _param.publishUrl == null) {
  109 + loger.warn('推流->参数错误', _param);
  110 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  111 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {"code": ApeConsts.RETURN_FAILED, "data": "参数错误!", "mediaId": 0});
  112 + return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
  113 + }
153 114
154 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId});  
155 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId}; 115 + //获取可选参数,转换为JSON字符串
  116 + try {
  117 + GlobalConfig.optionJsonData = JSON.stringify(_param.optionJsonData)||""
  118 + } catch (err) {
  119 + GlobalConfig.optionJsonData = "";
156 } 120 }
157 121
158 - //停止推流,  
159 - stopPublishVideo(_param) {  
160 - loger.log('停止推流->',_param);  
161 - if(!this.mcu.connected){  
162 - loger.warn(GlobalConfig.getCurrentStatus());  
163 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
164 - } 122 + //根据推流的地址获取对应的频道信息
  123 + let needPublishChannelInfo = this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
  124 + if (needPublishChannelInfo == null) {
  125 + loger.warn('推流->推流数据已经无效', _param);
  126 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {
  127 + "code": ApeConsts.RETURN_FAILED,
  128 + "data": "推流数据已经无效!",
  129 + "mediaId": 0
  130 + });
  131 + return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
  132 + }
165 133
166 - //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param  
167 - let nodeId=GlobalConfig.nodeId;  
168 - if(_param&&parseInt(_param.nodeId)>0){  
169 - nodeId=parseInt(_param.nodeId);  
170 - } 134 + //判断当前是否还有空闲的channle
  135 + let freeChannel = this.mediaModule.getFreeMediaChannel();
  136 + if (freeChannel == 0) {
  137 + loger.warn("推流->不能再打开更多的设备 ");
  138 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {
  139 + "code": ApeConsts.RETURN_FAILED,
  140 + "data": "不能再打开更多的设备!",
  141 + "mediaId": 0
  142 + });
  143 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备", "mediaChannels": this.mediaModule.mediaChannels};
  144 + }
171 145
172 - //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道  
173 - let releaseChannelId=0;  
174 - if(_param&&parseInt(_param.mediaId)>0){  
175 - releaseChannelId=parseInt(_param.mediaId);  
176 - }  
177 146
178 - //释放channelId 的占用  
179 - if(releaseChannelId>0){  
180 - //第一种情况,释放nodeId占用的指定mediaId (channelId)  
181 - this._releaseChannelForNodeId(nodeId,releaseChannelId);  
182 - }else {  
183 - //第二种情况,释放nodeId占用的所有channelId  
184 - this._releaseNodeIdAllChannel(nodeId);  
185 - } 147 + //判断当前的频道是否已经占用
  148 + if (this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)) {
  149 + if (needPublishChannelInfo.nodeId == GlobalConfig.nodeId) {
  150 + loger.warn(needPublishChannelInfo.channelId, "已经推送过消息,不需要再次推送");
  151 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {
  152 + "code": ApeConsts.RETURN_SUCCESS,
  153 + "data": "已经推送过消息,不需要再次推送!",
  154 + "mediaId": needPublishChannelInfo.channelId
  155 + });
  156 + return {
  157 + "code": ApeConsts.RETURN_SUCCESS,
  158 + "data": "已经推送过消息,不需要再次推送!",
  159 + "mediaId": needPublishChannelInfo.channelId
  160 + };
  161 + } else {
  162 + loger.warn(needPublishChannelInfo.channelId, "频道已经被占用");
  163 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {
  164 + "code": ApeConsts.RETURN_FAILED,
  165 + "data": "频道已经被占用!",
  166 + "mediaId": 0
  167 + });
  168 + return {"code": ApeConsts.RETURN_FAILED, "data": "频道已经被占用!", "mediaChannels": this.mediaModule.mediaChannels};
  169 + }
186 } 170 }
187 171
188 - //==========================屏幕共享========================================================================= 172 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  173 + channelInfo.owner = GlobalConfig.nodeId;
  174 + channelInfo.status = ApeConsts.CHANNEL_STATUS_OPENING;
  175 + channelInfo.channelId = needPublishChannelInfo.channelId;
  176 + channelInfo.streamId = needPublishChannelInfo.streamId;//按规则拼接的流名称
  177 + channelInfo.timestamp = needPublishChannelInfo.timestamp;//时间戳
  178 + channelInfo.mediaType = ApeConsts.MEDIA_TYPE_VIDEO;
  179 + this.sendTableUpdateHandler(channelInfo);
  180 +
  181 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {
  182 + "code": ApeConsts.RETURN_SUCCESS,
  183 + "data": "推流成功!",
  184 + "mediaId": needPublishChannelInfo.channelId
  185 + });
  186 + return {"code": ApeConsts.RETURN_SUCCESS, "data": "推流成功!", "mediaId": needPublishChannelInfo.channelId};
  187 + }
  188 +
  189 + //停止推流,
  190 + stopPublishVideo(_param) {
  191 + loger.log('停止推流->', _param);
  192 + if (!this.mcu.connected) {
  193 + loger.warn(GlobalConfig.getCurrentStatus());
  194 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  195 + }
189 196
190 - //屏幕共享连接打开  
191 - onPublishScreenShareFaile(){  
192 - loger.log('屏幕共享推流失败->');  
193 - this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE); 197 + //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param
  198 + let nodeId = GlobalConfig.nodeId;
  199 + if (_param && parseInt(_param.nodeId) > 0) {
  200 + nodeId = parseInt(_param.nodeId);
194 } 201 }
195 - //屏幕共享连接关闭  
196 - onPublishScreenShareClose(){  
197 - loger.log('屏幕共享推流关闭->');  
198 - this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CLOSE); 202 +
  203 + //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道
  204 + let releaseChannelId = 0;
  205 + if (_param && parseInt(_param.mediaId) > 0) {
  206 + releaseChannelId = parseInt(_param.mediaId);
199 } 207 }
200 - //屏幕共享连接失败  
201 - onPublishScreenShareDisconnect(){  
202 - loger.log('屏幕共享服务器连接失败->');  
203 - this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT); 208 +
  209 + //释放channelId 的占用
  210 + if (releaseChannelId > 0) {
  211 + //第一种情况,释放nodeId占用的指定mediaId (channelId)
  212 + this._releaseChannelForNodeId(nodeId, releaseChannelId);
  213 + } else {
  214 + //第二种情况,释放nodeId占用的所有channelId
  215 + this._releaseNodeIdAllChannel(nodeId);
204 } 216 }
205 - //屏幕共享连接失败  
206 - onPublishScreenShareConnected(){  
207 - loger.log('屏幕共享服务器连接成功->');  
208 - this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED); 217 + }
  218 +
  219 + //==========================屏幕共享=========================================================================
  220 +
  221 + //屏幕共享连接打开
  222 + onPublishScreenShareFaile() {
  223 + loger.log('屏幕共享推流失败->');
  224 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_FAILE);
  225 + }
  226 +
  227 + //屏幕共享连接关闭
  228 + onPublishScreenShareClose() {
  229 + loger.log('屏幕共享推流关闭->');
  230 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CLOSE);
  231 + }
  232 +
  233 + //屏幕共享连接失败
  234 + onPublishScreenShareDisconnect() {
  235 + loger.log('屏幕共享服务器连接失败->');
  236 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_DISCONNECT);
  237 + }
  238 +
  239 + //屏幕共享连接失败
  240 + onPublishScreenShareConnected() {
  241 + loger.log('屏幕共享服务器连接成功->');
  242 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_CONNECTED);
  243 + }
  244 +
  245 + onPublishScreenMovieInfoChange(data) {
  246 + loger.log('屏幕共享MOVIE信息发生改变->');
  247 + this._emit(MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE, data);
  248 + }
  249 +
  250 + onPublishScreenVideoInfoChange(data) {
  251 + loger.log('屏幕共享视频信息发生改变->');
  252 + this._emit(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE, data);
  253 + }
  254 +
  255 + //监听屏幕共享发布成功
  256 + onPublishScreenShareSuccess() {
  257 + loger.log('屏幕共享推流成功之后才能更新同步消息->');
  258 + //屏幕共享推流成功之后才能更新同步消息
  259 + let channelInfo = this.shareApe.getPublishChannelInfo();
  260 + this.sendTableUpdateHandler(channelInfo);
  261 + this._emit(MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS, {
  262 + "code": ApeConsts.RETURN_SUCCESS,
  263 + "data": "桌面共享推流!",
  264 + "mediaId": channelInfo.channelId
  265 + });
  266 + return {"code": ApeConsts.RETURN_SUCCESS, "data": "桌面共享推流!", "mediaId": channelInfo.channelId};
  267 + }
  268 +
  269 + //桌面共享推流
  270 + publishScreenShare(_param) {
  271 + if (!this.mcu.connected) {
  272 + loger.warn(GlobalConfig.getCurrentStatus());
  273 + this._emit(MessageTypes.VIDEO_PUBLISH_RESULT, {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接!", "mediaId": 0});
  274 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
209 } 275 }
210 - onPublishScreenMovieInfoChange(data){  
211 - loger.log('屏幕共享MOVIE信息发生改变->');  
212 - this._emit(MessageTypes.PUBLISH_SCREEN_MOVIE_INFO_CHANGE,data); 276 + let publishType = 'flash';
  277 + if (_param && _param.type == 'live') {
  278 + publishType = 'live';
213 } 279 }
214 - onPublishScreenVideoInfoChange(data){  
215 - loger.log('屏幕共享视频信息发生改变->');  
216 - this._emit(MessageTypes.PUBLISH_SCREEN_VIDEO_INFO_CHANGE,data); 280 + //老师能开启屏幕共享
  281 + if (GlobalConfig.isHost) {
  282 + //获取屏幕共享推流的地址
  283 + let shareResult = this.mediaModule.getMediaPublishPathForScreenShare(this.shareApe.channelId, publishType);
  284 + shareResult.ip = _param.ip || "";//外部可以设置屏幕共享的IP
  285 + shareResult.port = _param.port || "";//外部可以设置屏幕共享的端口
  286 + this.shareApe.publish(shareResult);
217 } 287 }
218 - //监听屏幕共享发布成功  
219 - onPublishScreenShareSuccess(){  
220 - loger.log('屏幕共享推流成功之后才能更新同步消息->');  
221 - //屏幕共享推流成功之后才能更新同步消息  
222 - let channelInfo=this.shareApe.getPublishChannelInfo();  
223 - this.sendTableUpdateHandler(channelInfo);  
224 - this._emit( MessageTypes.PUBLISH_SCREEN_SHARE_SUCCESS,{"code": ApeConsts.RETURN_SUCCESS, "data":"桌面共享推流!","mediaId":channelInfo.channelId});  
225 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"桌面共享推流!","mediaId":channelInfo.channelId};  
226 - }  
227 - //桌面共享推流  
228 - publishScreenShare(_param) {  
229 - if(!this.mcu.connected){  
230 - loger.warn(GlobalConfig.getCurrentStatus());  
231 - this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"已经断开连接!","mediaId":0});  
232 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
233 - }  
234 - let publishType='flash';  
235 - if(_param&&_param.type=='live'){  
236 - publishType='live';  
237 - }  
238 - //老师能开启屏幕共享  
239 - if(GlobalConfig.isHost) {  
240 - //获取屏幕共享推流的地址  
241 - let shareResult = this.mediaModule.getMediaPublishPathForScreenShare(this.shareApe.channelId, publishType);  
242 - shareResult.ip=_param.ip||"";//外部可以设置屏幕共享的IP  
243 - shareResult.port=_param.port||"";//外部可以设置屏幕共享的端口  
244 - this.shareApe.publish(shareResult);  
245 - } 288 + }
  289 +
  290 + //停止桌面共享推流
  291 + stopPublishScreenShare(_param) {
  292 + loger.log('停止桌面共享推流->', _param);
  293 + if (!this.mcu.connected) {
  294 + loger.warn(GlobalConfig.getCurrentStatus());
  295 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
246 } 296 }
  297 + //只有老师能停止屏幕共享
  298 + if (GlobalConfig.isHost) {
  299 + let channelInfo = this.shareApe.getDefaultChannelInfo();
  300 + channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  301 + this.sendTableUpdateHandler(channelInfo);
247 302
248 - //停止桌面共享推流  
249 - stopPublishScreenShare(_param) {  
250 - loger.log('停止桌面共享推流->',_param);  
251 - if(!this.mcu.connected){  
252 - loger.warn(GlobalConfig.getCurrentStatus());  
253 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
254 - }  
255 - //只有老师能停止屏幕共享  
256 - if(GlobalConfig.isHost){  
257 - let channelInfo=this.shareApe.getDefaultChannelInfo();  
258 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
259 - this.sendTableUpdateHandler(channelInfo);  
260 -  
261 - this.shareApe.stopPublish();  
262 - }  
263 - 303 + this.shareApe.stopPublish();
264 } 304 }
265 305
266 - //=============================屏幕共享 end=================================================  
267 -  
268 - //释放nodeId占用的指定的channelId频道  
269 - _releaseChannelForNodeId(nodeId,channelId){  
270 - loger.log(nodeId,"_releaseChannelForNodeId-->channelId",channelId);  
271 - let channelInfo=this.mediaModule.mediaChannels[channelId];  
272 - if(channelInfo&&channelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
273 - if(channelInfo.fromNodeId==nodeId){ 306 + }
274 307
275 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
276 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
277 - channelInfo.channelId=channelId; 308 + //=============================屏幕共享 end=================================================
278 309
279 - this.sendTableUpdateHandler(channelInfo);  
280 - }else {  
281 - loger.warn(channelId,"不属于nodeId",nodeId,"不能释放",channelInfo);  
282 - }  
283 - }else {  
284 - loger.warn(nodeId,"要释放的channel不存在或者已经释放-->channelId",channelInfo);  
285 - }  
286 - }  
287 - //释放nodeId占用的所有频道  
288 - _releaseNodeIdAllChannel(nodeId){  
289 - if(!this.mcu.connected){  
290 - clearTimeout(this.releaseTimeId);  
291 - loger.warn(GlobalConfig.getCurrentStatus());  
292 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
293 - }  
294 - loger.log("释放nodeId占用的所有频道->",nodeId);  
295 - let openingChannelInfo = this.mediaModule.getOpeningMediaChannelForNodeId(nodeId);  
296 - if (openingChannelInfo.channelId== 0) {  
297 - loger.warn(nodeId,"没有占用channel不需要处理");  
298 - return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};  
299 - } 310 + //释放nodeId占用的指定的channelId频道
  311 + _releaseChannelForNodeId(nodeId, channelId) {
  312 + loger.log(nodeId, "_releaseChannelForNodeId-->channelId", channelId);
  313 + let channelInfo = this.mediaModule.mediaChannels[channelId];
  314 + if (channelInfo && channelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  315 + if (channelInfo.fromNodeId == nodeId) {
300 316
301 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
302 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
303 - channelInfo.channelId=openingChannelInfo.channelId;  
304 - channelInfo.nodeId=openingChannelInfo.fromNodeId;//发送消息的人员nodeId  
305 - channelInfo.userRole=openingChannelInfo.userRole;  
306 - channelInfo.userName=openingChannelInfo.userName;  
307 - channelInfo.userId=openingChannelInfo.userId; 317 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  318 + channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  319 + channelInfo.channelId = channelId;
308 320
309 this.sendTableUpdateHandler(channelInfo); 321 this.sendTableUpdateHandler(channelInfo);
310 - //递归检查,800毫秒之后执行  
311 - this.releaseTimeId=setTimeout(function(){  
312 - loger.warn(nodeId,"检查频道是否占用");  
313 - this._releaseNodeIdAllChannel(nodeId);  
314 - }.bind(this),800); 322 + } else {
  323 + loger.warn(channelId, "不属于nodeId", nodeId, "不能释放", channelInfo);
  324 + }
  325 + } else {
  326 + loger.warn(nodeId, "要释放的channel不存在或者已经释放-->channelId", channelInfo);
  327 + }
  328 + }
  329 +
  330 + //释放nodeId占用的所有频道
  331 + _releaseNodeIdAllChannel(nodeId) {
  332 + if (!this.mcu.connected) {
  333 + clearTimeout(this.releaseTimeId);
  334 + loger.warn(GlobalConfig.getCurrentStatus());
  335 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  336 + }
  337 + loger.log("释放nodeId占用的所有频道->", nodeId);
  338 + let openingChannelInfo = this.mediaModule.getOpeningMediaChannelForNodeId(nodeId);
  339 + if (openingChannelInfo.channelId == 0) {
  340 + loger.warn(nodeId, "没有占用channel不需要处理");
  341 + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
315 } 342 }
316 343
317 - sendVideoBroadcastMsg(_param) {  
318 - if(!this.mcu.connected){  
319 - loger.warn(GlobalConfig.getCurrentStatus());  
320 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
321 - }  
322 -  
323 - if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {  
324 - loger.log('不能发送Video消息.McuClient还未初始化数据!');  
325 - if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {  
326 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
327 - return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};  
328 - }  
329 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能发送Video消息.McuClient还未初始化数据"};  
330 - }  
331 - if (_param == null) {  
332 - loger.warn('sendVideoCommandMsg失败,参数错误', _param);  
333 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
334 - return {"code": ApeConsts.RETURN_FAILED, "data": "sendVideoCommandMsg失败,参数错误"};  
335 - }  
336 - // to, message  
337 - loger.log('视频模块广播消息.', _param);  
338 -  
339 - if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {  
340 - //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启  
341 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
342 - if (freeChannel == 0) {  
343 - loger.warn('视频模块广播消息->不能再打开更多的设备', _param);  
344 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
345 - }  
346 - } 344 + let channelInfo = this.mediaModule.getDefaultChannelInfo();
  345 + channelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  346 + channelInfo.channelId = openingChannelInfo.channelId;
  347 + channelInfo.nodeId = openingChannelInfo.fromNodeId;//发送消息的人员nodeId
  348 + channelInfo.userRole = openingChannelInfo.userRole;
  349 + channelInfo.userName = openingChannelInfo.userName;
  350 + channelInfo.userId = openingChannelInfo.userId;
  351 +
  352 + this.sendTableUpdateHandler(channelInfo);
  353 + //递归检查,800毫秒之后执行
  354 + this.releaseTimeId = setTimeout(function () {
  355 + loger.warn(nodeId, "检查频道是否占用");
  356 + this._releaseNodeIdAllChannel(nodeId);
  357 + }.bind(this), 800);
  358 + }
  359 +
  360 + sendVideoBroadcastMsg(_param) {
  361 + if (!this.mcu.connected) {
  362 + loger.warn(GlobalConfig.getCurrentStatus());
  363 + return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
  364 + }
347 365
348 - let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];  
349 - videoSendPdu.type = pdu.RCPDU_SEND_VIDEO_DATA_REQUEST;  
350 - videoSendPdu.isPublic = true; 366 + if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
  367 + loger.log('不能发送Video消息.McuClient还未初始化数据!');
  368 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  369 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
  370 + return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};
  371 + }
  372 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能发送Video消息.McuClient还未初始化数据"};
  373 + }
  374 + if (_param == null) {
  375 + loger.warn('sendVideoCommandMsg失败,参数错误', _param);
  376 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  377 + return {"code": ApeConsts.RETURN_FAILED, "data": "sendVideoCommandMsg失败,参数错误"};
  378 + }
  379 + // to, message
  380 + loger.log('视频模块广播消息.', _param);
  381 +
  382 + if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {
  383 + //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
  384 + let freeChannel = this.mediaModule.getFreeMediaChannel();
  385 + if (freeChannel == 0) {
  386 + loger.warn('视频模块广播消息->不能再打开更多的设备', _param);
  387 + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备", "mediaChannels": this.mediaModule.mediaChannels};
  388 + }
  389 + }
351 390
352 - videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人  
353 - videoSendPdu.toNodeId = parseInt(_param.toNodeId) || 0;//接收者,0就是所有人  
354 - videoSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT; 391 + let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];
  392 + videoSendPdu.type = pdu.RCPDU_SEND_VIDEO_DATA_REQUEST;
  393 + videoSendPdu.isPublic = true;
355 394
356 - let dataStr='';  
357 - try{  
358 - dataStr=JSON.stringify(_param.data);  
359 - }catch (err){  
360 - loger.warn('控制消息->JSON转换失败');  
361 - dataStr=_param.data;  
362 - }  
363 - videoSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + dataStr);//开头两个字会乱码 395 + videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
  396 + videoSendPdu.toNodeId = parseInt(_param.toNodeId) || 0;//接收者,0就是所有人
  397 + videoSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;
364 398
365 - if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {  
366 - //发送给制定的人  
367 - this.send(videoSendPdu);  
368 - } else {  
369 - //发送给所有人  
370 - this.sendChatUniform(videoSendPdu);  
371 - }  
372 - return {"code": ApeConsts.RETURN_SUCCESS, "data": ""}; 399 + let dataStr = '';
  400 + try {
  401 + dataStr = JSON.stringify(_param.data);
  402 + } catch (err) {
  403 + loger.warn('控制消息->JSON转换失败');
  404 + dataStr = _param.data;
373 } 405 }
374 - //发送到mcu同步(更新数据)  
375 - sendTableUpdateHandler(_channelInfo) {  
376 - //loger.log("video===sendTableUpdateHandler ");  
377 - let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);  
378 -  
379 - if(updateModelPdu==null){  
380 - loger.warn("sendTableUpdateHandler error,updateModelPdu=null");  
381 - return;  
382 - } 406 + videoSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + dataStr);//开头两个字会乱码
  407 +
  408 + if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {
  409 + //发送给制定的人
  410 + this.send(videoSendPdu);
  411 + } else {
  412 + //发送给所有人
  413 + this.sendChatUniform(videoSendPdu);
  414 + }
  415 + return {"code": ApeConsts.RETURN_SUCCESS, "data": ""};
  416 + }
383 417
384 - let tableItemPdu = new pdu['RCRegistryTableItemPdu'];  
385 - tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;  
386 - tableItemPdu.owner = _channelInfo.owner;//0收到flash的是这个值,MCU做了了用户掉线处理,30秒之后会清理owner为0  
387 - tableItemPdu.itemData = updateModelPdu.toArrayBuffer(); 418 + //发送到mcu同步(更新数据)
  419 + sendTableUpdateHandler(_channelInfo) {
  420 + //loger.log("video===sendTableUpdateHandler ");
  421 + let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
388 422
389 - //insert  
390 - let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];  
391 - tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//  
392 - tableInsertItemPdu.items.push(tableItemPdu); 423 + if (updateModelPdu == null) {
  424 + loger.warn("sendTableUpdateHandler error,updateModelPdu=null");
  425 + return;
  426 + }
393 427
394 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
395 - updateObjPdu.objId = ApeConsts.VIDEO_OBJ_TABLE_ID;//  
396 - updateObjPdu.subType = tableInsertItemPdu.type;  
397 - updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer(); 428 + let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
  429 + tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;
  430 + tableItemPdu.owner = _channelInfo.owner;//0收到flash的是这个值,MCU做了了用户掉线处理,30秒之后会清理owner为0
  431 + tableItemPdu.itemData = updateModelPdu.toArrayBuffer();
  432 +
  433 + //insert
  434 + let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
  435 + tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
  436 + tableInsertItemPdu.items.push(tableItemPdu);
  437 +
  438 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  439 + updateObjPdu.objId = ApeConsts.VIDEO_OBJ_TABLE_ID;//
  440 + updateObjPdu.subType = tableInsertItemPdu.type;
  441 + updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
  442 +
  443 + //同步
  444 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  445 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  446 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  447 +
  448 + let adapterPdu = new pdu['RCAdapterPdu'];
  449 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  450 + adapterPdu.item.push(adapterItemPdu);
  451 +
  452 + loger.log("发送更新VIDEO.itemIdx=" + tableItemPdu.itemIdx);
  453 + this.sendUniform(adapterPdu, true);
  454 + }
  455 +
  456 + /////收到消息处理//////////////////////////////////////////////////
  457 +
  458 + // 视频消息处理,内部处理,不需要告诉应用层
  459 + receiveVideoCommandHandler(_data) {
  460 + let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);
  461 + if (videoReceivePdu == null) {
  462 + loger.warn("视频控制消息处理,收到的消息为null,不做处理");
  463 + return;
  464 + }
  465 + videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码
  466 +
  467 + let dataObj = {};
  468 + try {
  469 + dataObj = JSON.parse(videoReceivePdu.data);
  470 + } catch (err) {
  471 + loger.warn('控制消息->JSON转换失败');
  472 + dataObj = videoReceivePdu.data;
  473 + }
  474 + videoReceivePdu.data = dataObj;
  475 + //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
  476 + if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {
  477 + loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId);
  478 + } else {
  479 + loger.log('视频控制消息处理 .', videoReceivePdu);
  480 + this._emit(MessageTypes.VIDEO_BROADCAST, videoReceivePdu);
  481 + }
  482 + }
398 483
399 - //同步  
400 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
401 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
402 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();  
403 484
404 - let adapterPdu = new pdu['RCAdapterPdu'];  
405 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
406 - adapterPdu.item.push(adapterItemPdu); 485 + tableUpdateHandler(owner, itemIdx, itemData, seek) {
  486 + let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
  487 + loger.log("tableUpdateHandler->channel", itemIdx, 'mediaType', unpackChannelInfo.mediaType, 'status->', unpackChannelInfo.status, "seek->", seek);
407 488
408 - loger.log("发送更新VIDEO.itemIdx=" + tableItemPdu.itemIdx);  
409 - this.sendUniform(adapterPdu, true); 489 + //****很重要********
  490 + //如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)
  491 + if (owner == 0) {
  492 + loger.log("释放占用的频道,channel", itemIdx);
  493 + unpackChannelInfo.status = ApeConsts.CHANNEL_STATUS_RELEASED;
  494 + unpackChannelInfo.streamId = "";
  495 + }
  496 + //屏幕共享的流不保存
  497 + if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE && unpackChannelInfo.channelId > 0) {
  498 + this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
410 } 499 }
411 500
412 - /////收到消息处理////////////////////////////////////////////////// 501 + if (unpackChannelInfo && unpackChannelInfo.fromNodeId != GlobalConfig.nodeId) {
  502 + let receiveChannelInfo = {};
  503 + receiveChannelInfo.mediaId = unpackChannelInfo.channelId;
  504 + receiveChannelInfo.fromNodeId = unpackChannelInfo.fromNodeId;
  505 + receiveChannelInfo.userName = unpackChannelInfo.userName || "";
  506 + receiveChannelInfo.userRole = unpackChannelInfo.userRole || ApeConsts.normal;
  507 + receiveChannelInfo.mediaType = unpackChannelInfo.mediaType || ApeConsts.MEDIA_TYPE_DEFAULT;
  508 + receiveChannelInfo.screenWidth = unpackChannelInfo.screenWidth || GlobalConfig.screenWidth;
  509 + receiveChannelInfo.screenHeight = unpackChannelInfo.screenHeight || GlobalConfig.screenHeight;
  510 + receiveChannelInfo.deviceType = unpackChannelInfo.deviceType || 0;
  511 + receiveChannelInfo.optionJsonData = unpackChannelInfo.optionJsonData || "";
  512 + //消息不是自己同步的,需要处理
  513 + if (unpackChannelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  514 + //正在推流
  515 + receiveChannelInfo.m3u8Url = "";
  516 + receiveChannelInfo.rtmpUrl = "";
  517 + receiveChannelInfo.replay = "";
  518 +
  519 + receiveChannelInfo.seek = seek || 0;//这个是录制回放时使用的seek
  520 +
  521 + let m3u8Stream = this.mediaModule.getMediaPlayPath({"type": "m3u8", "streamId": unpackChannelInfo.streamId});
  522 + let rtmpStream = this.mediaModule.getMediaPlayPath({"type": "rtmp", "streamId": unpackChannelInfo.streamId});
  523 + let replay = this.mediaModule.getMediaRecordPlaybackPath({
  524 + "type": "m3u8",
  525 + "streamId": unpackChannelInfo.streamId
  526 + });
  527 +
  528 + if (m3u8Stream.code == 0) {
  529 + receiveChannelInfo.m3u8Url = m3u8Stream.playUrl;
  530 + }
  531 + if (rtmpStream.code == 0) {
  532 + receiveChannelInfo.rtmpUrl = rtmpStream.playUrl;
  533 + }
  534 + if (replay.code == 0) {
  535 + receiveChannelInfo.replay = replay.playUrl;
  536 + }
  537 +
  538 + if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE) {
  539 + //广播播放视频的消息
  540 + loger.log("VIDEO_PLAY", receiveChannelInfo);
  541 + this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);
  542 + } else {
  543 + //播放屏幕共享
  544 + loger.log("SCREEN_SHARE_PLAY", receiveChannelInfo);
  545 + this._emit(MessageTypes.SCREEN_SHARE_PLAY, receiveChannelInfo);
413 546
414 - // 视频消息处理,内部处理,不需要告诉应用层  
415 - receiveVideoCommandHandler(_data) {  
416 - let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);  
417 - if (videoReceivePdu == null) {  
418 - loger.warn("视频控制消息处理,收到的消息为null,不做处理");  
419 - return;  
420 } 547 }
421 - videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码  
422 -  
423 - let dataObj= {};  
424 - try{  
425 - dataObj=JSON.parse(videoReceivePdu.data);  
426 - }catch (err){  
427 - loger.warn('控制消息->JSON转换失败');  
428 - dataObj= videoReceivePdu.data;  
429 - }  
430 - videoReceivePdu.data=dataObj;  
431 - //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理  
432 - if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {  
433 - loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId); 548 + } else {
  549 + if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE) {
  550 + //停止播放视频
  551 + loger.log("VIDEO_STOP", receiveChannelInfo);
  552 + this._emit(MessageTypes.VIDEO_STOP, receiveChannelInfo);
434 } else { 553 } else {
435 - loger.log('视频控制消息处理 .',videoReceivePdu);  
436 - this._emit(MessageTypes.VIDEO_BROADCAST, videoReceivePdu);  
437 - } 554 + //停止播放屏幕共享
  555 + if (unpackChannelInfo.channelId != 0) {
  556 + loger.log("SCREEN_SHARE_STOP", receiveChannelInfo);
  557 + this._emit(MessageTypes.SCREEN_SHARE_STOP, receiveChannelInfo);
  558 + } else {
  559 +
  560 + loger.log("停止播放视频->channelId=0->不合法的id", receiveChannelInfo);
  561 + }
  562 + }
  563 +
  564 + }
  565 + } else {
  566 + loger.warn("视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:");
  567 + loger.log(unpackChannelInfo);
  568 + if (unpackChannelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  569 + GlobalConfig.openCamera = EngineUtils.creatTimestamp();
  570 + GlobalConfig.openMicrophones = GlobalConfig.openCamera;
  571 + } else {
  572 + GlobalConfig.openCamera = 0;
  573 + GlobalConfig.openMicrophones = 0;
  574 + }
  575 +
  576 + //更新用户的摄像头和麦克风状态
  577 + if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE) {
  578 + //非屏幕共享的情况下才更新状态
  579 + this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
  580 + nodeId: GlobalConfig.nodeId,
  581 + userRole: GlobalConfig.userRole,
  582 + userName: GlobalConfig.userName,
  583 + userId: GlobalConfig.userId,
  584 + openCamera: GlobalConfig.openCamera,
  585 + openMicrophones: GlobalConfig.openMicrophones
  586 + });
  587 + }
438 } 588 }
439 589
440 590
  591 + if (unpackChannelInfo.mediaType != ApeConsts.MEDIA_TYPE_SHARE) {
  592 + //非屏幕共享情况的处理
  593 + MediaModule.allMediaChannelsList[itemIdx] = unpackChannelInfo;
  594 + console.log('MediaModule.allMediaChannelsList', MediaModule.allMediaChannelsList);
  595 + this._emit(MessageTypes.VIDEO_UPDATE, unpackChannelInfo);
  596 + }
441 597
442 - tableUpdateHandler(owner, itemIdx, itemData,seek) {  
443 - let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);  
444 - loger.log("tableUpdateHandler->channel",itemIdx,'mediaType',unpackChannelInfo.mediaType,'status->',unpackChannelInfo.status,"seek->",seek);  
445 -  
446 - //****很重要********  
447 - //如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)  
448 - if(owner==0){  
449 - loger.log("释放占用的频道,channel",itemIdx);  
450 - unpackChannelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
451 - unpackChannelInfo.streamId="";  
452 - }  
453 - //屏幕共享的流不保存  
454 - if(unpackChannelInfo.mediaType!=ApeConsts.MEDIA_TYPE_SHARE&&unpackChannelInfo.channelId>0){  
455 - this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;  
456 - }  
457 -  
458 - if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){  
459 - let receiveChannelInfo={};  
460 - receiveChannelInfo.mediaId=unpackChannelInfo.channelId;  
461 - receiveChannelInfo.fromNodeId=unpackChannelInfo.fromNodeId;  
462 - receiveChannelInfo.userName=unpackChannelInfo.userName||"";  
463 - receiveChannelInfo.userRole=unpackChannelInfo.userRole||ApeConsts.normal;  
464 - receiveChannelInfo.mediaType=unpackChannelInfo.mediaType||ApeConsts.MEDIA_TYPE_DEFAULT;  
465 - receiveChannelInfo.screenWidth=unpackChannelInfo.screenWidth||GlobalConfig.screenWidth;  
466 - receiveChannelInfo.screenHeight=unpackChannelInfo.screenHeight||GlobalConfig.screenHeight;  
467 - receiveChannelInfo.deviceType=unpackChannelInfo.deviceType||0;  
468 - receiveChannelInfo.optionJsonData=unpackChannelInfo.optionJsonData||"";  
469 - //消息不是自己同步的,需要处理  
470 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
471 - //正在推流  
472 - receiveChannelInfo.m3u8Url="";  
473 - receiveChannelInfo.rtmpUrl="";  
474 - receiveChannelInfo.replay="";  
475 -  
476 - receiveChannelInfo.seek=seek||0;//这个是录制回放时使用的seek  
477 -  
478 - let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
479 - let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});  
480 - let replay=this.mediaModule.getMediaRecordPlaybackPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
481 -  
482 - if(m3u8Stream.code==0){  
483 - receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;  
484 - }  
485 - if(rtmpStream.code==0){  
486 - receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;  
487 - }  
488 - if(replay.code==0){  
489 - receiveChannelInfo.replay=replay.playUrl;  
490 - }  
491 -  
492 - if(unpackChannelInfo.mediaType!=ApeConsts.MEDIA_TYPE_SHARE){  
493 - //广播播放视频的消息  
494 - loger.log("VIDEO_PLAY",receiveChannelInfo);  
495 - this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);  
496 - }else{  
497 - //播放屏幕共享  
498 - loger.log("SCREEN_SHARE_PLAY",receiveChannelInfo);  
499 - this._emit(MessageTypes.SCREEN_SHARE_PLAY, receiveChannelInfo);  
500 -  
501 - }  
502 - }else {  
503 - if(unpackChannelInfo.mediaType!=ApeConsts.MEDIA_TYPE_SHARE){  
504 - //停止播放视频  
505 - loger.log("VIDEO_STOP",receiveChannelInfo);  
506 - this._emit(MessageTypes.VIDEO_STOP, receiveChannelInfo);  
507 - }else{  
508 - //停止播放屏幕共享  
509 - if(unpackChannelInfo.channelId!=0){  
510 - loger.log("SCREEN_SHARE_STOP", receiveChannelInfo);  
511 - this._emit(MessageTypes.SCREEN_SHARE_STOP, receiveChannelInfo);  
512 - }else {  
513 -  
514 - loger.log("停止播放视频->channelId=0->不合法的id", receiveChannelInfo);  
515 - }  
516 - }  
517 -  
518 - }  
519 - }else {  
520 - loger.warn("视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:");  
521 - loger.log(unpackChannelInfo);  
522 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
523 - GlobalConfig.openCamera=EngineUtils.creatTimestamp();  
524 - GlobalConfig.openMicrophones=GlobalConfig.openCamera;  
525 - }else {  
526 - GlobalConfig.openCamera=0;  
527 - GlobalConfig.openMicrophones=0;  
528 - }  
529 -  
530 - //更新用户的摄像头和麦克风状态  
531 - if(unpackChannelInfo.mediaType!=ApeConsts.MEDIA_TYPE_SHARE) {  
532 - //非屏幕共享的情况下才更新状态  
533 - this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {  
534 - nodeId: GlobalConfig.nodeId,  
535 - userRole: GlobalConfig.userRole,  
536 - userName: GlobalConfig.userName,  
537 - userId: GlobalConfig.userId,  
538 - openCamera: GlobalConfig.openCamera,  
539 - openMicrophones: GlobalConfig.openMicrophones  
540 - });  
541 - }  
542 - }  
543 - 598 + }
544 599
545 - if(unpackChannelInfo.mediaType!=ApeConsts.MEDIA_TYPE_SHARE){  
546 - //非屏幕共享情况的处理  
547 - MediaModule.allMediaChannelsList[itemIdx]=unpackChannelInfo;  
548 - console.log('MediaModule.allMediaChannelsList',MediaModule.allMediaChannelsList);  
549 - this._emit(MessageTypes.VIDEO_UPDATE, unpackChannelInfo); 600 + //更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
  601 + updaterRecordApeStatus(_param) {
  602 + console.warn("录制状态发送改变->更新当前的状态->", this.mediaModule.mediaChannels);
  603 + for (let i in this.mediaModule.mediaChannels) {
  604 + let channelInfo = this.mediaModule.mediaChannels[i];
  605 + if (channelInfo) {
  606 + if (channelInfo.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
  607 + channelInfo.owner = 0;
  608 + } else {
  609 + channelInfo.owner = channelInfo.fromNodeId;
550 } 610 }
551 - 611 + this.sendTableUpdateHandler(channelInfo);
  612 + }
552 } 613 }
553 - //更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次  
554 - updaterRecordApeStatus(_param){  
555 - console.warn("录制状态发送改变->更新当前的状态->",this.mediaModule.mediaChannels);  
556 - for (let i in this.mediaModule.mediaChannels){  
557 - let channelInfo=this.mediaModule.mediaChannels[i];  
558 - if(channelInfo){  
559 - if(channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){  
560 - channelInfo.owner=0;  
561 - }else {  
562 - channelInfo.owner=channelInfo.fromNodeId;  
563 - }  
564 - this.sendTableUpdateHandler(channelInfo);  
565 - }  
566 - } 614 + }
  615 +
  616 + //清除当前模块的数据
  617 + clearData() {
  618 + loger.log("clearData->");
  619 + MediaModule.allMediaChannelsList = {};
  620 + }
  621 +
  622 + ///////数据的封包和解包/////////////////////////////////////////
  623 + packPdu(_param, _itemIdx) {
  624 + //验证坐标点集合数组是否合法
  625 + if (_param == null || _itemIdx == null) {
  626 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  627 + return null;
567 } 628 }
568 629
569 - //清除当前模块的数据  
570 - clearData(){  
571 - loger.log("clearData->");  
572 - MediaModule.allMediaChannelsList={}; 630 + //判断type类型,根据type设置不同的参数
  631 + let packPduModel = new pdu['RCVideoChannelInfoPdu'];
  632 + packPduModel.status = _param.status || ApeConsts.CHANNEL_STATUS_RELEASED;
  633 + packPduModel.channelId = _itemIdx;
  634 + packPduModel.streamId = _param.streamId || "";
  635 + packPduModel.siteId = _param.siteId || GlobalConfig.siteId;//GlobalConfig.siteId;
  636 + packPduModel.classId = parseInt(_param.classId) || parseInt(GlobalConfig.classId);
  637 + packPduModel.userId = _param.userId || "0";
  638 + packPduModel.mediaType = _param.mediaType || ApeConsts.MEDIA_TYPE_VIDEO;
  639 + packPduModel.timestamp = _param.timestamp || 0;
  640 + packPduModel.fromNodeId = _param.nodeId || GlobalConfig.nodeId;
  641 + packPduModel.userName = _param.userName || GlobalConfig.userName;
  642 + packPduModel.toNodeId = 0;
  643 + packPduModel.userRole = _param.userRole || GlobalConfig.userRole;
  644 + packPduModel.screenWidth = _param.screenWidth || GlobalConfig.screenWidth;
  645 + packPduModel.screenHeight = _param.screenHeight || GlobalConfig.screenHeight;
  646 + packPduModel.deviceType = _param.deviceType || GlobalConfig.deviceType;
  647 + packPduModel.optionJsonData = GlobalConfig.optionJsonData;
  648 + loger.log('packPdu->', packPduModel);
  649 + return packPduModel;
  650 + }
  651 +
  652 + unPackPdu(owner, itemIdx, itemData) {
  653 + loger.log("unPackPdu->owner:", owner, "itemIdx->", itemIdx);
  654 + if (owner == null || itemIdx == null || itemData == null) {
  655 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  656 + return null;
573 } 657 }
574 -  
575 - ///////数据的封包和解包/////////////////////////////////////////  
576 - packPdu(_param, _itemIdx) {  
577 - //验证坐标点集合数组是否合法  
578 - if (_param == null || _itemIdx == null) {  
579 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
580 - return null;  
581 - }  
582 -  
583 - //判断type类型,根据type设置不同的参数  
584 - let packPduModel = new pdu['RCVideoChannelInfoPdu'];  
585 - packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;  
586 - packPduModel.channelId = _itemIdx;  
587 - packPduModel.streamId = _param.streamId||"";  
588 - packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;  
589 - packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);  
590 - packPduModel.userId =_param.userId||"0";  
591 - packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_VIDEO;  
592 - packPduModel.timestamp =_param.timestamp||0;  
593 - packPduModel.fromNodeId = _param.nodeId||GlobalConfig.nodeId;  
594 - packPduModel.userName=_param.userName||GlobalConfig.userName;  
595 - packPduModel.toNodeId = 0;  
596 - packPduModel.userRole=_param.userRole||GlobalConfig.userRole;  
597 - packPduModel.screenWidth=_param.screenWidth||GlobalConfig.screenWidth;  
598 - packPduModel.screenHeight=_param.screenHeight||GlobalConfig.screenHeight;  
599 - packPduModel.deviceType=_param.deviceType||GlobalConfig.deviceType;  
600 - packPduModel.optionJsonData=_param.optionJsonData||GlobalConfig.optionJsonData;  
601 - loger.log('packPdu->',packPduModel);  
602 - return packPduModel;  
603 - }  
604 -  
605 - unPackPdu(owner, itemIdx, itemData) {  
606 - loger.log("unPackPdu->owner:",owner,"itemIdx->",itemIdx);  
607 - if (owner == null || itemIdx == null || itemData == null) {  
608 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
609 - return null;  
610 - }  
611 - try {  
612 - let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);  
613 - loger.log(videoChannelInfo);  
614 - return videoChannelInfo;  
615 - } catch (err) {  
616 - loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);  
617 - }  
618 - return null; 658 + try {
  659 + let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
  660 + loger.log(videoChannelInfo);
  661 + return videoChannelInfo;
  662 + } catch (err) {
  663 + loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
619 } 664 }
  665 + return null;
  666 + }
620 } 667 }
621 668
622 export default VideoApe; 669 export default VideoApe;