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