1.音视频模块停止推流接口增加参数字段,根据字段来做停止推流是否频道占用;分4种情况
A.停止自己占用的所有流 B.停止自己占用的指定id流 C.停止其他人(nodeId)占用的所有流; D停止其他人(nodeId)占用的指定id流; 2.获取推流地址时,如果频道被占用完,返回值中增加当前频道的所有信息
正在显示
7 个修改的文件
包含
108 行增加
和
29 行删除
| @@ -34,15 +34,6 @@ let _audio_ape; | @@ -34,15 +34,6 @@ let _audio_ape; | ||
| 34 | let _doc_ape; | 34 | let _doc_ape; |
| 35 | let _whiteboard_ape; | 35 | let _whiteboard_ape; |
| 36 | 36 | ||
| 37 | -////初始化成功回调函数 | ||
| 38 | -//let _initSuccessCallBackFun; | ||
| 39 | -// | ||
| 40 | -////加入会议成功回调函数 | ||
| 41 | -//let _joinClassSuccessCallBackFun; | ||
| 42 | -// | ||
| 43 | -////监听mcu所有错误异常回调函数 | ||
| 44 | -//let _mcuErrorCallBackFun; | ||
| 45 | - | ||
| 46 | //MCUClient 外部实例化主类 | 37 | //MCUClient 外部实例化主类 |
| 47 | export default class MessageEntrance extends Emiter { | 38 | export default class MessageEntrance extends Emiter { |
| 48 | constructor() { | 39 | constructor() { |
| @@ -221,7 +212,7 @@ export default class MessageEntrance extends Emiter { | @@ -221,7 +212,7 @@ export default class MessageEntrance extends Emiter { | ||
| 221 | _onClassDeleteRoster(_data){ | 212 | _onClassDeleteRoster(_data){ |
| 222 | //{"nodeId":nodeId} | 213 | //{"nodeId":nodeId} |
| 223 | //当有人员离开的时候,如果离开的人员已经推流,那么需要停止推流,然后释放channel; | 214 | //当有人员离开的时候,如果离开的人员已经推流,那么需要停止推流,然后释放channel; |
| 224 | -/* if(_data!=null&&_data.nodeId!=null){ | 215 | + /* if(_data!=null&&_data.nodeId!=null){ |
| 225 | loger.log("有人员离开,检查一下离开的人员是否关闭推流"); | 216 | loger.log("有人员离开,检查一下离开的人员是否关闭推流"); |
| 226 | if(_video_ape){ | 217 | if(_video_ape){ |
| 227 | _video_ape.stopPublishVideo(_data); | 218 | _video_ape.stopPublishVideo(_data); |
| @@ -104,24 +104,65 @@ class AudioApe extends Ape { | @@ -104,24 +104,65 @@ class AudioApe extends Ape { | ||
| 104 | channelInfo.userId=GlobalConfig.userId; | 104 | channelInfo.userId=GlobalConfig.userId; |
| 105 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO; | 105 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO; |
| 106 | this.sendTableUpdateHandler(channelInfo); | 106 | this.sendTableUpdateHandler(channelInfo); |
| 107 | - return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} | 107 | + return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId}; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | //停止推流, | 110 | //停止推流, |
| 111 | stopPublishAudio(_param) { | 111 | stopPublishAudio(_param) { |
| 112 | - loger.log('stopPublishAudio'); | 112 | + loger.log('stopPublishAudio ->_param',_param); |
| 113 | if(!this.mcu.connected){ | 113 | if(!this.mcu.connected){ |
| 114 | loger.warn(GlobalConfig.getCurrentStatus()); | 114 | loger.warn(GlobalConfig.getCurrentStatus()); |
| 115 | return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | 115 | return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; |
| 116 | } | 116 | } |
| 117 | - //_param如果为空或者0,那么默认就是当前自己的nodeId,否则用_param | ||
| 118 | - let nodeId; | 117 | + |
| 118 | + //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param | ||
| 119 | + let nodeId=GlobalConfig.nodeId; | ||
| 119 | if(_param&&parseInt(_param.nodeId)>0){ | 120 | if(_param&&parseInt(_param.nodeId)>0){ |
| 120 | nodeId=parseInt(_param.nodeId); | 121 | nodeId=parseInt(_param.nodeId); |
| 122 | + } | ||
| 123 | + | ||
| 124 | + //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道 | ||
| 125 | + let releaseChannelId=0; | ||
| 126 | + if(_param&&parseInt(_param.mediaId)>0){ | ||
| 127 | + releaseChannelId=parseInt(_param.mediaId); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + //释放channelId 的占用 | ||
| 131 | + if(releaseChannelId>0){ | ||
| 132 | + //第一种情况,释放nodeId占用的指定mediaId (channelId) | ||
| 133 | + this._releaseChannelForNodeId(nodeId,releaseChannelId); | ||
| 121 | }else { | 134 | }else { |
| 122 | - nodeId=GlobalConfig.nodeId; | 135 | + //第二种情况,释放nodeId占用的所有channelId |
| 136 | + this._releaseNodeIdAllChannel(nodeId); | ||
| 123 | } | 137 | } |
| 138 | + } | ||
| 124 | 139 | ||
| 140 | + //释放nodeId占用的指定的channelId频道 | ||
| 141 | + _releaseChannelForNodeId(nodeId,channelId){ | ||
| 142 | + loger.log(nodeId,"_releaseChannelForNodeId-->channelId",channelId); | ||
| 143 | + let channelInfo=this.mediaModule.mediaChannels[channelId]; | ||
| 144 | + if(channelInfo&&channelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){ | ||
| 145 | + if(channelInfo.fromNodeId==nodeId){ | ||
| 146 | + let channelInfo={}; | ||
| 147 | + channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED; | ||
| 148 | + channelInfo.fromNodeId=0; | ||
| 149 | + channelInfo.channelId=channelId; | ||
| 150 | + channelInfo.timestamp=0; | ||
| 151 | + channelInfo.classId=GlobalConfig.classId; | ||
| 152 | + channelInfo.toNodeId=0; | ||
| 153 | + channelInfo.userId=GlobalConfig.userId; | ||
| 154 | + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; | ||
| 155 | + this.sendTableUpdateHandler(channelInfo); | ||
| 156 | + }else { | ||
| 157 | + loger.warn(channelId,"不属于nodeId",nodeId,"不能释放",channelInfo); | ||
| 158 | + } | ||
| 159 | + }else { | ||
| 160 | + loger.warn(nodeId,"要释放的channel不存在或者已经释放-->channelId",channelInfo); | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + //释放nodeId占用的所有频道 | ||
| 164 | + _releaseNodeIdAllChannel(nodeId){ | ||
| 165 | + loger.log(nodeId,"_releaseNodeIdAllChannel"); | ||
| 125 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); | 166 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); |
| 126 | if (openingChannel == 0) { | 167 | if (openingChannel == 0) { |
| 127 | loger.warn(nodeId,"没有占用channel不需要处理"); | 168 | loger.warn(nodeId,"没有占用channel不需要处理"); |
| @@ -138,8 +179,12 @@ class AudioApe extends Ape { | @@ -138,8 +179,12 @@ class AudioApe extends Ape { | ||
| 138 | channelInfo.userId=GlobalConfig.userId; | 179 | channelInfo.userId=GlobalConfig.userId; |
| 139 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; | 180 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; |
| 140 | this.sendTableUpdateHandler(channelInfo); | 181 | this.sendTableUpdateHandler(channelInfo); |
| 182 | + //递归检查,800毫秒之后执行 | ||
| 183 | + setTimeout(function(){ | ||
| 184 | + loger.warn(nodeId,"递归检查频道是否占用"); | ||
| 185 | + this._releaseNodeIdAllChannel(nodeId); | ||
| 186 | + }.bind(this),800); | ||
| 141 | } | 187 | } |
| 142 | - | ||
| 143 | sendAudioBroadcastMsg(_param) { | 188 | sendAudioBroadcastMsg(_param) { |
| 144 | loger.log('sendAudioBroadcastMsg',_param); | 189 | loger.log('sendAudioBroadcastMsg',_param); |
| 145 | if(!this.mcu.connected){ | 190 | if(!this.mcu.connected){ |
| @@ -79,8 +79,8 @@ class ChatApe extends Ape { | @@ -79,8 +79,8 @@ class ChatApe extends Ape { | ||
| 79 | var chatReceivePdu = pdu['RCChatSendDataRequestPdu'].decode(chatBuffer); | 79 | var chatReceivePdu = pdu['RCChatSendDataRequestPdu'].decode(chatBuffer); |
| 80 | 80 | ||
| 81 | var chatMsg = {}; | 81 | var chatMsg = {}; |
| 82 | - chatMsg.fromNodeID = chatReceivePdu.initiator; | ||
| 83 | - chatMsg.toNodeID = chatReceivePdu.peer; | 82 | + chatMsg.fromNodeId = chatReceivePdu.initiator; |
| 83 | + chatMsg.toNodeId = chatReceivePdu.peer; | ||
| 84 | chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2); | 84 | chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2); |
| 85 | chatMsg.fromName = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.fromName, 2); | 85 | chatMsg.fromName = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.fromName, 2); |
| 86 | chatMsg.fromRole = chatReceivePdu.fromRole; | 86 | chatMsg.fromRole = chatReceivePdu.fromRole; |
| @@ -246,7 +246,7 @@ class DocApe extends Ape { | @@ -246,7 +246,7 @@ class DocApe extends Ape { | ||
| 246 | docDataModel.action=ApeConsts.DOC_ACTION_SWITCH_DOC; | 246 | docDataModel.action=ApeConsts.DOC_ACTION_SWITCH_DOC; |
| 247 | docDataModel.visible=paramInfo.visible||false;//默认是false | 247 | docDataModel.visible=paramInfo.visible||false;//默认是false |
| 248 | 248 | ||
| 249 | - loger.log('切换文档,当前文档和上一个显示的文档都需要更新状态'); | 249 | + //loger.log('切换文档,当前文档和上一个显示的文档都需要更新状态'); |
| 250 | console.log({"oldDoc":oldDocModel,"nowDoc":docDataModel}); | 250 | console.log({"oldDoc":oldDocModel,"nowDoc":docDataModel}); |
| 251 | //更新当前选择的文档 | 251 | //更新当前选择的文档 |
| 252 | this.updaterDoc(docDataModel,docDataModel.itemIdx); | 252 | this.updaterDoc(docDataModel,docDataModel.itemIdx); |
| @@ -53,7 +53,7 @@ class MediaModule { | @@ -53,7 +53,7 @@ class MediaModule { | ||
| 53 | //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 | 53 | //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 |
| 54 | let freeChannel = this.getFreeMediaChannel(); | 54 | let freeChannel = this.getFreeMediaChannel(); |
| 55 | if (freeChannel == 0) { | 55 | if (freeChannel == 0) { |
| 56 | - return {"code":ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; | 56 | + return {"code":ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaChannels}; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | //默认方式推流 | 59 | //默认方式推流 |
| @@ -107,26 +107,64 @@ class VideoApe extends Ape { | @@ -107,26 +107,64 @@ class VideoApe extends Ape { | ||
| 107 | channelInfo.userId=GlobalConfig.userId; | 107 | channelInfo.userId=GlobalConfig.userId; |
| 108 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO; | 108 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO; |
| 109 | this.sendTableUpdateHandler(channelInfo); | 109 | this.sendTableUpdateHandler(channelInfo); |
| 110 | - return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} | 110 | + return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId}; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | //停止推流, | 113 | //停止推流, |
| 114 | stopPublishVideo(_param) { | 114 | stopPublishVideo(_param) { |
| 115 | + loger.log('stopPublishVideo ->_param',_param); | ||
| 115 | if(!this.mcu.connected){ | 116 | if(!this.mcu.connected){ |
| 116 | loger.warn(GlobalConfig.getCurrentStatus()); | 117 | loger.warn(GlobalConfig.getCurrentStatus()); |
| 117 | return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; | 118 | return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | - //_param如果为空,那么默认就是当前自己的nodeId,否则用_param | ||
| 121 | - let nodeId; | 121 | + //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param |
| 122 | + let nodeId=GlobalConfig.nodeId; | ||
| 122 | if(_param&&parseInt(_param.nodeId)>0){ | 123 | if(_param&&parseInt(_param.nodeId)>0){ |
| 123 | nodeId=parseInt(_param.nodeId); | 124 | nodeId=parseInt(_param.nodeId); |
| 124 | - }else { | ||
| 125 | - nodeId=GlobalConfig.nodeId; | ||
| 126 | } | 125 | } |
| 127 | 126 | ||
| 128 | - loger.log('stopPublishVideo ->nodeId',nodeId,' maxVideoChannels', GlobalConfig.maxVideoChannels); | 127 | + //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道 |
| 128 | + let releaseChannelId=0; | ||
| 129 | + if(_param&&parseInt(_param.mediaId)>0){ | ||
| 130 | + releaseChannelId=parseInt(_param.mediaId); | ||
| 131 | + } | ||
| 129 | 132 | ||
| 133 | + //释放channelId 的占用 | ||
| 134 | + if(releaseChannelId>0){ | ||
| 135 | + //第一种情况,释放nodeId占用的指定mediaId (channelId) | ||
| 136 | + this._releaseChannelForNodeId(nodeId,releaseChannelId); | ||
| 137 | + }else { | ||
| 138 | + //第二种情况,释放nodeId占用的所有channelId | ||
| 139 | + this._releaseNodeIdAllChannel(nodeId); | ||
| 140 | + } | ||
| 141 | + } | ||
| 142 | + //释放nodeId占用的指定的channelId频道 | ||
| 143 | + _releaseChannelForNodeId(nodeId,channelId){ | ||
| 144 | + loger.log(nodeId,"_releaseChannelForNodeId-->channelId",channelId); | ||
| 145 | + let channelInfo=this.mediaModule.mediaChannels[channelId]; | ||
| 146 | + if(channelInfo&&channelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){ | ||
| 147 | + if(channelInfo.fromNodeId==nodeId){ | ||
| 148 | + let channelInfo={}; | ||
| 149 | + channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED; | ||
| 150 | + channelInfo.fromNodeId=0; | ||
| 151 | + channelInfo.channelId=channelId; | ||
| 152 | + channelInfo.timestamp=0; | ||
| 153 | + channelInfo.classId=GlobalConfig.classId; | ||
| 154 | + channelInfo.toNodeId=0; | ||
| 155 | + channelInfo.userId=GlobalConfig.userId; | ||
| 156 | + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; | ||
| 157 | + this.sendTableUpdateHandler(channelInfo); | ||
| 158 | + }else { | ||
| 159 | + loger.warn(channelId,"不属于nodeId",nodeId,"不能释放",channelInfo); | ||
| 160 | + } | ||
| 161 | + }else { | ||
| 162 | + loger.warn(nodeId,"要释放的channel不存在或者已经释放-->channelId",channelInfo); | ||
| 163 | + } | ||
| 164 | + } | ||
| 165 | + //释放nodeId占用的所有频道 | ||
| 166 | + _releaseNodeIdAllChannel(nodeId){ | ||
| 167 | + loger.log(nodeId,"_releaseNodeIdAllChannel"); | ||
| 130 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); | 168 | let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); |
| 131 | if (openingChannel == 0) { | 169 | if (openingChannel == 0) { |
| 132 | loger.warn(nodeId,"没有占用channel不需要处理"); | 170 | loger.warn(nodeId,"没有占用channel不需要处理"); |
| @@ -143,6 +181,11 @@ class VideoApe extends Ape { | @@ -143,6 +181,11 @@ class VideoApe extends Ape { | ||
| 143 | channelInfo.userId=GlobalConfig.userId; | 181 | channelInfo.userId=GlobalConfig.userId; |
| 144 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; | 182 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; |
| 145 | this.sendTableUpdateHandler(channelInfo); | 183 | this.sendTableUpdateHandler(channelInfo); |
| 184 | + //递归检查,800毫秒之后执行 | ||
| 185 | + setTimeout(function(){ | ||
| 186 | + loger.warn(nodeId,"递归检查频道是否占用"); | ||
| 187 | + this._releaseNodeIdAllChannel(nodeId); | ||
| 188 | + }.bind(this),800); | ||
| 146 | } | 189 | } |
| 147 | 190 | ||
| 148 | sendVideoBroadcastMsg(_param) { | 191 | sendVideoBroadcastMsg(_param) { |
| @@ -172,7 +215,7 @@ class VideoApe extends Ape { | @@ -172,7 +215,7 @@ class VideoApe extends Ape { | ||
| 172 | let freeChannel = this.mediaModule.getFreeMediaChannel(); | 215 | let freeChannel = this.mediaModule.getFreeMediaChannel(); |
| 173 | if (freeChannel == 0) { | 216 | if (freeChannel == 0) { |
| 174 | loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param); | 217 | loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param); |
| 175 | - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; | 218 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels}; |
| 176 | } | 219 | } |
| 177 | } | 220 | } |
| 178 | /* message RCVideoSendDataRequestPdu { | 221 | /* message RCVideoSendDataRequestPdu { |
| @@ -87,7 +87,7 @@ class MCU extends Emiter { | @@ -87,7 +87,7 @@ class MCU extends Emiter { | ||
| 87 | let pduType = pduMsg.get("type"); | 87 | let pduType = pduMsg.get("type"); |
| 88 | let pduData = pduMsg.get("data"); | 88 | let pduData = pduMsg.get("data"); |
| 89 | //loger.data('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId); | 89 | //loger.data('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId); |
| 90 | - loger.log('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId); | 90 | + //loger.log('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId); |
| 91 | switch (pduType) { | 91 | switch (pduType) { |
| 92 | case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE: | 92 | case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE: |
| 93 | //加入会议请求返回数据处理 | 93 | //加入会议请求返回数据处理 |
| @@ -116,7 +116,7 @@ class MCU extends Emiter { | @@ -116,7 +116,7 @@ class MCU extends Emiter { | ||
| 116 | let sessionLabel = ApeConsts(pduMsg.sessionId); | 116 | let sessionLabel = ApeConsts(pduMsg.sessionId); |
| 117 | if (ape) { | 117 | if (ape) { |
| 118 | let subTypeLabel = pdu.id2type(pduMsg.subType); | 118 | let subTypeLabel = pdu.id2type(pduMsg.subType); |
| 119 | - loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType); | 119 | + //loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType); |
| 120 | //ape广播事件,只要ape中监听就能收到 | 120 | //ape广播事件,只要ape中监听就能收到 |
| 121 | ape._emit(pduMsg.subType, pduMsg.data); | 121 | ape._emit(pduMsg.subType, pduMsg.data); |
| 122 | } else { | 122 | } else { |
-
请 注册 或 登录 后发表评论