1.音视频模块推流接口增加optionJsonData:{"bufferTime":0}} 用于设置播放流的时候的bufferTime
正在显示
3 个修改的文件
包含
1066 行增加
和
984 行删除
| @@ -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; |
-
请 注册 或 登录 后发表评论