正在显示
11 个修改的文件
包含
723 行增加
和
401 行删除
| @@ -11,6 +11,7 @@ import Loger from 'Loger'; | @@ -11,6 +11,7 @@ import Loger from 'Loger'; | ||
| 11 | import ConferApe from 'apes/ConferApe'; | 11 | import ConferApe from 'apes/ConferApe'; |
| 12 | import ChatApe from 'apes/ChatApe'; | 12 | import ChatApe from 'apes/ChatApe'; |
| 13 | import VideoApe from 'apes/VideoApe'; | 13 | import VideoApe from 'apes/VideoApe'; |
| 14 | +import AudioApe from 'apes/AudioApe'; | ||
| 14 | import DocApe from 'apes/DocApe'; | 15 | import DocApe from 'apes/DocApe'; |
| 15 | import WhiteBoardApe from 'apes/WhiteBoardApe'; | 16 | import WhiteBoardApe from 'apes/WhiteBoardApe'; |
| 16 | import EngineUtils from "EngineUtils"; | 17 | import EngineUtils from "EngineUtils"; |
| @@ -29,6 +30,7 @@ let _mcu ; | @@ -29,6 +30,7 @@ let _mcu ; | ||
| 29 | let _confer_ape; | 30 | let _confer_ape; |
| 30 | let _chat_ape; | 31 | let _chat_ape; |
| 31 | let _video_ape; | 32 | let _video_ape; |
| 33 | +let _audio_ape; | ||
| 32 | let _doc_ape; | 34 | let _doc_ape; |
| 33 | let _whiteboard_ape; | 35 | let _whiteboard_ape; |
| 34 | 36 | ||
| @@ -68,7 +70,7 @@ export default class MessageEntrance extends Emiter { | @@ -68,7 +70,7 @@ export default class MessageEntrance extends Emiter { | ||
| 68 | // 底层MCU消息层 | 70 | // 底层MCU消息层 |
| 69 | _mcu = Mcu; | 71 | _mcu = Mcu; |
| 70 | _mcu.on('*', (type, data) => this._emit(type, data)); | 72 | _mcu.on('*', (type, data) => this._emit(type, data)); |
| 71 | - _mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._joinClassSuccessHandler.bind(this));//加入MCU会议完成 | 73 | + _mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._mcuJoinClassSuccessHandler.bind(this));//加入MCU会议完成 |
| 72 | 74 | ||
| 73 | 75 | ||
| 74 | // 注册所有应用Ape | 76 | // 注册所有应用Ape |
| @@ -87,11 +89,14 @@ export default class MessageEntrance extends Emiter { | @@ -87,11 +89,14 @@ export default class MessageEntrance extends Emiter { | ||
| 87 | _video_ape.on('*', (type, data) => this._emit(type, data)); | 89 | _video_ape.on('*', (type, data) => this._emit(type, data)); |
| 88 | _video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this)); | 90 | _video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this)); |
| 89 | 91 | ||
| 92 | + _audio_ape= new AudioApe(); | ||
| 93 | + _audio_ape.on('*', (type, data) => this._emit(type, data)); | ||
| 94 | + _audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this)); | ||
| 95 | + | ||
| 90 | _whiteboard_ape = new WhiteBoardApe(); | 96 | _whiteboard_ape = new WhiteBoardApe(); |
| 91 | _whiteboard_ape.on('*', (type, data) => this._emit(type, data)); | 97 | _whiteboard_ape.on('*', (type, data) => this._emit(type, data)); |
| 92 | //_whiteboard_ape.on(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE, this.annoUpdateHandler.bind(this)); | 98 | //_whiteboard_ape.on(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE, this.annoUpdateHandler.bind(this)); |
| 93 | 99 | ||
| 94 | - | ||
| 95 | _doc_ape = new DocApe(); | 100 | _doc_ape = new DocApe(); |
| 96 | _doc_ape.on('*', (type, data) => this._emit(type, data)); | 101 | _doc_ape.on('*', (type, data) => this._emit(type, data)); |
| 97 | _doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this)); | 102 | _doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this)); |
| @@ -115,13 +120,20 @@ export default class MessageEntrance extends Emiter { | @@ -115,13 +120,20 @@ export default class MessageEntrance extends Emiter { | ||
| 115 | this.sendChatMsg = this._sendChatMsg; | 120 | this.sendChatMsg = this._sendChatMsg; |
| 116 | 121 | ||
| 117 | //videoApe | 122 | //videoApe |
| 118 | - this.getPlayVideoPath = this._getPlayVideoPath; | ||
| 119 | - this.getPublishVideoPath = this._getPublishVideoPath; | 123 | + this.getVideoPlayPath = this._getPlayVideoPath; |
| 124 | + this.getVideoPublishPath = this._getPublishVideoPath; | ||
| 120 | this.publishVideo = this._publishVideo; | 125 | this.publishVideo = this._publishVideo; |
| 121 | this.stopPublishVideo = this._stopPublishVideo; | 126 | this.stopPublishVideo = this._stopPublishVideo; |
| 122 | - this.sendVideoCommandMsg=this.sendVideoCommandMsg; | 127 | + this.sendVideoBroadcastMsg=this.sendVideoCommandMsg; |
| 123 | 128 | ||
| 124 | 129 | ||
| 130 | + //audioApe | ||
| 131 | + this.getAudioPlayPath = this._getPlayAudioPath; | ||
| 132 | + this.getAudioPublishPath = this._getPublishAudioPath; | ||
| 133 | + this.publishAudio = this._publishAudio; | ||
| 134 | + this.stopPublishAudio = this._stopPublishAudio; | ||
| 135 | + this.sendAudioBroadcastMsg=this.sendAudioCommandMsg; | ||
| 136 | + | ||
| 125 | //whiteBoradApe | 137 | //whiteBoradApe |
| 126 | this.sendInsertAnnotaion = this._sendInsertAnnotaion; | 138 | this.sendInsertAnnotaion = this._sendInsertAnnotaion; |
| 127 | //this.sendDeleteAnnotaion=this._sendDeleteAnnotaion; | 139 | //this.sendDeleteAnnotaion=this._sendDeleteAnnotaion; |
| @@ -174,6 +186,7 @@ export default class MessageEntrance extends Emiter { | @@ -174,6 +186,7 @@ export default class MessageEntrance extends Emiter { | ||
| 174 | _onClassStatusInfoChange(_param) { | 186 | _onClassStatusInfoChange(_param) { |
| 175 | this._sassSaveClassStatusInfo(); | 187 | this._sassSaveClassStatusInfo(); |
| 176 | } | 188 | } |
| 189 | + | ||
| 177 | //有人员离开 | 190 | //有人员离开 |
| 178 | _onClassDeleteRoster(_data){ | 191 | _onClassDeleteRoster(_data){ |
| 179 | //{"nodeId":nodeId} | 192 | //{"nodeId":nodeId} |
| @@ -184,18 +197,25 @@ export default class MessageEntrance extends Emiter { | @@ -184,18 +197,25 @@ export default class MessageEntrance extends Emiter { | ||
| 184 | if(_video_ape){ | 197 | if(_video_ape){ |
| 185 | _video_ape.stopPublishVideo(_data); | 198 | _video_ape.stopPublishVideo(_data); |
| 186 | } | 199 | } |
| 200 | + if(_audio_ape){ | ||
| 201 | + _audio_ape.stopPublishAudio(_data); | ||
| 202 | + } | ||
| 187 | } | 203 | } |
| 188 | } | 204 | } |
| 189 | 205 | ||
| 190 | //当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel | 206 | //当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel |
| 191 | //的占用状态导致,对于这种情况,需要释放掉 | 207 | //的占用状态导致,对于这种情况,需要释放掉 |
| 192 | _onClassNonentityRoster(_param){ | 208 | _onClassNonentityRoster(_param){ |
| 193 | - if(_param==null||_param.fromNodeId==null){ | 209 | + if(_param==null||_param.nodeId==null){ |
| 194 | loger.warn("onClassNonentityRoster.参数错误") | 210 | loger.warn("onClassNonentityRoster.参数错误") |
| 195 | return; | 211 | return; |
| 196 | } | 212 | } |
| 213 | + let data={"nodeId":_param.nodeId}; | ||
| 197 | if(_video_ape){ | 214 | if(_video_ape){ |
| 198 | - _video_ape.stopPublishVideo({"nodeId":_param.fromNodeId}); | 215 | + _video_ape.stopPublishVideo(data); |
| 216 | + } | ||
| 217 | + if(_audio_ape){ | ||
| 218 | + _audio_ape.stopPublishAudio(data); | ||
| 199 | } | 219 | } |
| 200 | } | 220 | } |
| 201 | 221 | ||
| @@ -219,12 +239,14 @@ export default class MessageEntrance extends Emiter { | @@ -219,12 +239,14 @@ export default class MessageEntrance extends Emiter { | ||
| 219 | return; | 239 | return; |
| 220 | } | 240 | } |
| 221 | loger.log('init', _param); | 241 | loger.log('init', _param); |
| 242 | + | ||
| 222 | //保存参数 | 243 | //保存参数 |
| 223 | GlobalConfig.classId = parseInt(_param.classId); | 244 | GlobalConfig.classId = parseInt(_param.classId); |
| 224 | GlobalConfig.portal = _param.portal; | 245 | GlobalConfig.portal = _param.portal; |
| 225 | GlobalConfig.userRole = _param.userRole || ApeConsts.normal; | 246 | GlobalConfig.userRole = _param.userRole || ApeConsts.normal; |
| 226 | GlobalConfig.userId = _param.userId || "0"; | 247 | GlobalConfig.userId = _param.userId || "0"; |
| 227 | GlobalConfig.userName=_param.userName || ""; | 248 | GlobalConfig.userName=_param.userName || ""; |
| 249 | + | ||
| 228 | //获取课堂校验信息 | 250 | //获取课堂校验信息 |
| 229 | if (_sass) { | 251 | if (_sass) { |
| 230 | _sass.getJoinParams(GlobalConfig.getClassInfo()); | 252 | _sass.getJoinParams(GlobalConfig.getClassInfo()); |
| @@ -253,7 +275,7 @@ export default class MessageEntrance extends Emiter { | @@ -253,7 +275,7 @@ export default class MessageEntrance extends Emiter { | ||
| 253 | GlobalConfig.password = _param.password || ""; | 275 | GlobalConfig.password = _param.password || ""; |
| 254 | GlobalConfig.hasCamera=(typeof _param.hasCamera=="boolean")? _param.hasCamera:false; | 276 | GlobalConfig.hasCamera=(typeof _param.hasCamera=="boolean")? _param.hasCamera:false; |
| 255 | GlobalConfig.hasMicrophone=(typeof _param.hasMicrophone=="boolean")? _param.hasMicrophone:false; | 277 | GlobalConfig.hasMicrophone=(typeof _param.hasMicrophone=="boolean")? _param.hasMicrophone:false; |
| 256 | - debugger; | 278 | + //debugger; |
| 257 | //开始校验 | 279 | //开始校验 |
| 258 | if (_sass) { | 280 | if (_sass) { |
| 259 | _sass.passwordAndMd5Checking(GlobalConfig.getClassInfo()); | 281 | _sass.passwordAndMd5Checking(GlobalConfig.getClassInfo()); |
| @@ -269,13 +291,7 @@ export default class MessageEntrance extends Emiter { | @@ -269,13 +291,7 @@ export default class MessageEntrance extends Emiter { | ||
| 269 | GlobalConfig.siteId = _data.siteId || ""; | 291 | GlobalConfig.siteId = _data.siteId || ""; |
| 270 | GlobalConfig.classType = _data.meetingType || 0; | 292 | GlobalConfig.classType = _data.meetingType || 0; |
| 271 | 293 | ||
| 272 | - /*//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的 | ||
| 273 | - if (GlobalConfig.userRole == "host") { | ||
| 274 | - GlobalConfig.passwordRequired = true; | ||
| 275 | - } else { | ||
| 276 | - GlobalConfig.passwordRequired = _data.passwordRequired || false; | ||
| 277 | - } | ||
| 278 | - */ | 294 | + //host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的 |
| 279 | GlobalConfig.passwordRequired = _data.passwordRequired || false;//md5验证的时候需要Sass返回的值,不能更改 | 295 | GlobalConfig.passwordRequired = _data.passwordRequired || false;//md5验证的时候需要Sass返回的值,不能更改 |
| 280 | 296 | ||
| 281 | loger.log('SASS平台获取入会验证信息成功.'); | 297 | loger.log('SASS平台获取入会验证信息成功.'); |
| @@ -303,7 +319,7 @@ export default class MessageEntrance extends Emiter { | @@ -303,7 +319,7 @@ export default class MessageEntrance extends Emiter { | ||
| 303 | } | 319 | } |
| 304 | } | 320 | } |
| 305 | 321 | ||
| 306 | - // 通过SASS平台验证 | 322 | + // 通过SASS平台验证(密码和MD5) |
| 307 | _sassJoinSuccessHandler(_data) { | 323 | _sassJoinSuccessHandler(_data) { |
| 308 | //返回值 | 324 | //返回值 |
| 309 | /* flag 数值型 无 True:成功 | 325 | /* flag 数值型 无 True:成功 |
| @@ -330,42 +346,55 @@ export default class MessageEntrance extends Emiter { | @@ -330,42 +346,55 @@ export default class MessageEntrance extends Emiter { | ||
| 330 | "maxAudioChannels": 1, | 346 | "maxAudioChannels": 1, |
| 331 | "h5_mcu_list": "123.56.73.119:7001;123.56.69.230:7001;112.126.80.182:7001" | 347 | "h5_mcu_list": "123.56.73.119:7001;123.56.69.230:7001;112.126.80.182:7001" |
| 332 | }*/ | 348 | }*/ |
| 333 | - if (_data.h5_mcu_list) { | ||
| 334 | - //MCU地址默认使用第一个 | ||
| 335 | - let server = _data.h5_mcu_list.split(";")[0]; | ||
| 336 | - GlobalConfig.MCUServerIP = server.split(":")[0]; | ||
| 337 | - GlobalConfig.MCUServerPort = server.split(":")[1]; | ||
| 338 | - } | ||
| 339 | - | ||
| 340 | - //视频推流播流地址 | ||
| 341 | - if (_data.ms) { | ||
| 342 | - //MS地址默认使用第一个 | ||
| 343 | - let server = _data.ms.split(";")[0]; | ||
| 344 | - GlobalConfig.MSServerIP = server.split(":")[0]; | ||
| 345 | - GlobalConfig.MSServerPort = server.split(":")[1]; | ||
| 346 | - } | ||
| 347 | - | ||
| 348 | - //m3u8播流地址 | ||
| 349 | - if(_data.rs){ | ||
| 350 | - //RS地址默认使用第一个 | ||
| 351 | - let server = _data.rs.split(";")[0]; | ||
| 352 | - GlobalConfig.RSServerIP = server.split(":")[0]; | ||
| 353 | - GlobalConfig.RSServerPort = server.split(":")[1]; | ||
| 354 | - } | ||
| 355 | - | ||
| 356 | - GlobalConfig.docServer = _data.doc; | ||
| 357 | - GlobalConfig.h5_mcu_list = _data.h5_mcu_list; | ||
| 358 | - GlobalConfig.h5Module = _data.h5Module; | ||
| 359 | - GlobalConfig.mcu = _data.mcu; | ||
| 360 | - GlobalConfig.ms = _data.ms; | ||
| 361 | - GlobalConfig.record = _data.record; | ||
| 362 | - GlobalConfig.rs = _data.rs; | ||
| 363 | - GlobalConfig.maxVideoChannels = _data.maxVideoChannels; | ||
| 364 | - GlobalConfig.maxAudioChannels = _data.maxAudioChannels; | ||
| 365 | - GlobalConfig.maxMediaChannels = _data.maxVideoChannels + _data.maxAudioChannels; | ||
| 366 | 349 | ||
| 350 | + /* | ||
| 351 | + if (_data.h5_mcu_list) { | ||
| 352 | + //MCU地址默认使用第一个 | ||
| 353 | + let server = _data.h5_mcu_list.split(";")[0]; | ||
| 354 | + GlobalConfig.MCUServerIP = server.split(":")[0]; | ||
| 355 | + GlobalConfig.MCUServerPort = server.split(":")[1]; | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + //视频推流播流地址 | ||
| 359 | + if (_data.ms) { | ||
| 360 | + //MS地址默认使用第一个 | ||
| 361 | + let server = _data.ms.split(";")[0]; | ||
| 362 | + GlobalConfig.MSServerIP = server.split(":")[0]; | ||
| 363 | + GlobalConfig.MSServerPort = server.split(":")[1]; | ||
| 364 | + } | ||
| 365 | + | ||
| 366 | + //m3u8播流地址 | ||
| 367 | + if(_data.rs){ | ||
| 368 | + //RS地址默认使用第一个 | ||
| 369 | + let server = _data.rs.split(";")[0]; | ||
| 370 | + GlobalConfig.RSServerIP = server.split(":")[0]; | ||
| 371 | + GlobalConfig.RSServerPort = server.split(":")[1]; | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + GlobalConfig.docServer = _data.doc; | ||
| 375 | + GlobalConfig.h5_mcu_list = _data.h5_mcu_list; | ||
| 376 | + GlobalConfig.h5Module = _data.h5Module; | ||
| 377 | + GlobalConfig.mcu = _data.mcu; | ||
| 378 | + GlobalConfig.ms = _data.ms; | ||
| 379 | + GlobalConfig.record = _data.record; | ||
| 380 | + GlobalConfig.rs = _data.rs; | ||
| 381 | + GlobalConfig.maxVideoChannels = _data.maxVideoChannels; | ||
| 382 | + GlobalConfig.maxAudioChannels = _data.maxAudioChannels; | ||
| 383 | + | ||
| 384 | + */ | ||
| 385 | + | ||
| 386 | + | ||
| 387 | + /* | ||
| 388 | + //这个接口获取的数据在getClassParam接口的数据中都有,内容重复,这个接口废弃 | ||
| 389 | + //获取会议基本信息 | ||
| 390 | + if (_sass) { | ||
| 391 | + _sass.getClassDetail(); | ||
| 392 | + } | ||
| 393 | + */ | ||
| 394 | + | ||
| 395 | + //获取会议最完整的数据 | ||
| 367 | if (_sass) { | 396 | if (_sass) { |
| 368 | - _sass.getClassDetail();//会议基本信息 | 397 | + _sass.getClassParam(); |
| 369 | } | 398 | } |
| 370 | } | 399 | } |
| 371 | 400 | ||
| @@ -398,7 +427,7 @@ export default class MessageEntrance extends Emiter { | @@ -398,7 +427,7 @@ export default class MessageEntrance extends Emiter { | ||
| 398 | GlobalConfig.classBeginTime = _data.beginTime || ""; | 427 | GlobalConfig.classBeginTime = _data.beginTime || ""; |
| 399 | GlobalConfig.classEndTime = _data.endTime || ""; | 428 | GlobalConfig.classEndTime = _data.endTime || ""; |
| 400 | 429 | ||
| 401 | - //获取会议所有信息和以前保存的会议状态信息 | 430 | + //获取会议所有信息和以前保存的会议状态信息(最全的信息) |
| 402 | if (_sass) { | 431 | if (_sass) { |
| 403 | _sass.getClassParam(); | 432 | _sass.getClassParam(); |
| 404 | } | 433 | } |
| @@ -411,8 +440,15 @@ export default class MessageEntrance extends Emiter { | @@ -411,8 +440,15 @@ export default class MessageEntrance extends Emiter { | ||
| 411 | // console.log(_data); | 440 | // console.log(_data); |
| 412 | //包含整个会议最全的信息,储存数据 | 441 | //包含整个会议最全的信息,储存数据 |
| 413 | if (_data) { | 442 | if (_data) { |
| 443 | + GlobalConfig.className = _data.meetingName || ""; | ||
| 444 | + GlobalConfig.classBeginTime = _data.beginTime || ""; | ||
| 445 | + GlobalConfig.classEndTime = _data.endTime || ""; | ||
| 446 | + | ||
| 447 | + GlobalConfig.maxVideoChannels = _data.maxVideoChannels; | ||
| 448 | + GlobalConfig.maxAudioChannels = _data.maxAudioChannels; | ||
| 449 | + | ||
| 414 | GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表 | 450 | GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表 |
| 415 | - GlobalConfig.setDocRecordList(_data.docRecordList);//录制回放地址?? | 451 | + GlobalConfig.setRecordList(_data.recordList);//录制回放地址 |
| 416 | GlobalConfig.setDocList(_data.docList);//文档地址 | 452 | GlobalConfig.setDocList(_data.docList);//文档地址 |
| 417 | GlobalConfig.setMsList(_data.msList);//推流播流服务器地址 | 453 | GlobalConfig.setMsList(_data.msList);//推流播流服务器地址 |
| 418 | GlobalConfig.setRsList(_data.rsList);//播放m3u8格式的地址 | 454 | GlobalConfig.setRsList(_data.rsList);//播放m3u8格式的地址 |
| @@ -421,22 +457,45 @@ export default class MessageEntrance extends Emiter { | @@ -421,22 +457,45 @@ export default class MessageEntrance extends Emiter { | ||
| 421 | GlobalConfig.setMusicListPrepare(_data.musicListPrepare);//提前上传的声音文件列表 | 457 | GlobalConfig.setMusicListPrepare(_data.musicListPrepare);//提前上传的声音文件列表 |
| 422 | 458 | ||
| 423 | 459 | ||
| 460 | + if (_data.mcuList) { | ||
| 461 | + //MCU地址默认使用第一个 | ||
| 462 | + GlobalConfig.MCUServerIP =_data.mcuList[0].ip||""; | ||
| 463 | + GlobalConfig.MCUServerPort =_data.mcuList[0].port||""; | ||
| 464 | + } | ||
| 465 | + | ||
| 466 | + //视频推流播流地址 | ||
| 467 | + if (_data.msList) { | ||
| 468 | + //MS地址默认使用第一个 | ||
| 469 | + GlobalConfig.MSServerIP =_data.msList[0].ip||""; | ||
| 470 | + GlobalConfig.MSServerPort =_data.msList[0].port||""; | ||
| 471 | + } | ||
| 472 | + | ||
| 473 | + //m3u8播流地址 | ||
| 474 | + if(_data.rsList){ | ||
| 475 | + //RS地址默认使用第一个 | ||
| 476 | + GlobalConfig.RSServerIP =_data.rsList[0].ip||""; | ||
| 477 | + GlobalConfig.RSServerPort =_data.rsList[0].port||""; | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + //文档地址 | ||
| 481 | + if(_data.docList){ | ||
| 482 | + //doc地址默认使用第一个 | ||
| 483 | + GlobalConfig.DOCServerIP =_data.docList[0].ip||""; | ||
| 484 | + GlobalConfig.DOCServerPort =_data.docList[0].port||""; | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + //record | ||
| 488 | + if(_data.recordList){ | ||
| 489 | + //地址默认使用第一个 | ||
| 490 | + GlobalConfig.RecordServerIP =_data.recordList[0].ip||""; | ||
| 491 | + GlobalConfig.RecordServerPort =_data.recordList[0].port||""; | ||
| 492 | + } | ||
| 493 | + | ||
| 424 | } | 494 | } |
| 495 | + | ||
| 425 | if (_data.currentInfo) { | 496 | if (_data.currentInfo) { |
| 426 | //根据从Sass获取的数据信息,同步最后一次保存的会议状态信息 | 497 | //根据从Sass获取的数据信息,同步最后一次保存的会议状态信息 |
| 427 | loger.log("同步最后一次保存过的会议状态信息"); | 498 | loger.log("同步最后一次保存过的会议状态信息"); |
| 428 | - | ||
| 429 | - /*//解析BASE64的数据 | ||
| 430 | - loger.log("11111111111111111111111111111111"); | ||
| 431 | - console.log(GlobalConfig.classStatusInfo); | ||
| 432 | - //已经保存过会议状态信息,读取之前的数据 | ||
| 433 | - let _classStatusInfo=EngineUtils.objectFromBase64(_data.currentInfo); | ||
| 434 | - loger.log("classStatusInfo",_classStatusInfo); | ||
| 435 | - GlobalConfig.classStatusInfo=_classStatusInfo; | ||
| 436 | - loger.log("2222222222222222222222222"); | ||
| 437 | - console.log(GlobalConfig.classStatusInfo);*/ | ||
| 438 | - | ||
| 439 | - //console.log(_data.currentInfo); | ||
| 440 | GlobalConfig.setClassStatusInfo(_data.currentInfo); | 499 | GlobalConfig.setClassStatusInfo(_data.currentInfo); |
| 441 | console.log(GlobalConfig.classStatusInfo) | 500 | console.log(GlobalConfig.classStatusInfo) |
| 442 | } else { | 501 | } else { |
| @@ -450,11 +509,6 @@ export default class MessageEntrance extends Emiter { | @@ -450,11 +509,6 @@ export default class MessageEntrance extends Emiter { | ||
| 450 | //保存会议状态信息 | 509 | //保存会议状态信息 |
| 451 | _sassSaveClassStatusInfo() { | 510 | _sassSaveClassStatusInfo() { |
| 452 | if (GlobalConfig.isHost) { | 511 | if (GlobalConfig.isHost) { |
| 453 | - //用get保存数据,数据内容需要转为BASE64 | ||
| 454 | - //let _classStatusInfo=EngineUtils.objectToBase64(GlobalConfig.classStatusInfo); | ||
| 455 | - //loger.log("保存会议状态信息",_classStatusInfo); | ||
| 456 | - //_sass.saveClassStatusInfo({"classStatusInfo":_classStatusInfo});//保存会议状态信息 | ||
| 457 | - | ||
| 458 | //只有加入会议之后才能保存数据 | 512 | //只有加入会议之后才能保存数据 |
| 459 | if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) { | 513 | if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) { |
| 460 | //POST 保存数据 | 514 | //POST 保存数据 |
| @@ -481,7 +535,7 @@ export default class MessageEntrance extends Emiter { | @@ -481,7 +535,7 @@ export default class MessageEntrance extends Emiter { | ||
| 481 | } | 535 | } |
| 482 | 536 | ||
| 483 | // MCU 会议成功 | 537 | // MCU 会议成功 |
| 484 | - _joinClassSuccessHandler(_data) { | 538 | + _mcuJoinClassSuccessHandler(_data) { |
| 485 | loger.log('MCU 会议成功.'); | 539 | loger.log('MCU 会议成功.'); |
| 486 | GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2); | 540 | GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2); |
| 487 | 541 | ||
| @@ -490,17 +544,15 @@ export default class MessageEntrance extends Emiter { | @@ -490,17 +544,15 @@ export default class MessageEntrance extends Emiter { | ||
| 490 | //返回给客户端初始化成功的数据 | 544 | //返回给客户端初始化成功的数据 |
| 491 | let initSuccessCallBackData = {}; | 545 | let initSuccessCallBackData = {}; |
| 492 | 546 | ||
| 493 | - //GlobalConfig.MCUServerIP=_data.MCUServerIP; | ||
| 494 | - // GlobalConfig.MCUServerPort=_data.MCUServerPort; | 547 | + initSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP; |
| 548 | + initSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort; | ||
| 495 | 549 | ||
| 496 | - initSuccessCallBackData.docServer = GlobalConfig.docServer;//文档服务器地址 | ||
| 497 | initSuccessCallBackData.classId = GlobalConfig.classId; | 550 | initSuccessCallBackData.classId = GlobalConfig.classId; |
| 498 | initSuccessCallBackData.className = GlobalConfig.className; | 551 | initSuccessCallBackData.className = GlobalConfig.className; |
| 499 | initSuccessCallBackData.h5Module = GlobalConfig.h5Module; | 552 | initSuccessCallBackData.h5Module = GlobalConfig.h5Module; |
| 500 | initSuccessCallBackData.isHost = GlobalConfig.isHost; | 553 | initSuccessCallBackData.isHost = GlobalConfig.isHost; |
| 501 | initSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels; | 554 | initSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels; |
| 502 | initSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels; | 555 | initSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels; |
| 503 | - initSuccessCallBackData.maxMediaChannels = GlobalConfig.maxMediaChannels; | ||
| 504 | initSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay; | 556 | initSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay; |
| 505 | 557 | ||
| 506 | initSuccessCallBackData.msType = GlobalConfig.msType; | 558 | initSuccessCallBackData.msType = GlobalConfig.msType; |
| @@ -526,79 +578,6 @@ export default class MessageEntrance extends Emiter { | @@ -526,79 +578,6 @@ export default class MessageEntrance extends Emiter { | ||
| 526 | loger.log('加入会议成功', initSuccessCallBackData); | 578 | loger.log('加入会议成功', initSuccessCallBackData); |
| 527 | _joinClassSuccessCallBackFun(initSuccessCallBackData); | 579 | _joinClassSuccessCallBackFun(initSuccessCallBackData); |
| 528 | } | 580 | } |
| 529 | - | ||
| 530 | - | ||
| 531 | - //loger.log('MCU 会议成功.'); | ||
| 532 | - //GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2); | ||
| 533 | - //if(_sass){ | ||
| 534 | - // _sass.getClassDetail();//会议信息 | ||
| 535 | - // _sass.getClassParam();//会议参数大全 | ||
| 536 | - //} | ||
| 537 | - // | ||
| 538 | - ////储存数据 | ||
| 539 | - //GlobalConfig.MCUServerIP=_data.MCUServerIP; | ||
| 540 | - //GlobalConfig.MCUServerPort=_data.MCUServerPort; | ||
| 541 | - //GlobalConfig.classId=_data.classId; | ||
| 542 | - //GlobalConfig.h5Module=_data.h5Module; | ||
| 543 | - //GlobalConfig.maxAudioChannels=_data.maxAudioChannels; | ||
| 544 | - //GlobalConfig.maxVideoChannels=_data.maxVideoChannels; | ||
| 545 | - //GlobalConfig.maxMediaChannels=_data.maxMediaChannels; | ||
| 546 | - //GlobalConfig.mcuClassInfo=_data.mcuClassInfo; | ||
| 547 | - //GlobalConfig.mcuDelay=_data.mcuDelay; | ||
| 548 | - //GlobalConfig.md5=_data.md5; | ||
| 549 | - //GlobalConfig.msType=_data.msType; | ||
| 550 | - //GlobalConfig.nodeId=_data.nodeId; | ||
| 551 | - //GlobalConfig.password=_data.password; | ||
| 552 | - //GlobalConfig.portal=_data.portal; | ||
| 553 | - //GlobalConfig.role=_data.role; | ||
| 554 | - //GlobalConfig.siteId=_data.siteId; | ||
| 555 | - //GlobalConfig.topNodeID=_data.topNodeID; | ||
| 556 | - //GlobalConfig.userId=_data.userId; | ||
| 557 | - //GlobalConfig.userName=_data.userName; | ||
| 558 | - //GlobalConfig.userRole=_data.userRole; | ||
| 559 | - //GlobalConfig.userType=_data.userType; | ||
| 560 | - // | ||
| 561 | - ////返回给客户数据 | ||
| 562 | - //if(_joinClassSuccessCallBackFun){ | ||
| 563 | - // //返回给客户端初始化成功的数据 | ||
| 564 | - // let initSuccessCallBackData={}; | ||
| 565 | - // | ||
| 566 | - // //GlobalConfig.MCUServerIP=_data.MCUServerIP; | ||
| 567 | - // // GlobalConfig.MCUServerPort=_data.MCUServerPort; | ||
| 568 | - // | ||
| 569 | - // initSuccessCallBackData.docServer=GlobalConfig.docServer;//文档服务器地址 | ||
| 570 | - // initSuccessCallBackData.classId=GlobalConfig.classId; | ||
| 571 | - // initSuccessCallBackData.className=GlobalConfig.className; | ||
| 572 | - // initSuccessCallBackData.h5Module=GlobalConfig.h5Module; | ||
| 573 | - // initSuccessCallBackData.isHost=GlobalConfig.isHost; | ||
| 574 | - // initSuccessCallBackData.maxAudioChannels=GlobalConfig.maxAudioChannels; | ||
| 575 | - // initSuccessCallBackData.maxVideoChannels=GlobalConfig.maxVideoChannels; | ||
| 576 | - // initSuccessCallBackData.maxMediaChannels=GlobalConfig.maxMediaChannels; | ||
| 577 | - // initSuccessCallBackData.mcuDelay=GlobalConfig.mcuDelay; | ||
| 578 | - // | ||
| 579 | - // initSuccessCallBackData.msType=GlobalConfig.msType; | ||
| 580 | - // initSuccessCallBackData.nodeId=GlobalConfig.nodeId; | ||
| 581 | - // initSuccessCallBackData.password=GlobalConfig.password; | ||
| 582 | - // initSuccessCallBackData.passwordRequired=GlobalConfig.passwordRequired;// 老师的默认是true | ||
| 583 | - // //GlobalConfig.passwordRequired 老师的默认是true | ||
| 584 | - // //GlobalConfig.portal=_data.portal; | ||
| 585 | - // initSuccessCallBackData.role=GlobalConfig.role; | ||
| 586 | - // initSuccessCallBackData.siteId=GlobalConfig.siteId; | ||
| 587 | - // initSuccessCallBackData.topNodeID=GlobalConfig.topNodeID; | ||
| 588 | - // initSuccessCallBackData.userId=GlobalConfig.userId; | ||
| 589 | - // initSuccessCallBackData.userName=GlobalConfig.userName; | ||
| 590 | - // initSuccessCallBackData.userRole=GlobalConfig.userRole; | ||
| 591 | - // initSuccessCallBackData.userType=GlobalConfig.userType; | ||
| 592 | - // | ||
| 593 | - // initSuccessCallBackData.siteId=GlobalConfig.siteId; | ||
| 594 | - // initSuccessCallBackData.classId=GlobalConfig.classId; | ||
| 595 | - // initSuccessCallBackData.userRole=GlobalConfig.userRole; | ||
| 596 | - // initSuccessCallBackData.userId=GlobalConfig.userId; | ||
| 597 | - // initSuccessCallBackData.passwordRequired=GlobalConfig.passwordRequired; | ||
| 598 | - // initSuccessCallBackData.classType=GlobalConfig.classType||ApeConsts.CLASS_TYPE_INTERACT; | ||
| 599 | - // loger.log('加入会议成功',initSuccessCallBackData); | ||
| 600 | - // _joinClassSuccessCallBackFun(initSuccessCallBackData); | ||
| 601 | - //} | ||
| 602 | } | 581 | } |
| 603 | 582 | ||
| 604 | //Sass删除文档数据 | 583 | //Sass删除文档数据 |
| @@ -653,6 +632,9 @@ export default class MessageEntrance extends Emiter { | @@ -653,6 +632,9 @@ export default class MessageEntrance extends Emiter { | ||
| 653 | if(_video_ape){ | 632 | if(_video_ape){ |
| 654 | _video_ape.stopPublishVideo(); | 633 | _video_ape.stopPublishVideo(); |
| 655 | } | 634 | } |
| 635 | + if(_audio_ape){ | ||
| 636 | + _audio_ape.stopPublishAudio(); | ||
| 637 | + } | ||
| 656 | //离开会议 | 638 | //离开会议 |
| 657 | if(_confer_ape){ | 639 | if(_confer_ape){ |
| 658 | _confer_ape.leaveClass(); | 640 | _confer_ape.leaveClass(); |
| @@ -714,6 +696,45 @@ export default class MessageEntrance extends Emiter { | @@ -714,6 +696,45 @@ export default class MessageEntrance extends Emiter { | ||
| 714 | } | 696 | } |
| 715 | } | 697 | } |
| 716 | 698 | ||
| 699 | + //AudioApe | ||
| 700 | + audioUpdate(_data){ | ||
| 701 | + //音频同步的消息发送改变,需要通知ferApe模块中的用户更新状态 | ||
| 702 | + if(_confer_ape){ | ||
| 703 | + _confer_ape.updaterRosterStatus(_data); | ||
| 704 | + } | ||
| 705 | + } | ||
| 706 | + | ||
| 707 | + sendAudioCommandMsg(_param){ | ||
| 708 | + if(_audio_ape){ | ||
| 709 | + return _audio_ape.sendAudioBroadcastMsg(_param); | ||
| 710 | + } | ||
| 711 | + } | ||
| 712 | + | ||
| 713 | + _getPlayAudioPath(_param){ | ||
| 714 | + if(_audio_ape){ | ||
| 715 | + return _audio_ape.getAudioPlayPath(_param); | ||
| 716 | + } | ||
| 717 | + } | ||
| 718 | + | ||
| 719 | + _getPublishAudioPath(_param){ | ||
| 720 | + if(_audio_ape){ | ||
| 721 | + return _audio_ape.getAudioPublishPath(_param); | ||
| 722 | + } | ||
| 723 | + } | ||
| 724 | + | ||
| 725 | + _publishAudio(_param){ | ||
| 726 | + if(_audio_ape){ | ||
| 727 | + return _audio_ape.publishAudio(_param); | ||
| 728 | + } | ||
| 729 | + } | ||
| 730 | + | ||
| 731 | + _stopPublishAudio(_param){ | ||
| 732 | + if(_audio_ape){ | ||
| 733 | + return _audio_ape.stopPublishAudio(_param); | ||
| 734 | + } | ||
| 735 | + } | ||
| 736 | + | ||
| 737 | + | ||
| 717 | //WhiteBoardApe | 738 | //WhiteBoardApe |
| 718 | // 添加标注,发送信息 | 739 | // 添加标注,发送信息 |
| 719 | _sendInsertAnnotaion(_param){ | 740 | _sendInsertAnnotaion(_param){ |
| @@ -820,30 +841,32 @@ export default class MessageEntrance extends Emiter { | @@ -820,30 +841,32 @@ export default class MessageEntrance extends Emiter { | ||
| 820 | if(GlobalConfig.isHost){ | 841 | if(GlobalConfig.isHost){ |
| 821 | for (let value of GlobalConfig.docListPrepare){ | 842 | for (let value of GlobalConfig.docListPrepare){ |
| 822 | if(value){ | 843 | if(value){ |
| 823 | - //{ | ||
| 824 | - // "MD5": "f3feb3fac8cd3a953bded00e07a0c66b", | ||
| 825 | - // "absoluteLocation": "http://101.200.150.192/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf", | ||
| 826 | - // "createUserID": "972", | ||
| 827 | - // "createUserIP": "114.241.81.175", | ||
| 828 | - // "createUserName": "base", | ||
| 829 | - // "dynamicPPT": 0, | ||
| 830 | - // "dynamicTransferStatic": "", | ||
| 831 | - // "id": "8ab3b0ed5a00f2fa015a0219a3df016c", | ||
| 832 | - // "meetingNumber": "", | ||
| 833 | - // "name": "McuClient_v.1.0.1_API.pdf", | ||
| 834 | - // "orderStr": "", | ||
| 835 | - // "pdfSize": 5, | ||
| 836 | - // "processEndTime": "2017-02-03 11:54:31", | ||
| 837 | - // "processRate": 0, | ||
| 838 | - // "processStartTime": "2017-02-03 11:54:27", | ||
| 839 | - // "relativeLocation": "/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf", | ||
| 840 | - // "siteID": "h5test", | ||
| 841 | - // "size": 360920, | ||
| 842 | - // "status": 3, | ||
| 843 | - // "type": "pdf", | ||
| 844 | - // "uploadEndTime": "2017-02-03 11:54:27", | ||
| 845 | - // "uploadStartTime": "2017-02-03 11:54:27" | ||
| 846 | - //} | 844 | + /* //提前上传的文档文档信息的结构 |
| 845 | + { | ||
| 846 | + "MD5": "f3feb3fac8cd3a953bded00e07a0c66b", | ||
| 847 | + "absoluteLocation": "http://101.200.150.192/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf", | ||
| 848 | + "createUserID": "972", | ||
| 849 | + "createUserIP": "114.241.81.175", | ||
| 850 | + "createUserName": "base", | ||
| 851 | + "dynamicPPT": 0, | ||
| 852 | + "dynamicTransferStatic": "", | ||
| 853 | + "id": "8ab3b0ed5a00f2fa015a0219a3df016c", | ||
| 854 | + "meetingNumber": "", | ||
| 855 | + "name": "McuClient_v.1.0.1_API.pdf", | ||
| 856 | + "orderStr": "", | ||
| 857 | + "pdfSize": 5, | ||
| 858 | + "processEndTime": "2017-02-03 11:54:31", | ||
| 859 | + "processRate": 0, | ||
| 860 | + "processStartTime": "2017-02-03 11:54:27", | ||
| 861 | + "relativeLocation": "/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf", | ||
| 862 | + "siteID": "h5test", | ||
| 863 | + "size": 360920, | ||
| 864 | + "status": 3, | ||
| 865 | + "type": "pdf", | ||
| 866 | + "uploadEndTime": "2017-02-03 11:54:27", | ||
| 867 | + "uploadStartTime": "2017-02-03 11:54:27" | ||
| 868 | + }*/ | ||
| 869 | + | ||
| 847 | loger.log("判断是否需要把提前上传的文档上传到mcu",value); | 870 | loger.log("判断是否需要把提前上传的文档上传到mcu",value); |
| 848 | let paramInfo={ | 871 | let paramInfo={ |
| 849 | "pageNum": value.pdfSize, | 872 | "pageNum": value.pdfSize, |
| @@ -30,7 +30,9 @@ class GlobalConfig { | @@ -30,7 +30,9 @@ class GlobalConfig { | ||
| 30 | static getClassDetail(){ | 30 | static getClassDetail(){ |
| 31 | return this.classDetail; | 31 | return this.classDetail; |
| 32 | } | 32 | } |
| 33 | - | 33 | + static setClassDetail(_data){ |
| 34 | + this.classDetail=_data; | ||
| 35 | + } | ||
| 34 | static getClassInfo (){ | 36 | static getClassInfo (){ |
| 35 | let classInfo={}; | 37 | let classInfo={}; |
| 36 | classInfo.siteId= this.siteId; | 38 | classInfo.siteId= this.siteId; |
| @@ -55,7 +57,6 @@ class GlobalConfig { | @@ -55,7 +57,6 @@ class GlobalConfig { | ||
| 55 | classInfo.MCUServerPort=this.MCUServerPort; | 57 | classInfo.MCUServerPort=this.MCUServerPort; |
| 56 | classInfo.maxVideoChannels= this.maxVideoChannels; | 58 | classInfo.maxVideoChannels= this.maxVideoChannels; |
| 57 | classInfo.maxAudioChannels=this.maxAudioChannels; | 59 | classInfo.maxAudioChannels=this.maxAudioChannels; |
| 58 | - classInfo.maxMediaChannels= this.maxMediaChannels; | ||
| 59 | 60 | ||
| 60 | return classInfo; | 61 | return classInfo; |
| 61 | 62 | ||
| @@ -175,13 +176,13 @@ class GlobalConfig { | @@ -175,13 +176,13 @@ class GlobalConfig { | ||
| 175 | static getDocListPrepare(){ | 176 | static getDocListPrepare(){ |
| 176 | return this.docListPrepare; | 177 | return this.docListPrepare; |
| 177 | } | 178 | } |
| 178 | - //储存文档录制列表 | ||
| 179 | - static setDocRecordList(_data){ | 179 | + //储存录制列表 |
| 180 | + static setRecordList(_data){ | ||
| 180 | if(_data==null) return; | 181 | if(_data==null) return; |
| 181 | - this.docRecordList=_data; | 182 | + this.recordList=_data; |
| 182 | } | 183 | } |
| 183 | - static getDocRecordList(){ | ||
| 184 | - return this.docRecordList; | 184 | + static getRecordList(){ |
| 185 | + return this.recordList; | ||
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | //文档服务器列表 | 188 | //文档服务器列表 |
| @@ -247,11 +248,12 @@ GlobalConfig.md5=""; | @@ -247,11 +248,12 @@ GlobalConfig.md5=""; | ||
| 247 | GlobalConfig.msType=1;//目前固定用这个 | 248 | GlobalConfig.msType=1;//目前固定用这个 |
| 248 | GlobalConfig.mcuDelay=3000;//默认的延迟时间 | 249 | GlobalConfig.mcuDelay=3000;//默认的延迟时间 |
| 249 | GlobalConfig.docDelay=1600;//文档模块加入成功之后延迟发送送成功的消息给主模块 | 250 | GlobalConfig.docDelay=1600;//文档模块加入成功之后延迟发送送成功的消息给主模块 |
| 250 | -GlobalConfig.portal="112.126.80.182:80"; | ||
| 251 | -GlobalConfig.ip="112.126.80.182"; | ||
| 252 | -GlobalConfig.port="80"; | 251 | +GlobalConfig.portal="112.126.80.182:80";//Sass IP |
| 252 | + | ||
| 253 | +//GlobalConfig.ip="112.126.80.182"; | ||
| 254 | +//GlobalConfig.port="80"; | ||
| 255 | + | ||
| 253 | GlobalConfig.MCUServerIP="114.215.195.70"; | 256 | GlobalConfig.MCUServerIP="114.215.195.70"; |
| 254 | -GlobalConfig.docServer="";//当前的文档地址加载的服务器地址 | ||
| 255 | GlobalConfig.MCUServerPort=9003; | 257 | GlobalConfig.MCUServerPort=9003; |
| 256 | 258 | ||
| 257 | GlobalConfig.MSServerIP = "";//推流 播流的地址 | 259 | GlobalConfig.MSServerIP = "";//推流 播流的地址 |
| @@ -261,9 +263,16 @@ GlobalConfig.MSServerPort =""; | @@ -261,9 +263,16 @@ GlobalConfig.MSServerPort =""; | ||
| 261 | GlobalConfig.RSServerIP =""; | 263 | GlobalConfig.RSServerIP =""; |
| 262 | GlobalConfig.RSServerPort =""; | 264 | GlobalConfig.RSServerPort =""; |
| 263 | 265 | ||
| 266 | +//DOC | ||
| 267 | +GlobalConfig.DOCServerIP =""; | ||
| 268 | +GlobalConfig.DOCServerPort =""; | ||
| 269 | + | ||
| 270 | +GlobalConfig.RecordServerIP =""; | ||
| 271 | +GlobalConfig.RecordServerPort =""; | ||
| 272 | + | ||
| 264 | GlobalConfig.maxVideoChannels=0; | 273 | GlobalConfig.maxVideoChannels=0; |
| 265 | GlobalConfig.maxAudioChannels=0; | 274 | GlobalConfig.maxAudioChannels=0; |
| 266 | -GlobalConfig.maxMediaChannels=0; | 275 | + |
| 267 | GlobalConfig.isDebug=false; | 276 | GlobalConfig.isDebug=false; |
| 268 | GlobalConfig.deBugData={}; | 277 | GlobalConfig.deBugData={}; |
| 269 | 278 | ||
| @@ -315,7 +324,7 @@ GlobalConfig.classAllParam={};//Sass直接返回的所有会议信息(最全) | @@ -315,7 +324,7 @@ GlobalConfig.classAllParam={};//Sass直接返回的所有会议信息(最全) | ||
| 315 | GlobalConfig.classDetail={};//Sass直接返回的当前课堂基本信息 | 324 | GlobalConfig.classDetail={};//Sass直接返回的当前课堂基本信息 |
| 316 | 325 | ||
| 317 | GlobalConfig.docListPrepare=[]; // 已经提前上传的文档,进入课堂后需要自动加载 | 326 | GlobalConfig.docListPrepare=[]; // 已经提前上传的文档,进入课堂后需要自动加载 |
| 318 | -GlobalConfig.docRecordList=[];//录制服务器地址集合 | 327 | +GlobalConfig.recordList=[];//录制服务器地址集合 |
| 319 | GlobalConfig.docList=[];//文档服务器地址集合 | 328 | GlobalConfig.docList=[];//文档服务器地址集合 |
| 320 | GlobalConfig.mcuList=[];//录制服务器地址集合 | 329 | GlobalConfig.mcuList=[];//录制服务器地址集合 |
| 321 | GlobalConfig.msList=[];//ms服务器地址集合 | 330 | GlobalConfig.msList=[];//ms服务器地址集合 |
| @@ -323,21 +332,5 @@ GlobalConfig.musicList=[];//music服务器地址集合 | @@ -323,21 +332,5 @@ GlobalConfig.musicList=[];//music服务器地址集合 | ||
| 323 | GlobalConfig.musicListPrepare=[];//提提前上传的music集合 | 332 | GlobalConfig.musicListPrepare=[];//提提前上传的music集合 |
| 324 | GlobalConfig.rsList=[]; | 333 | GlobalConfig.rsList=[]; |
| 325 | 334 | ||
| 326 | -// client type | ||
| 327 | -//点对点会议版本 | ||
| 328 | - GlobalConfig.CT_P2PMEETING = 0; | ||
| 329 | -/** | ||
| 330 | - * 直播教育版本和大型直播版本 | ||
| 331 | - */ | ||
| 332 | -GlobalConfig.CT_LIVEEDUCATION = 1; | ||
| 333 | -/** | ||
| 334 | - * 录制播放器 | ||
| 335 | - */ | ||
| 336 | -GlobalConfig.CT_RECORDPLAYER = 2; | ||
| 337 | -/** | ||
| 338 | - * 实时流版本 | ||
| 339 | - */ | ||
| 340 | -GlobalConfig. CT_LIVESTREAMING = 3; | ||
| 341 | -GlobalConfig.clientType =0; | ||
| 342 | 335 | ||
| 343 | export default GlobalConfig; | 336 | export default GlobalConfig; |
| 1 | +//对外暴露的对象 | ||
| 2 | + | ||
| 3 | + | ||
| 1 | import EngineEntrance from 'EngineEntrance'; | 4 | import EngineEntrance from 'EngineEntrance'; |
| 2 | import MessageTypes from 'MessageTypes'; | 5 | import MessageTypes from 'MessageTypes'; |
| 3 | 6 | ||
| 4 | -const MCU_CLIENT=new EngineEntrance(); | 7 | +const MCU_CLIENT=new EngineEntrance();//入口文件 |
| 5 | 8 | ||
| 6 | export function createMcuClient() { | 9 | export function createMcuClient() { |
| 7 | return MCU_CLIENT; | 10 | return MCU_CLIENT; |
| 8 | } | 11 | } |
| 9 | 12 | ||
| 13 | +//监听是事件名和异常定义 | ||
| 10 | export {MessageTypes}; | 14 | export {MessageTypes}; |
| @@ -29,7 +29,12 @@ MessageTypes.CHAT_RECEIVE = 'chat.receive'; | @@ -29,7 +29,12 @@ MessageTypes.CHAT_RECEIVE = 'chat.receive'; | ||
| 29 | 29 | ||
| 30 | //视频模块事件定义 | 30 | //视频模块事件定义 |
| 31 | MessageTypes.VIDEO_UPDATE = 'video.update'; | 31 | MessageTypes.VIDEO_UPDATE = 'video.update'; |
| 32 | -MessageTypes.VIDEO_COMMAND= 'video.command'; | 32 | +MessageTypes.VIDEO_BROADCAST= 'video.broadcast'; |
| 33 | + | ||
| 34 | +//音频模块事件定义 | ||
| 35 | +MessageTypes.AUDIO_UPDATE = 'audio.update'; | ||
| 36 | +MessageTypes.AUDIO_BROADCAST= 'audio.broadcast'; | ||
| 37 | + | ||
| 33 | 38 | ||
| 34 | //文档模块事件定义 | 39 | //文档模块事件定义 |
| 35 | MessageTypes.DOC_DELETE='document.delete';//删除文档 | 40 | MessageTypes.DOC_DELETE='document.delete';//删除文档 |
| @@ -82,10 +82,13 @@ ApeConsts.USER_MIC_OPEN = 0x0040; // 麦克风开启 | @@ -82,10 +82,13 @@ ApeConsts.USER_MIC_OPEN = 0x0040; // 麦克风开启 | ||
| 82 | ApeConsts.USER_CAMERA_OPEN = 0x0080; // 视频开启 | 82 | ApeConsts.USER_CAMERA_OPEN = 0x0080; // 视频开启 |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | + | ||
| 85 | //VIDEO MIC 流媒体消息操作控制类型 | 86 | //VIDEO MIC 流媒体消息操作控制类型 |
| 86 | ApeConsts.MEDIA_ACTION_DEFAULT=0; | 87 | ApeConsts.MEDIA_ACTION_DEFAULT=0; |
| 88 | + | ||
| 87 | ApeConsts.MEDIA_ACTION_OPEN_CAMERA=1;// "open.camera"; | 89 | ApeConsts.MEDIA_ACTION_OPEN_CAMERA=1;// "open.camera"; |
| 88 | ApeConsts.MEDIA_ACTION_CLOSE_CAMERA=2;// "close.camera"; | 90 | ApeConsts.MEDIA_ACTION_CLOSE_CAMERA=2;// "close.camera"; |
| 91 | + | ||
| 89 | ApeConsts.MEDIA_ACTION_OPEN_MIC= 3;//"open.mic"; | 92 | ApeConsts.MEDIA_ACTION_OPEN_MIC= 3;//"open.mic"; |
| 90 | ApeConsts.MEDIA_ACTION_CLOSE_MIC= 4;//"close.mic"; | 93 | ApeConsts.MEDIA_ACTION_CLOSE_MIC= 4;//"close.mic"; |
| 91 | 94 | ||
| @@ -99,12 +102,16 @@ ApeConsts.MEDIA_TYPE_DEFAULT=0;//没有类型 | @@ -99,12 +102,16 @@ ApeConsts.MEDIA_TYPE_DEFAULT=0;//没有类型 | ||
| 99 | ApeConsts.MEDIA_TYPE_VIDEO=1;//视频流(包含音频) | 102 | ApeConsts.MEDIA_TYPE_VIDEO=1;//视频流(包含音频) |
| 100 | ApeConsts.MEDIA_TYPE_AUDIO=2;//音频流 | 103 | ApeConsts.MEDIA_TYPE_AUDIO=2;//音频流 |
| 101 | 104 | ||
| 102 | -//FLASH中使用下面4个 | ||
| 103 | -ApeConsts.CGS_RELEASED = 0;///< 无人占用状态 | ||
| 104 | -ApeConsts.CGS_PENDING = 1;///< 占用成功,等待打开 | ||
| 105 | -ApeConsts.CGS_OPENNED = 2;///< 打开成功 | ||
| 106 | -ApeConsts.CGS_GRABBING = 3; ///< 准备占用中, 属于本地状态机需要用的状态,在多点数据库中不存在。 | 105 | +//return返回值状态 |
| 106 | +ApeConsts.RETURN_SUCCESS=0;//成功 | ||
| 107 | +ApeConsts.RETURN_FAILED=1;//失败 | ||
| 107 | 108 | ||
| 109 | +////FLASH中使用下面4个 | ||
| 110 | +//ApeConsts.CGS_RELEASED = 0;///< 无人占用状态 | ||
| 111 | +//ApeConsts.CGS_PENDING = 1;///< 占用成功,等待打开 | ||
| 112 | +//ApeConsts.CGS_OPENNED = 2;///< 打开成功 | ||
| 113 | +//ApeConsts.CGS_GRABBING = 3; ///< 准备占用中, 属于本地状态机需要用的状态,在多点数据库中不存在。 | ||
| 114 | +// | ||
| 108 | 115 | ||
| 109 | 116 | ||
| 110 | ApeConsts.INVALIDATE_CHANNEL_ID = -1; | 117 | ApeConsts.INVALIDATE_CHANNEL_ID = -1; |
src/apes/AudioApe.js
0 → 100644
| 1 | +// ////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +//音频模块 | ||
| 3 | +// ////////////////////////////////////////////////////////////////////////////// | ||
| 4 | + | ||
| 5 | +import Ape from './Ape'; | ||
| 6 | +import ApeConsts from './ApeConsts'; | ||
| 7 | +import pdu from 'pdus'; | ||
| 8 | +import Loger from 'Loger'; | ||
| 9 | +import MessageTypes from 'MessageTypes'; | ||
| 10 | +import GlobalConfig from 'GlobalConfig'; | ||
| 11 | +import EngineUtils from 'EngineUtils'; | ||
| 12 | +import MediaModule from "./MediaModule"; | ||
| 13 | + | ||
| 14 | +let loger = Loger.getLoger('AudioApe'); | ||
| 15 | + | ||
| 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.mediaModule=new MediaModule(); | ||
| 25 | + this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.AUDIO_OBJ_TABLE_ID; | ||
| 26 | + this.mediaModule.mediaChannels={}; | ||
| 27 | + // Ape Models | ||
| 28 | + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); | ||
| 29 | + 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); | ||
| 30 | + | ||
| 31 | + // 广播消息,用户之间的消息传递 | ||
| 32 | + this.on(pdu.RCPDU_AUDIO_SEND_DATA_REQUEST, this.receiveAudiooCommandHandler.bind(this)); | ||
| 33 | + } | ||
| 34 | + //ape加入成功 | ||
| 35 | + onJoinChannelHandlerSuccess(){ | ||
| 36 | + //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据 | ||
| 37 | + this.mediaModule.maxMediaChannel=GlobalConfig.maxAudioChannels; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /////////////发送数据操作//////////////////////////////////////////// | ||
| 41 | + //获取播流地址 | ||
| 42 | + getAudioPlayPath(_param) { | ||
| 43 | + loger.log('getAudioPlayPath'); | ||
| 44 | + return this.mediaModule.getMediaPlayPath(_param); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + //获取推流地址 | ||
| 48 | + getAudioPublishPath(_param) { | ||
| 49 | + loger.log('getAudioPublishPath'); | ||
| 50 | + return this.mediaModule.getMediaPublishPath(_param); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + //推流 | ||
| 54 | + publishAudio(_param) { | ||
| 55 | + if (_param == null||_param.channelId == null|| | ||
| 56 | + _param.classId == null||_param.userId == null|| | ||
| 57 | + _param.siteId == null|| _param.timestamp==null) | ||
| 58 | + { | ||
| 59 | + loger.warn('publishAudio,参数错误', _param); | ||
| 60 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 61 | + return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"}; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + //同一个nodeId只允许推一个流,如果已经推了就不能再推 | ||
| 65 | + if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){ | ||
| 66 | + loger.warn("publishAudio,已经存在一个流,不能再推"); | ||
| 67 | + return {"code": ApeConsts.RETURN_FAILED, "data": "已经存在一个流,不能再推"}; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + //判断当前是否还有空闲的channle | ||
| 71 | + let freeChannel = this.mediaModule.getFreeMediaChannel(); | ||
| 72 | + if (freeChannel == 0) { | ||
| 73 | + loger.warn("publishAudio,没有空闲的channel "); | ||
| 74 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + //判断当前的频道是否已经占用 | ||
| 78 | + if(this.mediaModule.checkChannelIsOpening(_param.channelId)){ | ||
| 79 | + loger.warn(_param.channelId,"频道已经被占用"); | ||
| 80 | + return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"}; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + let channelInfo={}; | ||
| 84 | + channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING; | ||
| 85 | + channelInfo.fromNodeId=GlobalConfig.nodeId; | ||
| 86 | + channelInfo.channelId=_param.channelId;//freeChannel | ||
| 87 | + channelInfo.timestamp=_param.timestamp;//EngineUtils.creatTimestamp(); | ||
| 88 | + channelInfo.classId=_param.classId;//GlobalConfig.classId; | ||
| 89 | + channelInfo.siteId=_param.siteId;//GlobalConfig.siteId; | ||
| 90 | + channelInfo.toNodeId=0; | ||
| 91 | + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO; | ||
| 92 | + this.sendTableUpdateHandler(channelInfo); | ||
| 93 | + return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + //停止推流, | ||
| 97 | + stopPublishAudio(_param) { | ||
| 98 | + loger.log('stopPublishAudio'); | ||
| 99 | + //_param如果为空,那么默认就是当前自己的nodeId,否则用_param | ||
| 100 | + let nodeId; | ||
| 101 | + if(_param&&parseInt(_param.nodeId)>=0){ | ||
| 102 | + nodeId=parseInt(_param.nodeId); | ||
| 103 | + }else { | ||
| 104 | + nodeId=GlobalConfig.nodeId; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); | ||
| 108 | + if (openingChannel == 0) { | ||
| 109 | + loger.warn(nodeId,"stopPublishAudio,没有占用channel,不需要关闭"); | ||
| 110 | + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"}; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + let channelInfo={}; | ||
| 114 | + channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED; | ||
| 115 | + channelInfo.fromNodeId=0; | ||
| 116 | + channelInfo.channelId=openingChannel; | ||
| 117 | + channelInfo.timestamp=0; | ||
| 118 | + channelInfo.classId=GlobalConfig.classId; | ||
| 119 | + channelInfo.toNodeId=0; | ||
| 120 | + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT; | ||
| 121 | + this.sendTableUpdateHandler(channelInfo); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + sendAudioBroadcastMsg(_param) { | ||
| 125 | + if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) { | ||
| 126 | + loger.log('sendAudioBroadcastMsg.McuClient还未初始化数据!'); | ||
| 127 | + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) { | ||
| 128 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); | ||
| 129 | + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"}; | ||
| 130 | + } | ||
| 131 | + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg.McuClient还未初始化数据"}; | ||
| 132 | + } | ||
| 133 | + if (_param == null) { | ||
| 134 | + loger.warn('sendAudioBroadcastMsg,参数错误', _param); | ||
| 135 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 136 | + return {"code": ApeConsts.RETURN_FAILED, "data": "sendAudioBroadcastMsg,参数错误"}; | ||
| 137 | + } | ||
| 138 | + // to, message | ||
| 139 | + loger.log('发送Audio消息.', _param); | ||
| 140 | + | ||
| 141 | + if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) { | ||
| 142 | + //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 | ||
| 143 | + let freeChannel = this.mediaModule.getFreeMediaChannel(); | ||
| 144 | + if (freeChannel == 0) { | ||
| 145 | + loger.warn('sendAudioBroadcastMsg,不能再打开更多的设备', _param); | ||
| 146 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + | ||
| 151 | + let audioSendPdu = new pdu['RCAudioSendDataRequestPdu']; | ||
| 152 | + audioSendPdu.type = pdu.RCPDU_AUDIO_SEND_DATA_REQUEST; | ||
| 153 | + audioSendPdu.isPublic = true; | ||
| 154 | + | ||
| 155 | + audioSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人 | ||
| 156 | + audioSendPdu.toNodeId = parseInt(_param.toNodeID) || 0;//接收者,0就是所有人 | ||
| 157 | + audioSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT; | ||
| 158 | + | ||
| 159 | + audioSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码 | ||
| 160 | + | ||
| 161 | + if (!audioSendPdu.isPublic && 0 != audioSendPdu.toNodeId) { | ||
| 162 | + //发送给制定的人 | ||
| 163 | + loger.log('发送私聊消息.'); | ||
| 164 | + this.send(audioSendPdu); | ||
| 165 | + } else { | ||
| 166 | + //发送给所有人 | ||
| 167 | + loger.log('发送公聊消息.'); | ||
| 168 | + this.sendChatUniform(audioSendPdu); | ||
| 169 | + } | ||
| 170 | + return {"code": ApeConsts.RETURN_SUCCESS, "data": ""}; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + sendTableUpdateHandler(_channelInfo) { | ||
| 174 | + loger.log("audio,sendTableUpdateHandler "); | ||
| 175 | + let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId); | ||
| 176 | + if(updateModelPdu==null){ | ||
| 177 | + loger.warn("sendTableUpdateHandler error,updateModelPdu=null"); | ||
| 178 | + return; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + let tableItemPdu = new pdu['RCRegistryTableItemPdu']; | ||
| 182 | + tableItemPdu.itemIdx = _channelInfo.channelId; | ||
| 183 | + tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定 | ||
| 184 | + tableItemPdu.itemData = updateModelPdu.toArrayBuffer(); | ||
| 185 | + | ||
| 186 | + //insert | ||
| 187 | + let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu']; | ||
| 188 | + //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU]; | ||
| 189 | + //repeated RCRegistryTableItemPdu items = 2; | ||
| 190 | + tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;// | ||
| 191 | + tableInsertItemPdu.items.push(tableItemPdu); | ||
| 192 | + | ||
| 193 | + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu']; | ||
| 194 | + updateObjPdu.objId = ApeConsts.AUDIO_OBJ_TABLE_ID;// | ||
| 195 | + updateObjPdu.subType = tableInsertItemPdu.type; | ||
| 196 | + updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer(); | ||
| 197 | + | ||
| 198 | + //同步 | ||
| 199 | + let adapterItemPdu = new pdu['RCAdapterItemPdu']; | ||
| 200 | + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ; | ||
| 201 | + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); | ||
| 202 | + | ||
| 203 | + let adapterPdu = new pdu['RCAdapterPdu']; | ||
| 204 | + adapterPdu.type = pdu.RCPDU_REG_ADAPTER; | ||
| 205 | + adapterPdu.item.push(adapterItemPdu); | ||
| 206 | + | ||
| 207 | + loger.log("发送更新AUDIO.itemIdx=" + tableItemPdu.itemIdx); | ||
| 208 | + this.sendUniform(adapterPdu, true); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + /////收到消息处理////////////////////////////////////////////////// | ||
| 212 | + | ||
| 213 | + // 消息处理,内部处理,不需要告诉应用层 | ||
| 214 | + receiveAudiooCommandHandler(_data) { | ||
| 215 | + let audioReceivePdu = pdu['RCAudioSendDataRequestPdu'].decode(_data); | ||
| 216 | + if (audioReceivePdu == null) { | ||
| 217 | + loger.warn("音频消息处理,收到的消息为null,不做处理"); | ||
| 218 | + return; | ||
| 219 | + } | ||
| 220 | + audioReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(audioReceivePdu.data, 2);//开头两个字会乱码 | ||
| 221 | + loger.log('音频消息处理 receiveAudiooCommandHandler.', audioReceivePdu); | ||
| 222 | + | ||
| 223 | + //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理 | ||
| 224 | + if (audioReceivePdu.toNodeId != 0 && audioReceivePdu.toNodeId != GlobalConfig.nodeId) { | ||
| 225 | + loger.log('音频消息不处理 toNodeId=', audioReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId); | ||
| 226 | + } else { | ||
| 227 | + this._emit(MessageTypes.AUDIO_BROADCAST, audioReceivePdu); | ||
| 228 | + } | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + tableUpdateHandler(owner, itemIdx, itemData) { | ||
| 232 | + // debugger; | ||
| 233 | + let updateChannelInfo = this.unPackPdu(owner, itemIdx, itemData); | ||
| 234 | + | ||
| 235 | + this.mediaModule.mediaChannels[itemIdx] = updateChannelInfo; | ||
| 236 | + | ||
| 237 | + this._emit(MessageTypes.AUDIO_UPDATE, updateChannelInfo); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + ///////数据的封包和解包///////////////////////////////////////// | ||
| 241 | + packPdu(_param, _itemIdx) { | ||
| 242 | + loger.log("packPdu "); | ||
| 243 | + //验证坐标点集合数组是否合法 | ||
| 244 | + if (_param == null || _itemIdx == null) { | ||
| 245 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 246 | + return null; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + //判断type类型,根据type设置不同的参数 | ||
| 250 | + let packPduModel = new pdu['RCAudioChannelInfoPdu']; | ||
| 251 | + packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED; | ||
| 252 | + packPduModel.channelId = _itemIdx; | ||
| 253 | + packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId; | ||
| 254 | + packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId); | ||
| 255 | + packPduModel.userId =_param.userId||"0"; | ||
| 256 | + packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_AUDIO; | ||
| 257 | + packPduModel.timestamp =_param.timestamp||EngineUtils.creatTimestamp(); | ||
| 258 | + packPduModel.fromNodeId = GlobalConfig.nodeId; | ||
| 259 | + packPduModel.toNodeId = 0; | ||
| 260 | + console.log("packPdu",packPduModel); | ||
| 261 | + return packPduModel; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + unPackPdu(owner, itemIdx, itemData) { | ||
| 265 | + loger.log("unPackPdu "); | ||
| 266 | + if (owner == null || itemIdx == null || itemData == null) { | ||
| 267 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 268 | + return null; | ||
| 269 | + } | ||
| 270 | + try { | ||
| 271 | + let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData); | ||
| 272 | + loger.log("unPackPdu",packChannelInfo); | ||
| 273 | + return packChannelInfo; | ||
| 274 | + } catch (err) { | ||
| 275 | + loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message); | ||
| 276 | + } | ||
| 277 | + return null; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +export default AudioApe; | ||
| 283 | + |
| @@ -454,8 +454,8 @@ class ConferApe extends Ape { | @@ -454,8 +454,8 @@ class ConferApe extends Ape { | ||
| 454 | //视频模块发生更新,人员状态需要更新 | 454 | //视频模块发生更新,人员状态需要更新 |
| 455 | updaterRosterStatus(_param){ | 455 | updaterRosterStatus(_param){ |
| 456 | if(_param){ | 456 | if(_param){ |
| 457 | - loger.log("视频模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); | ||
| 458 | - loger.log(_param.status,_param.fromNodeId,this.rosters[_param.fromNodeId]); | 457 | + loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param.fromNodeId); |
| 458 | + loger.log(_param.status,_param.fromNodeId); | ||
| 459 | //console.log(_param.fromNodeId); | 459 | //console.log(_param.fromNodeId); |
| 460 | //如果是自己。改变自己的状态同步到MCU | 460 | //如果是自己。改变自己的状态同步到MCU |
| 461 | //if(_param.fromNodeId==GlobalConfig.nodeId){ | 461 | //if(_param.fromNodeId==GlobalConfig.nodeId){ |
| @@ -465,8 +465,8 @@ class ConferApe extends Ape { | @@ -465,8 +465,8 @@ class ConferApe extends Ape { | ||
| 465 | 465 | ||
| 466 | //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 | 466 | //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的 |
| 467 | if(_param.status==ApeConsts.CHANNEL_STATUS_OPENING&&this.rosters[_param.fromNodeId]==null){ | 467 | if(_param.status==ApeConsts.CHANNEL_STATUS_OPENING&&this.rosters[_param.fromNodeId]==null){ |
| 468 | - loger.log("视频模块被占用,占有人已经不存在课堂中,释放Channel,_param->",_param); | ||
| 469 | - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER,_param.fromNodeId); | 468 | + loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->",_param); |
| 469 | + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER,{"nodeId":_param.fromNodeId}); | ||
| 470 | } | 470 | } |
| 471 | } | 471 | } |
| 472 | } | 472 | } |
| @@ -145,7 +145,8 @@ class DocApe extends Ape { | @@ -145,7 +145,8 @@ class DocApe extends Ape { | ||
| 145 | return ""; | 145 | return ""; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | - let fullPath=GlobalConfig.docServer+_param.relativeUrl; | 148 | + let port = (GlobalConfig.DOCServerPort == "" || GlobalConfig.DOCServerPort == null) ? "":":" + GlobalConfig.DOCServerPort; |
| 149 | + let fullPath=GlobalConfig.DOCServerIP+port+_param.relativeUrl; | ||
| 149 | var index; | 150 | var index; |
| 150 | switch (_param.type){ | 151 | switch (_param.type){ |
| 151 | case "jpg": | 152 | case "jpg": |
src/apes/MediaModule.js
0 → 100644
| 1 | +// ////////////////////////////////////////////////////////////////////////////// | ||
| 2 | +// VideoApe、AudioApe 共用的方法单独提取处理 | ||
| 3 | +// ////////////////////////////////////////////////////////////////////////////// | ||
| 4 | + | ||
| 5 | +import ApeConsts from './ApeConsts'; | ||
| 6 | +import Loger from 'Loger'; | ||
| 7 | +import MessageTypes from 'MessageTypes'; | ||
| 8 | +import GlobalConfig from 'GlobalConfig'; | ||
| 9 | +import EngineUtils from 'EngineUtils'; | ||
| 10 | + | ||
| 11 | +let loger = Loger.getLoger('MediaModule'); | ||
| 12 | + | ||
| 13 | +class MediaModule { | ||
| 14 | + constructor() { | ||
| 15 | + this.mediaChannels = {}; | ||
| 16 | + this.maxMediaChannel=0; | ||
| 17 | + this.MEDIA_OBJ_TABLE_ID=0; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + //获取播流地址 | ||
| 21 | + getMediaPlayPath(_param) { | ||
| 22 | + loger.log('getMediaPlayPath'); | ||
| 23 | + if (_param == null||_param.siteId == null|| | ||
| 24 | + _param.classId == null||_param.userId == null|| | ||
| 25 | + _param.channelId == null|| _param.timestamp==null) | ||
| 26 | + { | ||
| 27 | + loger.warn('getMediaPlayPath,参数错误', _param); | ||
| 28 | + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 29 | + return {"code": ApeConsts.RETURN_FAILED, "data": ""}; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + let path = ""; | ||
| 33 | + let port=""; | ||
| 34 | + if (_param.type == "m3u8") { | ||
| 35 | + //M3U8 | ||
| 36 | + //http://123.56.73.119:6001/hls/h5dev_403074980_0_983041_1487663265/index.m3u8 | ||
| 37 | + port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort; | ||
| 38 | + path = "http://" + GlobalConfig.RSServerIP | ||
| 39 | + + port + "/live/" | ||
| 40 | + + _param.siteId | ||
| 41 | + + "_" + _param.classId | ||
| 42 | + + "_" + _param.userId | ||
| 43 | + + "_" + _param.channelId | ||
| 44 | + + "_" + _param.timestamp | ||
| 45 | + + "/index.m3u8"; | ||
| 46 | + } else { | ||
| 47 | + port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort; | ||
| 48 | + path = "rtmp://" + GlobalConfig.MSServerIP | ||
| 49 | + + port + "/live/" | ||
| 50 | + + _param.siteId | ||
| 51 | + + "_" + _param.classId | ||
| 52 | + + "_" + _param.userId | ||
| 53 | + + "_" + _param.channelId | ||
| 54 | + + "_" + _param.timestamp; | ||
| 55 | + } | ||
| 56 | + return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path}; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + //获取推流地址 | ||
| 60 | + getMediaPublishPath(_param) { | ||
| 61 | + loger.log('getMediaPublishPath'); | ||
| 62 | + //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 | ||
| 63 | + let freeChannel = this.getFreeMediaChannel(); | ||
| 64 | + if (freeChannel == 0) { | ||
| 65 | + return {"code":ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + //默认方式推流 | ||
| 69 | + let pubType="live"; | ||
| 70 | + //flash推流 | ||
| 71 | + if(_param&&_param.type=="flash"){ | ||
| 72 | + pubType ="flash"; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + //端口,有端口就显示 ":xxx",没有端口就是"" | ||
| 76 | + let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort; | ||
| 77 | + //时间戳 | ||
| 78 | + let timestamp = EngineUtils.creatTimestamp(); | ||
| 79 | + | ||
| 80 | + //生成推流地址和推流数据(同步数据的时候用) | ||
| 81 | + let publishUrl = "rtmp://" + GlobalConfig.MSServerIP | ||
| 82 | + + port + "/"+pubType+"/" +GlobalConfig.siteId+"_" | ||
| 83 | + + GlobalConfig.classId + "_"+GlobalConfig.userId | ||
| 84 | + +"_" + freeChannel + "_" + timestamp; | ||
| 85 | + return {"code": ApeConsts.RETURN_SUCCESS, | ||
| 86 | + "data":"", | ||
| 87 | + "siteId":GlobalConfig.siteId, | ||
| 88 | + "classId":GlobalConfig.classId, | ||
| 89 | + "userId":GlobalConfig.userId, | ||
| 90 | + "channelId": freeChannel, | ||
| 91 | + "timestamp": timestamp, | ||
| 92 | + "publishUrl": publishUrl | ||
| 93 | + }; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + //获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId | ||
| 97 | + getFreeMediaChannel() { | ||
| 98 | + let counter = 0; | ||
| 99 | + for (let key in this.mediaChannels) { | ||
| 100 | + let item = this.mediaChannels[key]; | ||
| 101 | + if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) { | ||
| 102 | + return item.channelId; | ||
| 103 | + } | ||
| 104 | + counter++; | ||
| 105 | + } | ||
| 106 | + loger.log("getFreeMediaChannel","maxMediaChannel",this.maxMediaChannel,"counter:",counter); | ||
| 107 | + console.log(this.mediaChannels); | ||
| 108 | + if (counter < this.maxMediaChannel) { | ||
| 109 | + return this.MEDIA_OBJ_TABLE_ID + (counter); | ||
| 110 | + } | ||
| 111 | + return 0;//没有空闲的 | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId | ||
| 115 | + getOpeningMediaChannel(_nodeId){ | ||
| 116 | + if(_nodeId==null||_nodeId==0){ | ||
| 117 | + return 0; | ||
| 118 | + } | ||
| 119 | + for (let key in this.mediaChannels) { | ||
| 120 | + let item = this.mediaChannels[key]; | ||
| 121 | + if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) { | ||
| 122 | + return item.channelId; | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + return 0; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + //检查频道是否已经被占用 | ||
| 129 | + checkChannelIsOpening(_channelId){ | ||
| 130 | + if(_channelId==null){ | ||
| 131 | + loger.warn("checkChannelIsOpening error,channel=",_channelId); | ||
| 132 | + return true; | ||
| 133 | + } | ||
| 134 | + let channelInfo=this.mediaChannels[_channelId]; | ||
| 135 | + if(channelInfo==null||channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){ | ||
| 136 | + return false; | ||
| 137 | + } | ||
| 138 | + return true; | ||
| 139 | + } | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +export default MediaModule; | ||
| 143 | + |
| 1 | // ////////////////////////////////////////////////////////////////////////////// | 1 | // ////////////////////////////////////////////////////////////////////////////// |
| 2 | -// | ||
| 3 | -// Copyright (C) 2016-present All Rights Reserved. | ||
| 4 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | -// http://www.apache.org/licenses/LICENSE-2.0 | ||
| 6 | -// | ||
| 7 | -// Github Home: https://github.com/AlexWang1987 | ||
| 8 | -// Author: AlexWang | ||
| 9 | -// Date: 2016-08-23 18:07:28 | ||
| 10 | -// QQ Email: 1669499355@qq.com | ||
| 11 | -// Last Modified time: 2016-09-06 11:13:59 | ||
| 12 | -// Description: LiveClass-VideoApe | ||
| 13 | -// | 2 | +//视频模块 |
| 14 | // ////////////////////////////////////////////////////////////////////////////// | 3 | // ////////////////////////////////////////////////////////////////////////////// |
| 15 | 4 | ||
| 16 | import Ape from './Ape'; | 5 | import Ape from './Ape'; |
| @@ -20,10 +9,11 @@ import Loger from 'Loger'; | @@ -20,10 +9,11 @@ import Loger from 'Loger'; | ||
| 20 | import MessageTypes from 'MessageTypes'; | 9 | import MessageTypes from 'MessageTypes'; |
| 21 | import GlobalConfig from 'GlobalConfig'; | 10 | import GlobalConfig from 'GlobalConfig'; |
| 22 | import EngineUtils from 'EngineUtils'; | 11 | import EngineUtils from 'EngineUtils'; |
| 12 | +import MediaModule from "./MediaModule"; | ||
| 23 | 13 | ||
| 24 | -let loger = Loger.getLoger('VideoChat'); | 14 | +let loger = Loger.getLoger('VideoApe'); |
| 25 | 15 | ||
| 26 | -class VideoChat extends Ape { | 16 | +class VideoApe extends Ape { |
| 27 | constructor() { | 17 | constructor() { |
| 28 | super( | 18 | super( |
| 29 | ApeConsts.VIDEO_SESSION_ID, | 19 | ApeConsts.VIDEO_SESSION_ID, |
| @@ -31,8 +21,9 @@ class VideoChat extends Ape { | @@ -31,8 +21,9 @@ class VideoChat extends Ape { | ||
| 31 | ApeConsts.VIDEO_SESSION_TAG | 21 | ApeConsts.VIDEO_SESSION_TAG |
| 32 | ); | 22 | ); |
| 33 | 23 | ||
| 34 | - //Attributes | ||
| 35 | - this.videoChannels = {}; | 24 | + this.mediaModule=new MediaModule(); |
| 25 | + this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.VIDEO_OBJ_TABLE_ID; | ||
| 26 | + this.mediaModule.mediaChannels={}; | ||
| 36 | 27 | ||
| 37 | // Ape Models | 28 | // Ape Models |
| 38 | this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); | 29 | this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); |
| @@ -41,84 +32,23 @@ class VideoChat extends Ape { | @@ -41,84 +32,23 @@ class VideoChat extends Ape { | ||
| 41 | // videoApe 监听视频控制消息,用户之间的消息传递 | 32 | // videoApe 监听视频控制消息,用户之间的消息传递 |
| 42 | this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this)); | 33 | this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this)); |
| 43 | } | 34 | } |
| 35 | + //ape加入成功 | ||
| 36 | + onJoinChannelHandlerSuccess(){ | ||
| 37 | + //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据 | ||
| 38 | + this.mediaModule.maxMediaChannel=GlobalConfig.maxVideoChannels; | ||
| 39 | + } | ||
| 44 | 40 | ||
| 45 | /////////////发送数据操作//////////////////////////////////////////// | 41 | /////////////发送数据操作//////////////////////////////////////////// |
| 46 | //获取播流地址 | 42 | //获取播流地址 |
| 47 | getPlayVideoPath(_param) { | 43 | getPlayVideoPath(_param) { |
| 48 | loger.log('getPlayVideoPath'); | 44 | loger.log('getPlayVideoPath'); |
| 49 | - if (_param == null||_param.siteId == null|| | ||
| 50 | - _param.classId == null||_param.userId == null|| | ||
| 51 | - _param.channelId == null|| _param.timestamp==null) | ||
| 52 | - { | ||
| 53 | - loger.warn('getPlayVideoPath,参数错误', _param); | ||
| 54 | - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | ||
| 55 | - return {"code": 1, "data": ""}; | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - let path = ""; | ||
| 59 | - let port=""; | ||
| 60 | - if (_param.type == "m3u8") { | ||
| 61 | - //M3U8 | ||
| 62 | - //http://123.56.73.119:6001/hls/h5dev_403074980_0_983041_1487663265/index.m3u8 | ||
| 63 | - port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort; | ||
| 64 | - path = "http://" + GlobalConfig.RSServerIP | ||
| 65 | - + port + "/live/" | ||
| 66 | - + _param.siteId | ||
| 67 | - + "_" + _param.classId | ||
| 68 | - + "_" + _param.userId | ||
| 69 | - + "_" + _param.channelId | ||
| 70 | - + "_" + _param.timestamp | ||
| 71 | - + "/index.m3u8"; | ||
| 72 | - } else { | ||
| 73 | - port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort; | ||
| 74 | - path = "rtmp://" + GlobalConfig.MSServerIP | ||
| 75 | - + port + "/live/" | ||
| 76 | - + _param.siteId | ||
| 77 | - + "_" + _param.classId | ||
| 78 | - + "_" + _param.userId | ||
| 79 | - + "_" + _param.channelId | ||
| 80 | - + "_" + _param.timestamp; | ||
| 81 | - } | ||
| 82 | - return {"code": 0, "data": path}; | 45 | + return this.mediaModule.getMediaPlayPath(_param); |
| 83 | } | 46 | } |
| 84 | 47 | ||
| 85 | //获取推流地址 | 48 | //获取推流地址 |
| 86 | getPublishVideoPath(_param) { | 49 | getPublishVideoPath(_param) { |
| 87 | loger.log('getPublishVideoPath'); | 50 | loger.log('getPublishVideoPath'); |
| 88 | - | ||
| 89 | - //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 | ||
| 90 | - let freeChannel = this.getFreeVideoChannel(); | ||
| 91 | - if (freeChannel == 0) { | ||
| 92 | - return {"code": 1, "data": "不能再打开更多的设备"}; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - //默认方式推流 | ||
| 96 | - let pubType="live"; | ||
| 97 | - //flash推流 | ||
| 98 | - if(_param&&_param.type=="flash"){ | ||
| 99 | - pubType ="flash"; | ||
| 100 | - } | ||
| 101 | - | ||
| 102 | - //端口,有端口就显示 ":xxx",没有端口就是"" | ||
| 103 | - let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort; | ||
| 104 | - //时间戳 | ||
| 105 | - let timestamp = EngineUtils.creatTimestamp(); | ||
| 106 | - | ||
| 107 | - //生成推流地址和推流数据(同步数据的时候用) | ||
| 108 | - let publishUrl = "rtmp://" + GlobalConfig.MSServerIP | ||
| 109 | - + port + "/"+pubType+"/" +GlobalConfig.siteId+"_" | ||
| 110 | - + GlobalConfig.classId + "_"+GlobalConfig.userId | ||
| 111 | - +"_" + freeChannel + "_" + timestamp; | ||
| 112 | - return {"code": 0, | ||
| 113 | - "data": | ||
| 114 | - { "siteId":GlobalConfig.siteId, | ||
| 115 | - "classId":GlobalConfig.classId, | ||
| 116 | - "userId":GlobalConfig.userId, | ||
| 117 | - "channelId": freeChannel, | ||
| 118 | - "timestamp": timestamp, | ||
| 119 | - "publishUrl": publishUrl | ||
| 120 | - } | ||
| 121 | - }; | 51 | + return this.mediaModule.getMediaPublishPath(_param); |
| 122 | } | 52 | } |
| 123 | 53 | ||
| 124 | //推流 | 54 | //推流 |
| @@ -129,28 +59,28 @@ class VideoChat extends Ape { | @@ -129,28 +59,28 @@ class VideoChat extends Ape { | ||
| 129 | { | 59 | { |
| 130 | loger.warn('publishVideo,参数错误', _param); | 60 | loger.warn('publishVideo,参数错误', _param); |
| 131 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | 61 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); |
| 132 | - return {"code": 1, "data": ""}; | 62 | + return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"}; |
| 133 | } | 63 | } |
| 134 | 64 | ||
| 135 | loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); | 65 | loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); |
| 136 | 66 | ||
| 137 | //同一个nodeId只允许推一个流,如果已经推了就不能再推 | 67 | //同一个nodeId只允许推一个流,如果已经推了就不能再推 |
| 138 | - if(this.getOpeningVideoChannel(GlobalConfig.nodeId)!=0){ | 68 | + if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){ |
| 139 | loger.warn("publishVideo,已经存在一个流,不能再推"); | 69 | loger.warn("publishVideo,已经存在一个流,不能再推"); |
| 140 | - return; | 70 | + return {"code": ApeConsts.RETURN_FAILED, "data": "已经存在一个流,不能再推"}; |
| 141 | } | 71 | } |
| 142 | 72 | ||
| 143 | //判断当前是否还有空闲的channle | 73 | //判断当前是否还有空闲的channle |
| 144 | - let freeChannel = this.getFreeVideoChannel(); | 74 | + let freeChannel = this.mediaModule.getFreeMediaChannel(); |
| 145 | if (freeChannel == 0) { | 75 | if (freeChannel == 0) { |
| 146 | loger.warn("publishVideo,没有空闲的channel "); | 76 | loger.warn("publishVideo,没有空闲的channel "); |
| 147 | - return {"code": 1, "data": "不能再打开更多的设备"}; | 77 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; |
| 148 | } | 78 | } |
| 149 | 79 | ||
| 150 | //判断当前的频道是否已经占用 | 80 | //判断当前的频道是否已经占用 |
| 151 | - if(this.checkChannelIsOpening(_param.channelId)){ | 81 | + if(this.mediaModule.checkChannelIsOpening(_param.channelId)){ |
| 152 | loger.warn(_param.channelId,"频道已经被占用"); | 82 | loger.warn(_param.channelId,"频道已经被占用"); |
| 153 | - return {"code":1,"data":"频道已经被占用!"}; | 83 | + return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"}; |
| 154 | } | 84 | } |
| 155 | 85 | ||
| 156 | let channelInfo={}; | 86 | let channelInfo={}; |
| @@ -163,7 +93,7 @@ class VideoChat extends Ape { | @@ -163,7 +93,7 @@ class VideoChat extends Ape { | ||
| 163 | channelInfo.toNodeId=0; | 93 | channelInfo.toNodeId=0; |
| 164 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO; | 94 | channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO; |
| 165 | this.sendTableUpdateHandler(channelInfo); | 95 | this.sendTableUpdateHandler(channelInfo); |
| 166 | - return {"code":0,"data":"推流成功!"} | 96 | + return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} |
| 167 | } | 97 | } |
| 168 | 98 | ||
| 169 | //停止推流, | 99 | //停止推流, |
| @@ -177,10 +107,10 @@ class VideoChat extends Ape { | @@ -177,10 +107,10 @@ class VideoChat extends Ape { | ||
| 177 | nodeId=GlobalConfig.nodeId; | 107 | nodeId=GlobalConfig.nodeId; |
| 178 | } | 108 | } |
| 179 | 109 | ||
| 180 | - let openingChannel = this.getOpeningVideoChannel(nodeId); | 110 | + let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); |
| 181 | if (openingChannel == 0) { | 111 | if (openingChannel == 0) { |
| 182 | - loger.warn(nodeId,"stopPublishVideo,没有打开的channel,不需要关闭"); | ||
| 183 | - return {"code": 1, "data": "没有打开的channel,不需要关闭"}; | 112 | + loger.warn(nodeId,"stopPublishVideo,没有占用channel,不需要关闭"); |
| 113 | + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"}; | ||
| 184 | } | 114 | } |
| 185 | 115 | ||
| 186 | let channelInfo={}; | 116 | let channelInfo={}; |
| @@ -201,23 +131,22 @@ class VideoChat extends Ape { | @@ -201,23 +131,22 @@ class VideoChat extends Ape { | ||
| 201 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); | 131 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); |
| 202 | return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"}; | 132 | return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"}; |
| 203 | } | 133 | } |
| 204 | - return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"}; | 134 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能发送Video消息.McuClient还未初始化数据"}; |
| 205 | } | 135 | } |
| 206 | if (_param == null) { | 136 | if (_param == null) { |
| 207 | loger.warn('sendVideoCommandMsg失败,参数错误', _param); | 137 | loger.warn('sendVideoCommandMsg失败,参数错误', _param); |
| 208 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); | 138 | this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); |
| 209 | - return {"code": 1, "data": "sendVideoCommandMsg失败,参数错误"}; | ||
| 210 | - ; | 139 | + return {"code": ApeConsts.RETURN_FAILED, "data": "sendVideoCommandMsg失败,参数错误"}; |
| 211 | } | 140 | } |
| 212 | // to, message | 141 | // to, message |
| 213 | loger.log('发送Video消息.', _param); | 142 | loger.log('发送Video消息.', _param); |
| 214 | 143 | ||
| 215 | if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) { | 144 | if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) { |
| 216 | //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 | 145 | //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 |
| 217 | - let freeChannel = this.getFreeVideoChannel(); | 146 | + let freeChannel = this.mediaModule.getFreeMediaChannel(); |
| 218 | if (freeChannel == 0) { | 147 | if (freeChannel == 0) { |
| 219 | loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param); | 148 | loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param); |
| 220 | - return {"code": 1, "data": "不能再打开更多的设备"}; | 149 | + return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; |
| 221 | } | 150 | } |
| 222 | } | 151 | } |
| 223 | /* message RCVideoSendDataRequestPdu { | 152 | /* message RCVideoSendDataRequestPdu { |
| @@ -246,7 +175,7 @@ class VideoChat extends Ape { | @@ -246,7 +175,7 @@ class VideoChat extends Ape { | ||
| 246 | loger.log('发送公聊Video消息.'); | 175 | loger.log('发送公聊Video消息.'); |
| 247 | this.sendChatUniform(videoSendPdu); | 176 | this.sendChatUniform(videoSendPdu); |
| 248 | } | 177 | } |
| 249 | - return {"code": 0, "data": ""}; | 178 | + return {"code": ApeConsts.RETURN_SUCCESS, "data": ""}; |
| 250 | } | 179 | } |
| 251 | 180 | ||
| 252 | sendTableUpdateHandler(_channelInfo) { | 181 | sendTableUpdateHandler(_channelInfo) { |
| @@ -314,45 +243,15 @@ class VideoChat extends Ape { | @@ -314,45 +243,15 @@ class VideoChat extends Ape { | ||
| 314 | if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) { | 243 | if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) { |
| 315 | loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId); | 244 | loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId); |
| 316 | } else { | 245 | } else { |
| 317 | - this._emit(MessageTypes.VIDEO_COMMAND, videoReceivePdu); | 246 | + this._emit(MessageTypes.VIDEO_BROADCAST, videoReceivePdu); |
| 318 | } | 247 | } |
| 319 | } | 248 | } |
| 320 | 249 | ||
| 321 | tableUpdateHandler(owner, itemIdx, itemData) { | 250 | tableUpdateHandler(owner, itemIdx, itemData) { |
| 322 | // debugger; | 251 | // debugger; |
| 323 | let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData); | 252 | let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData); |
| 324 | - //videoChannelInfo.owner = owner; | ||
| 325 | - //videoChannelInfo.channelId = itemIdx; | ||
| 326 | - //videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status; | ||
| 327 | - //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo); | ||
| 328 | - this.videoChannels[itemIdx] = videoChannelInfo; | ||
| 329 | - | 253 | + this.mediaModule.mediaChannels[itemIdx] = videoChannelInfo; |
| 330 | this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo); | 254 | this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo); |
| 331 | - /* switch (videoChannelInfo.status) { | ||
| 332 | - case ApeConsts.CHANNEL_STATUS_RELEASED: | ||
| 333 | - // 只能关闭自己的流 | ||
| 334 | - if (this.activeChannelId === videoChannelInfo.channelId) { | ||
| 335 | - this.activeChannelId = 0; | ||
| 336 | - this.activeURL = ''; | ||
| 337 | - this.emitVideoChange(); | ||
| 338 | - } | ||
| 339 | - break; | ||
| 340 | - case ApeConsts.CHANNEL_STATUS_OPENING: | ||
| 341 | - //_playUrl = "rtmfp://" + Config.mediaServerAddr + ":" + Config.mediaServerPort + "/message/" + _streamName; | ||
| 342 | - //_cdnUrl = "rtmp://" + Config.mediaCDNServerAddr + ":" + Config.mediaCDNServerPort + "/message/" + _streamName; | ||
| 343 | - //this.activeChannelId = videoChannelInfo.channelId; | ||
| 344 | - //// AMS/FMS | ||
| 345 | - //if (this._classInfo.msType ==ApeConsts.MS_TYPE_FMS) { | ||
| 346 | - // this.activeURL = `http://dazhi.3mang.com/live/${this._classInfo.classId}/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`; | ||
| 347 | - //}else { | ||
| 348 | - // this.activeURL = `http://hls.3mang.com/live/${this._classInfo.classId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`; | ||
| 349 | - //} | ||
| 350 | - // 任何人都可以打开流 | ||
| 351 | - this.emitVideoChange(); | ||
| 352 | - break; | ||
| 353 | - default: | ||
| 354 | - break; | ||
| 355 | - }*/ | ||
| 356 | } | 255 | } |
| 357 | 256 | ||
| 358 | ///////数据的封包和解包///////////////////////////////////////// | 257 | ///////数据的封包和解包///////////////////////////////////////// |
| @@ -364,14 +263,6 @@ class VideoChat extends Ape { | @@ -364,14 +263,6 @@ class VideoChat extends Ape { | ||
| 364 | return null; | 263 | return null; |
| 365 | } | 264 | } |
| 366 | 265 | ||
| 367 | - /* message RCVideoChannelInfoPdu { | ||
| 368 | - optional uint32 status = 1;//开启的状态 | ||
| 369 | - optional uint32 channel_id = 2;//唯一的频道id | ||
| 370 | - optional uint32 timestamp = 3;//更新的时间戳 | ||
| 371 | - optional uint32 from_node_id = 4;//发起者的id | ||
| 372 | - optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收) | ||
| 373 | - }*/ | ||
| 374 | - | ||
| 375 | //判断type类型,根据type设置不同的参数 | 266 | //判断type类型,根据type设置不同的参数 |
| 376 | let packPduModel = new pdu['RCVideoChannelInfoPdu']; | 267 | let packPduModel = new pdu['RCVideoChannelInfoPdu']; |
| 377 | packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED; | 268 | packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED; |
| @@ -403,53 +294,7 @@ class VideoChat extends Ape { | @@ -403,53 +294,7 @@ class VideoChat extends Ape { | ||
| 403 | } | 294 | } |
| 404 | return null; | 295 | return null; |
| 405 | } | 296 | } |
| 406 | - | ||
| 407 | - //获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId | ||
| 408 | - getFreeVideoChannel() { | ||
| 409 | - loger.log("getFreeVideoChannel"); | ||
| 410 | - console.log(this.videoChannels); | ||
| 411 | - let counter = 0; | ||
| 412 | - for (let key in this.videoChannels) { | ||
| 413 | - let item = this.videoChannels[key]; | ||
| 414 | - if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) { | ||
| 415 | - return item.channelId; | ||
| 416 | - } | ||
| 417 | - counter++; | ||
| 418 | - } | ||
| 419 | - if (counter < GlobalConfig.maxVideoChannels) { | ||
| 420 | - return ApeConsts.VIDEO_OBJ_TABLE_ID + (counter); | ||
| 421 | - } | ||
| 422 | - return 0;//没有空闲的 | ||
| 423 | - } | ||
| 424 | - | ||
| 425 | - //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId | ||
| 426 | - getOpeningVideoChannel(_nodeId){ | ||
| 427 | - if(_nodeId==null||_nodeId==0){ | ||
| 428 | - return 0; | ||
| 429 | - } | ||
| 430 | - for (let key in this.videoChannels) { | ||
| 431 | - let item = this.videoChannels[key]; | ||
| 432 | - if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) { | ||
| 433 | - return item.channelId; | ||
| 434 | - } | ||
| 435 | - } | ||
| 436 | - return 0; | ||
| 437 | - } | ||
| 438 | - | ||
| 439 | - //检查频道是否已经被占用 | ||
| 440 | - checkChannelIsOpening(_channelId){ | ||
| 441 | - if(_channelId==null){ | ||
| 442 | - loger.warn("checkChannelIsOpening error,channel=",_channelId); | ||
| 443 | - return true; | ||
| 444 | - } | ||
| 445 | - | ||
| 446 | - let channelInfo=this.videoChannels[_channelId]; | ||
| 447 | - if(channelInfo==null||channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){ | ||
| 448 | - return false; | ||
| 449 | - } | ||
| 450 | - return true; | ||
| 451 | - } | ||
| 452 | } | 297 | } |
| 453 | 298 | ||
| 454 | -export default VideoChat; | 299 | +export default VideoApe; |
| 455 | 300 |
| @@ -740,10 +740,16 @@ message RCGiftSendDataRequestPdu { | @@ -740,10 +740,16 @@ message RCGiftSendDataRequestPdu { | ||
| 740 | optional bytes user_data = 5; | 740 | optional bytes user_data = 5; |
| 741 | } | 741 | } |
| 742 | 742 | ||
| 743 | -message RCAudioSendDataRequestPdu { | 743 | +message RCAudioSendDataRequestPdu1 { |
| 744 | optional uint32 initiator = 1; | 744 | optional uint32 initiator = 1; |
| 745 | required bytes user_data = 2; | 745 | required bytes user_data = 2; |
| 746 | } | 746 | } |
| 747 | +message RCAudioSendDataRequestPdu { | ||
| 748 | + required uint32 from_node_id = 1;//发起人 | ||
| 749 | + optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收 | ||
| 750 | + optional uint32 actionType = 3;//消息指令类型; | ||
| 751 | + optional bytes data = 4;//其他数据,这个根据actionType来确定数据的结构 | ||
| 752 | +} | ||
| 747 | 753 | ||
| 748 | message RCVideoSendDataRequestPdu { | 754 | message RCVideoSendDataRequestPdu { |
| 749 | required uint32 from_node_id = 1;//发起人 | 755 | required uint32 from_node_id = 1;//发起人 |
| @@ -759,6 +765,17 @@ message RCAudioChannelInfoRecordPdu { | @@ -759,6 +765,17 @@ message RCAudioChannelInfoRecordPdu { | ||
| 759 | required uint32 bitrate = 4; | 765 | required uint32 bitrate = 4; |
| 760 | required uint32 codec = 5; | 766 | required uint32 codec = 5; |
| 761 | } | 767 | } |
| 768 | +message RCAudioChannelInfoPdu { | ||
| 769 | + optional uint32 status = 1;//开启的状态 | ||
| 770 | + optional uint32 channel_id = 2;//唯一的频道id | ||
| 771 | + optional uint32 timestamp = 3;//更新的时间戳 | ||
| 772 | + optional uint32 from_node_id = 4;//发起者的id | ||
| 773 | + optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收) | ||
| 774 | + optional uint32 media_type = 6;//媒体类型:视频(包含音频)或音频 | ||
| 775 | + optional uint32 class_id = 7;//课堂号 | ||
| 776 | + optional string site_id = 8;//站点号 | ||
| 777 | + optional string user_id = 9;//用户的userId | ||
| 778 | +} | ||
| 762 | 779 | ||
| 763 | message RCVideoChannelInfoPdu { | 780 | message RCVideoChannelInfoPdu { |
| 764 | optional uint32 status = 1;//开启的状态 | 781 | optional uint32 status = 1;//开启的状态 |
| @@ -907,6 +924,7 @@ message RCClassStatusInfoPdu { | @@ -907,6 +924,7 @@ message RCClassStatusInfoPdu { | ||
| 907 | optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页 | 924 | optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页 |
| 908 | } | 925 | } |
| 909 | 926 | ||
| 927 | + | ||
| 910 | //end | 928 | //end |
| 911 | `; | 929 | `; |
| 912 | 930 |
-
请 注册 或 登录 后发表评论