From 283bfd10663dd65ab0ed7ecb9efcdc474eb591d6 Mon Sep 17 00:00:00 2001 From: liyong <liyong@3mang.com> Date: Fri, 29 Sep 2017 15:51:27 +0800 Subject: [PATCH] 1.新增控制webRtc模块视频窗口缩放的接口,在课堂信息中增加字段videoScale 这个是视频的缩放倍数; --- src/EngineEntrance.js | 27 ++++++++++++++++++++++++++- src/GlobalConfig.js | 5 +++++ src/apes/ConferApe.js | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/apes/WebRtcApe.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/pdus/pro.js | 1 + 5 files changed, 195 insertions(+), 219 deletions(-) diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js index 8178735..d54b9da 100644 --- a/src/EngineEntrance.js +++ b/src/EngineEntrance.js @@ -62,7 +62,7 @@ export default class MessageEntrance extends Emiter { constructor() { super(); //sdk 信息 - GlobalConfig.sdkVersion = "v2.14.5.20170927"; + GlobalConfig.sdkVersion = "v2.15.3.20170929"; loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); //设置 @@ -297,6 +297,7 @@ export default class MessageEntrance extends Emiter { this.setAppConfig=this._setAppConfig.bind(this); this.recordControl=this._mediaRecordControl.bind(this); + this.changeRtcVideoConfig=this._changeRtcVideoConfig.bind(this);//设置webRtc视频视图的缩放 this.setDeviceInfo = this._setDeviceInfo.bind(this); //设置设备信息(麦克风,摄像头等等.....) this.setMessageDelay = this._setMessageDelay.bind(this); //设置是否延迟消息 @@ -2916,6 +2917,30 @@ export default class MessageEntrance extends Emiter { } /* + * 设置RTC视频属性 + * */ + _changeRtcVideoConfig(_params){ + loger.log("设置RTC视频属性",_params); + if(!_params){ + return; + } + if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){ + return; + } + if(_webRtc){ + _webRtc.changeRtcVideoConfig(_params); + + //如果是老师操作,需要同步给所有人 + if(GlobalConfig.isHost){ + if(_confer_ape){ + GlobalConfig.videoScale=_params.videoScale||1; + _confer_ape.sendUpdaterClassStatusInfo({videoScale:_params.videoScale}); + } + } + } + } + + /* * 设置监课和需要隐藏显示的用户视图 * */ _setInvisibleMediaView(_params){ diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js index 5dc9a63..febc847 100644 --- a/src/GlobalConfig.js +++ b/src/GlobalConfig.js @@ -101,6 +101,7 @@ class GlobalConfig { classStatusInfo.currentSceneTableId = this.currentSceneTableId; //文档区域的模块显示 classStatusInfo.serverAndLoacTimeDistanc = this.serverAndLoacTimeDistanc; + classStatusInfo.videoScale=this.videoScale; return classStatusInfo; } //设置当前的课堂状态的信息 @@ -148,6 +149,7 @@ class GlobalConfig { this.currentSceneTableId = data.currentSceneTableId || 0; //文档区域的模块显示 this.isEnableDraw=data.isEnableDraw||false;//是否开启所有人的绘制权限 + this.videoScale=parseInt(data.videoScale)||1; // 全局禁言状态 this.silence = data.silence || false; this.silenceUsers =data.silenceUsers || {}; @@ -607,5 +609,8 @@ GlobalConfig.stopRecordingInterfaces="";//停止录制的接口 GlobalConfig.getTxRecordInfoInterfaces="";//获取媒体录制信息数据的接口(tx) GlobalConfig.getChannelToken="";//获取token的地址 + +GlobalConfig.videoScale=1;//视频的缩放倍数,默认1倍无缩放 + export default GlobalConfig; diff --git a/src/apes/ConferApe.js b/src/apes/ConferApe.js index 8aec0a2..0007e84 100644 --- a/src/apes/ConferApe.js +++ b/src/apes/ConferApe.js @@ -130,7 +130,7 @@ class ConferApe extends Ape { nodeInfoRecordPdu.city = GlobalConfig.city; //城市 nodeInfoRecordPdu.province = GlobalConfig.province; //服务商 nodeInfoRecordPdu.isp = GlobalConfig.isp; //服务商 - nodeInfoRecordPdu.msList=[]; + nodeInfoRecordPdu.msList = []; //用户的MS列表 let msListAll = GlobalConfig.msListFinal; for (let k = 0; k < msListAll.length; k++) { @@ -257,10 +257,10 @@ class ConferApe extends Ape { //conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除 conferRecordSendPdu.classTime = GlobalConfig.recordTimestamp; //课堂录制的累积时间,不会被清除 conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec"; - if(GlobalConfig.recordStatus){ - loger.log("发送录制的指令->开启",conferRecordSendPdu); - }else { - loger.log("发送录制的指令->停止",conferRecordSendPdu); + if (GlobalConfig.recordStatus) { + loger.log("发送录制的指令->开启", conferRecordSendPdu); + } else { + loger.log("发送录制的指令->停止", conferRecordSendPdu); } this.sendChatUniform(conferRecordSendPdu); } @@ -273,64 +273,65 @@ class ConferApe extends Ape { return; } //如果已经开始录制就不再开启 - if(GlobalConfig.recordStatus&&this.rosterLen>1){ - loger.warn('目前已经是录制状态->当前课堂人数:'+this.rosterLen); + if (GlobalConfig.recordStatus && this.rosterLen > 1) { + loger.warn('目前已经是录制状态->当前课堂人数:' + this.rosterLen); return false; } //如果是host或者当前课堂只有1个人 if (this.checkHasRecordControl()) { - loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen); + loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus, "当前人数:" + this.rosterLen); //如果录制的文件名不存在,需要创建一个名字 let timestampYMD = EngineUtils.creatTimestampYMD(); - if(!GlobalConfig.recordFileName){ - GlobalConfig.recordFileName=GlobalConfig.siteId + "/" + timestampYMD + "/" + GlobalConfig.classId + "_" + timestampYMD + ".rec"; //4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` + if (!GlobalConfig.recordFileName) { + GlobalConfig.recordFileName = GlobalConfig.siteId + "/" + timestampYMD + "/" + GlobalConfig.classId + "_" + timestampYMD + ".rec"; //4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` } GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); - this.sendConferRecordMsg({"recordStatus": true}); - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); - this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制 + this.sendConferRecordMsg({"recordStatus": true}); + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); + this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制 } } //检测是否有控制录制操作的权限 - checkHasRecordControl(){ + checkHasRecordControl() { //loger.warn('检测是否有控制录制操作的权限', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen); //1.如果自己是老师或者当前课堂只有一个人 - if(GlobalConfig.isHost||this.rosterLen<=1){ + if (GlobalConfig.isHost || this.rosterLen <= 1) { return true; } //2.如果自己不是老师,需要判断当前课堂内是否有老师,如果有老师就不做操作 - for(let i in this.rosters){ + for (let i in this.rosters) { //如果就老师就停止 - let rosterItem=this.rosters[i]; - if(rosterItem&&rosterItem.userRole==ApeConsts.host){ + let rosterItem = this.rosters[i]; + if (rosterItem && rosterItem.userRole == ApeConsts.host) { return false; } } //3.课堂内有多个人并且都不是老师,选择一个nodeId最小的来操作 - for(let k in this.rosters){ + for (let k in this.rosters) { //如果选择的nodeId是自己就有权限,否则没有权限 - if(k==GlobalConfig.nodeId){ + if (k == GlobalConfig.nodeId) { return true; - }else { + } else { return false; } } return false } + //停止录制 stopRecord(isForce) { //判断是否有权限 - if (this.checkHasRecordControl()){ + if (this.checkHasRecordControl()) { loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus); //this.sendUpdaterClassStatusInfo({"actionType":GlobalConfig.classStatus, isStopAllPublishMedia: true}); this.sendConferMsg({"to": 0, "message": "STOP_ALL_PUBLISH", "actionType": ApeConsts.STOP_ALL_PUBLISH}); - setTimeout(()=>{ + setTimeout(()=> { GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); this.sendConferRecordMsg({"recordStatus": false}); - },2000); - }else { + }, 2000); + } else { loger.warn('没有权限停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus); } } @@ -394,8 +395,9 @@ class ConferApe extends Ape { loger.warn('学生没有开启禁言的权限'); } } + //全局绘制权限控制 - changeDrawStatus(params){ + changeDrawStatus(params) { if (!GlobalConfig.isNormal) { //同步禁言状态 if (params && params.isEnableDraw == true) { @@ -408,12 +410,13 @@ class ConferApe extends Ape { loger.warn('学生没有开启绘制的权限'); } } + //控制指定用户的画笔状态 - changeUserDrawStatus(_param){ + changeUserDrawStatus(_param) { loger.log('控制指定用户的画笔状态->', _param); if (_param && _param.isDisEnableDraw == true) { //举手 - GlobalConfig.selfDisEnableDrawTime=EngineUtils.creatTimestamp();//被禁用画笔的时间 + GlobalConfig.selfDisEnableDrawTime = EngineUtils.creatTimestamp();//被禁用画笔的时间 } else { GlobalConfig.selfDisEnableDrawTime = 0; //取消禁用画笔 } @@ -426,12 +429,12 @@ class ConferApe extends Ape { let timestamp = EngineUtils.creatTimestampStr(); GlobalConfig.classStopTime = timestamp; -/* - //如果录制的文件名不存在,需要创建一个名字 - let timestampYMD = EngineUtils.creatTimestampYMD(); - GlobalConfig.recordFileName = GlobalConfig.recordFileName || - GlobalConfig.siteId + "/" + timestampYMD + "/" + GlobalConfig.classId + "_" + timestampYMD + ".rec"; //4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` -*/ + /* + //如果录制的文件名不存在,需要创建一个名字 + let timestampYMD = EngineUtils.creatTimestampYMD(); + GlobalConfig.recordFileName = GlobalConfig.recordFileName || + GlobalConfig.siteId + "/" + timestampYMD + "/" + GlobalConfig.classId + "_" + timestampYMD + ".rec"; //4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename` + */ if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) { //之前是为开始状态,第一次点开始 @@ -530,25 +533,26 @@ class ConferApe extends Ape { console.log(_param); } } + //控制画笔的使用状态 controlDrawStatus(_param) { - //控制用户的举手状态 - if (!_param || !_param.nodeId) { - loger.log('控制画笔的使用状态->失败->参数错误', _param); - return; - } - let msgObj = {}; - msgObj.nodeId = _param.nodeId; - msgObj.isDisEnableDraw = false; - if (_param && _param.isDisEnableDraw == true) { - msgObj.isDisEnableDraw = true; - } - this.sendConferMsg({ - "to": _param.nodeId, - "message": JSON.stringify(msgObj), - "actionType": ApeConsts.CLASS_ACTION_DRAW_STATUS_CHANGE - }); + //控制用户的举手状态 + if (!_param || !_param.nodeId) { + loger.log('控制画笔的使用状态->失败->参数错误', _param); + return; + } + let msgObj = {}; + msgObj.nodeId = _param.nodeId; + msgObj.isDisEnableDraw = false; + if (_param && _param.isDisEnableDraw == true) { + msgObj.isDisEnableDraw = true; } + this.sendConferMsg({ + "to": _param.nodeId, + "message": JSON.stringify(msgObj), + "actionType": ApeConsts.CLASS_ACTION_DRAW_STATUS_CHANGE + }); + } //控制举手状态 controlHandUpStatus(_param) { @@ -589,7 +593,7 @@ class ConferApe extends Ape { } loger.log('切换文档-媒体-屏幕模块切换->', _param); //如果是host身份 - if (GlobalConfig.isHost) { + if (GlobalConfig.isHost||GlobalConfig.isAssistant||GlobalConfig.isPresenter) { if (_param) { GlobalConfig.currentSceneTableId = parseInt(_param.currentSceneTableId) || 0; //当前场景显示的模块 0=文档模块、1=屏幕共享、2=媒体共享 //保存数据到Sass @@ -604,7 +608,7 @@ class ConferApe extends Ape { //更新课堂信息 sendUpdaterClassStatusInfo(_param) { //{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流 - //loger.log('发送更新课堂信息->'); + //loger.log('发送更新课堂信息->'); if (_param == null || EngineUtils.isEmptyObject(_param)) { loger.log('发送更新课堂信息->参数错误'); this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); @@ -651,32 +655,18 @@ class ConferApe extends Ape { /////收到消息处理///////////////////////////////////////////////////////////////////////////////// //加入channel成功 onJoinChannelHandlerSuccess() { - if(GlobalConfig.isRecordPlayBack){ - loger.log('课堂模块初始完成->当前是录制回放:'+ GlobalConfig.classStatus); + if (GlobalConfig.isRecordPlayBack) { + loger.log('课堂模块初始完成->当前是录制回放:' + GlobalConfig.classStatus); return; } - loger.log('课堂模块初始完成->当前课堂状态:'+ GlobalConfig.classStatus,"recordStatus:"+GlobalConfig.recordStatus); + loger.log('课堂模块初始完成->当前课堂状态:' + GlobalConfig.classStatus, "recordStatus:" + GlobalConfig.recordStatus); this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1); this.startTimerCounter(); this.startClass(); clearTimeout(this.startRecordTimer); - this.startRecordTimer=setTimeout(()=>{ - this.startRecord(); - },2000); - - /* //如果当前课堂正在进行中,开启计时器 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { - //开始计时 - this.startTimerCounter(); + this.startRecordTimer = setTimeout(()=> { this.startRecord(); - } else if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT && - GlobalConfig.isHost && GlobalConfig.isAutoStartClass && !GlobalConfig.isRecordPlayBack) { - //自动开始上课的4个条件 - //1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课 - loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack); - this.startClass(); - }*/ - + }, 2000); } //开启计时器 @@ -707,17 +697,17 @@ class ConferApe extends Ape { //向应用层更新当前课堂进行的时间长度 (秒) this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp}); - /* 录制消息已经更新了数据,这个课堂内的就不需要再更新,间隔太短了频率太高 - //以一定的时间间隔同步课堂内所有人的累积上课时间 - if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { - //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 - if (this.checkHasRecordControl()) { - //保存数据到Sass - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); - //同步消息给其他人 - this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false}); - } - }*/ + /* 录制消息已经更新了数据,这个课堂内的就不需要再更新,间隔太短了频率太高 + //以一定的时间间隔同步课堂内所有人的累积上课时间 + if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { + //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 + if (this.checkHasRecordControl()) { + //保存数据到Sass + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); + //同步消息给其他人 + this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false}); + } + }*/ //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理) if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) { @@ -730,7 +720,6 @@ class ConferApe extends Ape { } } - //更新录制进行时间 GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1; if (this.checkHasRecordControl()) { @@ -745,83 +734,6 @@ class ConferApe extends Ape { this.sendUpdaterClassStatusInfo({"actionType": GlobalConfig.classStatus, isStopAllPublishMedia: false}); } } - /* if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { - GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时 - //老师身份的时候要记录录制的时间 - if (GlobalConfig.isHost||this.rosterLen<=1) { - GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1; - } - //向应用层更新当前课堂进行的时间长度 (秒) - this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp}); - - //以一定的时间间隔同步课堂内所有人的累积上课时间 - if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { - //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 - if (GlobalConfig.isHost||this.rosterLen<=1) { - //保存数据到Sass - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); - //同步消息给其他人 - this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false}); - } - } - - //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理) - if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) { - //MS推流选点 - this._emit(MessageTypes.SWITCH_MS_IP); - //MS拉流选点 - this._emit(MessageTypes.SWITCH_RTMP_PULL_IP); - //HLS拉流选点 - this._emit(MessageTypes.SWITCH_HLS_IP); - } - }else { - //课堂暂停或未开始的情况下,如果已经开始录制,需要更新录制的时间 - if (GlobalConfig.isHost||this.rosterLen<=1) { - GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1; - //以一定的时间间隔同步课堂内所有人的累积上课时间 - if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { - //保存数据到Sass - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); - //同步消息给其他人 - this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false}); - } - } - }*/ - - /* //如果还没开始或已经暂停、关闭,不做计时处理 - if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) { - loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus); - return; - } - GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时 - - //老师身份的时候要记录录制的时间 - if (GlobalConfig.isHost) { - GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1; - } - //向应用层更新当前课堂进行的时间长度 (秒) - this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp}); - - //以一定的时间间隔同步课堂内所有人的累积上课时间 - if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) { - //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器 - if (GlobalConfig.isHost) { - //保存数据到Sass - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); - //同步消息给其他人 - this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false}); - } - } - - //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理) - if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) { - //MS推流选点 - this._emit(MessageTypes.SWITCH_MS_IP); - //MS拉流选点 - this._emit(MessageTypes.SWITCH_RTMP_PULL_IP); - //HLS拉流选点 - this._emit(MessageTypes.SWITCH_HLS_IP); - }*/ } tableUpdateHandler(owner, itemIdx, itemData) { @@ -831,7 +743,7 @@ class ConferApe extends Ape { //{"itemIdx":720899,"from":976168842,"owner":976168842,"actionType":null,"classStatusInfo":{"nodeId":976168842,"userId":"user_979813","userName":"user_979813","siteId":"markettest","classId":889112694,"className":"ly828-1v1","classType":1,"classStatus":1,"classStartTime":"2017-8-28-16-33-18","classStopTime":"2017-8-29-11-9-28","classTimestamp":1930,"classBeginTime":"2017-08-28 16:00:00","classEndTime":"2017-08-31 18:00:00","recordStatus":false,"recordTimestamp":2825,"recordFileName":"markettest/20170828/889112694_20170828.rec","recordDownloadUrl":"","serverTimestamp":1503976246,"activeDocId":976170739,"activeDocCurPage":1,"isStopAllPublishMedia":false,"currentSceneTableId":0,"silence":false,"silenceUsers":"{}","isEnableDraw":true}} //处理课堂更新的信息 if (model && model.classStatusInfo) { - // loger.log("课堂更新->",model.classStatusInfo); + // loger.log("课堂更新->",model.classStatusInfo); try { model.classStatusInfo.silenceUsers = JSON.parse(model.classStatusInfo.silenceUsers); } catch (err) { @@ -843,7 +755,7 @@ class ConferApe extends Ape { this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH); } } - // loger.log('课堂数据更新->'); + // loger.log('课堂数据更新->'); //通知应用层更新课堂状态 let classInfo = GlobalConfig.classStatusInfo; //loger.log('通知应用层更新课堂状态->CLASS_UPTATE_STATUS') @@ -855,14 +767,6 @@ class ConferApe extends Ape { this.stopTimerCounter(); return; } - - /* if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { - //如果课堂在进行中,开始计时器 - this.startTimerCounter(); - } else { - //停止计时 - this.stopTimerCounter(); - }*/ } catch (err) { loger.warn('课堂更新->error', err.message); } @@ -883,9 +787,9 @@ class ConferApe extends Ape { //关闭之前停止所有推流 this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH); //收到课堂关闭,所有人都退出,执行自己关闭的流程 - setTimeout(()=>{ + setTimeout(()=> { this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1}); - },2000); + }, 2000); break; case ApeConsts.STOP_ALL_PUBLISH: this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH); @@ -1010,12 +914,12 @@ class ConferApe extends Ape { //{"initiator":564398684,"record":true,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"}//开启成功 //{"initiator":564398684,"record":false,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"} //停止成功 loger.warn("录制回放控制操作成功->", conferRecordSendPdu); - if (conferRecordSendPdu ){ - if(conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") { + if (conferRecordSendPdu) { + if (conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") { //每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件 loger.warn("MCU已经开启录制"); this._emit(MessageTypes.CLASS_RECORD_SUCCESS); - }else{ + } else { //停止录制成功 loger.warn("MCU已经停止录制"); } @@ -1045,18 +949,16 @@ class ConferApe extends Ape { // 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中) this.rosterLen = Object.keys(this.rosters).length; GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数 - /* if (this.rosterLen <=1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { - loger.warn("当前课堂没有老师->暂停课堂"); - this.pauseClass({isForce: true}); - //this.stopRecord(true); - }*/ + /* if (this.rosterLen <=1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) { + loger.warn("当前课堂没有老师->暂停课堂"); + this.pauseClass({isForce: true}); + //this.stopRecord(true); + }*/ //处理用户信息 this.unPackRosterInfo(nodeId, nodeData); return; } - //loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]); - //新加入的人员不是自己 //1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉 //2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大 @@ -1069,35 +971,15 @@ class ConferApe extends Ape { deviceType: nodeData.deviceType } if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) { - loger.warn("相同身份的人进入->自己被踢出->进入的人员信息","userName:"+ nodeData.name,"userId:"+ nodeData.userId,"userRole:"+ nodeData.userRole,"nodeId:"+ nodeData.nodeId,"deviceType:"+ nodeData.deviceType); + loger.warn("相同身份的人进入->自己被踢出->进入的人员信息", "userName:" + nodeData.name, "userId:" + nodeData.userId, "userRole:" + nodeData.userRole, "nodeId:" + nodeData.nodeId, "deviceType:" + nodeData.deviceType); this.kickOutRoster(newUserInfo); return; } else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") { loger.warn("异地登陆->userId->", GlobalConfig.userId); - this._emit(MessageTypes.MCU_ERROR, {type:MessageTypes.ERR_CLASS_REMOTE_LANDING, data:newUserInfo}); + this._emit(MessageTypes.MCU_ERROR, {type: MessageTypes.ERR_CLASS_REMOTE_LANDING, data: newUserInfo}); this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1}); } } - /*if (parseInt(nodeId) > GlobalConfig.nodeId) { - if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) { - this.kickOutRoster(); - return; - } else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) { - this.kickOutRoster(); - return; - } else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) { - this.kickOutRoster(); - return; - } else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) { - this.kickOutRoster(); - return; - }else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){ - loger.log("异地登陆->userId->",GlobalConfig.userId); - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING); - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1}); - } - }*/ - //处理用户信息 this.unPackRosterInfo(nodeId, nodeData); } @@ -1106,7 +988,7 @@ class ConferApe extends Ape { unPackRosterInfo(nodeId, nodeData) { let rosterExists = this.rosters[nodeId]; this.rosters[nodeId] = nodeData; - GlobalConfig.rosters=this.rosters; + GlobalConfig.rosters = this.rosters; let userDataObj = null; try { userDataObj = pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData); @@ -1133,7 +1015,7 @@ class ConferApe extends Ape { this.rosterLen = Object.keys(this.rosters).length; GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数 newNodeData.rosterLen = this.rosterLen; - if(nodeId!=GlobalConfig.nodeId){ + if (nodeId != GlobalConfig.nodeId) { loger.log("人员更新信息->", newNodeData); } this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData}); @@ -1149,7 +1031,7 @@ class ConferApe extends Ape { userRole:nodeData.userRole, deviceType: nodeData.deviceType }*/ - this._emit(MessageTypes.MCU_ERROR, {type:MessageTypes.ERR_CLASS_KICK_OUT,data: _newUserInfo}); + this._emit(MessageTypes.MCU_ERROR, {type: MessageTypes.ERR_CLASS_KICK_OUT, data: _newUserInfo}); this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1}); } @@ -1181,7 +1063,7 @@ class ConferApe extends Ape { loger.log(nodeId, "->离开课堂->身份->", user.userRole); } delete this.rosters[nodeId]; - GlobalConfig.rosters=this.rosters; + GlobalConfig.rosters = this.rosters; this.rosterLen = Object.keys(this.rosters).length; GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数 @@ -1244,6 +1126,7 @@ class ConferApe extends Ape { classStatusInfo.silence = GlobalConfig.silence; classStatusInfo.silenceUsers = JSON.stringify(GlobalConfig.silenceUsers); classStatusInfo.isEnableDraw = GlobalConfig.isEnableDraw; + classStatusInfo.videoScale=GlobalConfig.videoScale||1; //loger.log("classStatusInfo--->", classStatusInfo); /* @@ -1278,11 +1161,12 @@ class ConferApe extends Ape { } return null; } - stopApe(){ - this.rosters={}; - this.rosterLen=0; - GlobalConfig.rosterNumber=this.rosterLen; - GlobalConfig.rosters=this.rosters; + + stopApe() { + this.rosters = {}; + this.rosterLen = 0; + GlobalConfig.rosterNumber = this.rosterLen; + GlobalConfig.rosters = this.rosters; } } diff --git a/src/apes/WebRtcApe.js b/src/apes/WebRtcApe.js index 54db159..c114089 100644 --- a/src/apes/WebRtcApe.js +++ b/src/apes/WebRtcApe.js @@ -44,6 +44,8 @@ class WebRtcApe extends Emiter { this.isPublish = false;//当前是否正在推流 + this.videoScale=1;//视图的缩放比例,默认为1; + this.normalRemoteViewId = ""; this.normalRemoteStyle = ""; this.normalRemoteVideoWidth = 320; @@ -64,6 +66,12 @@ class WebRtcApe extends Emiter { this.invisibleVideoWidth = 320; this.invisibleVideoHeight = 240; this.xdyRemote = "xdy_remote"; + + this.localWebRtcVideoClass='localWebRtcVideoClass';//本地视图统一的class名称 + this.invisibleWebRtcVideoClass='invisibleWebRtcVideoClass'; + this.normalWebRtcVideoClass='normalWebRtcVideoClass'; + this.hostWebRtcVideoClass='hostWebRtcVideoClass' + //webRtc sdk this.client = AgoraRTC.createClient({mode: this.mode}); @@ -184,17 +192,17 @@ class WebRtcApe extends Emiter { if (userRole == ApeConsts.invisible) { //把远程视频添加到监课列表 loger.log("获取远程视频流成功->监课:" + userName + "->" + uid, new Date().getTime()); - let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.invisibleVideoWidth}px;height:${this.invisibleVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; + let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.invisibleWebRtcVideoClass}" style="width:${this.invisibleVideoWidth*this.videoScale}px;height:${this.invisibleVideoHeight*this.videoScale}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; $(this.invisibleViewId).append(viewDiv); } else if (userRole == ApeConsts.host||userRole == ApeConsts.assistant||userRole == ApeConsts.presenter) { //把远程视图添加到老师列表 loger.log("获取远程视频流成功->userRole:"+userRole+":" + userName + "->" + uid, new Date().getTime()); - let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; + let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.hostWebRtcVideoClass}" style="width:${this.hostRemoteVideoWidth*this.videoScale}px;height:${this.hostRemoteVideoHeight*this.videoScale}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; $(this.hostRemoteViewId).append(viewDiv); } else { //把视图添加到学生列表 loger.log("获取远程视频流成功->学生:" + userName + "->" + uid, new Date().getTime()); - let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.normalRemoteVideoWidth}px;height:${this.normalRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; + let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.normalWebRtcVideoClass}" style="width:${this.normalRemoteVideoWidth*this.videoScale}px;height:${this.normalRemoteVideoHeight*this.videoScale}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`; $(this.normalRemoteViewId).append(viewDiv); } //播放视频,隐藏控制条 @@ -370,8 +378,9 @@ class WebRtcApe extends Emiter { let viewName = 'localVideoBox_' + this.uid; let videoBox = document.createElement("div"); videoBox.id = viewName; - videoBox.style.width = this.localVideoWidth + 'px'; - videoBox.style.height = this.localVideoHeight + 'px'; + videoBox.className=this.localWebRtcVideoClass; + videoBox.style.width = (this.localVideoWidth*this.videoScale) + 'px'; + videoBox.style.height = (this.localVideoHeight*this.videoScale) + 'px'; videoBox.style.float = 'left'; videoBox.style.marginRight = "1px"; videoBox.style.pointerEvents = 'none'; @@ -439,6 +448,50 @@ class WebRtcApe extends Emiter { } /* + * 更新所有视频的尺寸大小 + * */ + updateAllVideoSize(){ + $("."+this.localWebRtcVideoClass).css("width",this.localVideoWidth*this.videoScale); + $("."+this.localWebRtcVideoClass).css("height",this.localVideoHeight*this.videoScale); + + $("."+this.hostWebRtcVideoClass).css("width",this.hostRemoteVideoWidth*this.videoScale); + $("."+this.hostWebRtcVideoClass).css("height",this.hostRemoteVideoHeight*this.videoScale); + + $("."+this.normalWebRtcVideoClass).css("width",this.normalRemoteVideoWidth*this.videoScale); + $("."+this.normalWebRtcVideoClass).css("height",this.normalRemoteVideoHeight*this.videoScale); + + //监课的不需要设置 + //$("."+this.invisibleWebRtcVideoClass).css("width",this.localVideoWidth); + //$("."+this.invisibleWebRtcVideoClass).css("height",this.localVideoHeight); + } + + /* + * 设置rtc视频的属性 + * */ + changeRtcVideoConfig(_params){ + //{videoScale:1} + if(!_params){ + return; + } + let scale=parseInt(_params.videoScale)||1;//最小值只能为1,这个是按倍数缩放视频 + if(this.videoScale==scale){ + return; + } + this.videoScale=scale; + loger.log("更新视频视图大小->videoScale:"+this.videoScale); + /* this.localVideoWidth=this.localVideoWidth*this.videoScale; + this.localVideoHeight=this.localVideoHeight*this.videoScale; + + this.hostRemoteVideoWidth=this.hostRemoteVideoWidth*this.videoScale; + this.hostRemoteVideoHeight=this.hostRemoteVideoHeight*this.videoScale; + + this.normalRemoteVideoWidth=this.normalRemoteVideoWidth*this.videoScale; + this.normalRemoteVideoHeight=this.normalRemoteVideoHeight*this.videoScale;*/ + this.updateAllVideoSize(); + + } + + /* * 设置本地回显视图 * */ setLoaclView(_params) { @@ -448,6 +501,9 @@ class WebRtcApe extends Emiter { this.localVideoWidth = parseInt(_params.width) || 320; this.localVideoHeight = parseInt(_params.height) || 240; this.nameDisplay = _params.nameDisplay || "block"; + + this.localVideoWidth=this.localVideoWidth; + this.localVideoHeight=this.localVideoHeight; } /* @@ -459,6 +515,8 @@ class WebRtcApe extends Emiter { this.hostRemoteStyle = _params.styleStr || ""; this.hostRemoteVideoWidth = parseInt(_params.width) || 320; this.hostRemoteVideoHeight = parseInt(_params.height) || 240; + this.hostRemoteVideoWidth=this.hostRemoteVideoWidth; + this.hostRemoteVideoHeight=this.hostRemoteVideoHeight; } /* @@ -470,6 +528,9 @@ class WebRtcApe extends Emiter { this.normalRemoteStyle = _params.styleStr || ""; this.normalRemoteVideoWidth = parseInt(_params.width) || 320; this.normalRemoteVideoHeight = parseInt(_params.height) || 240; + + this.normalRemoteVideoWidth=this.normalRemoteVideoWidth; + this.normalRemoteVideoHeight=this.normalRemoteVideoHeight; } /* diff --git a/src/pdus/pro.js b/src/pdus/pro.js index 34b8a91..55dcc4a 100644 --- a/src/pdus/pro.js +++ b/src/pdus/pro.js @@ -1045,6 +1045,7 @@ message RCClassStatusInfoPdu { optional bool silence=24;//课堂禁言 optional string silenceUsers=25;//课堂用户禁言状态列表 optional bool isEnableDraw=26;//课堂用户是否开启绘制权限 + optional uint32 videoScale=27;//视频显示的缩放倍数 } message RCConferenceRecordRequestPdu { -- libgit2 0.24.0