diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js index 5a0ad7b..6a7fcd3 100644 --- a/src/EngineEntrance.js +++ b/src/EngineEntrance.js @@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter { super(); this.lastClassActiveTime=0;//最后一次课堂激活的时间戳 //sdk 信息 - GlobalConfig.sdkVersion = "v2.34.16.20171128"; + GlobalConfig.sdkVersion = "v2.35.11.20171130"; loger.warn("sdkVersion:" + GlobalConfig.sdkVersion); console.log("sdkVersion:" + GlobalConfig.sdkVersion); //设置 @@ -607,6 +607,9 @@ export default class MessageEntrance extends Emiter { this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM); return; } + //添加日志捕获 + LogManager.catchConsole(); + loger.warn('=====================STEP1======================='); loger.log('初始化课堂->', _param); //保存参数 @@ -1297,7 +1300,7 @@ export default class MessageEntrance extends Emiter { LogManager.userName = GlobalConfig.userName;//用户名称 LogManager.logUrl = GlobalConfig.logUrl;//日志服务器地址 //http://log.3mang.com LogManager.platform = GlobalConfig.platform; - loger.log('加入课堂成功->'); + loger.log('加入课堂成功->classType:'+GlobalConfig.classType); loger.log(joinClassSuccessCallBackData); //加入课堂成功,广播消息 @@ -1325,7 +1328,8 @@ export default class MessageEntrance extends Emiter { channelId: GlobalConfig.channelId, channelKey: GlobalConfig.channelKey, uid: GlobalConfig.userUid, - info: "" + GlobalConfig.userRole + info: "" + GlobalConfig.userRole, + immediatePublish:false }); }, 1600); } @@ -3147,6 +3151,9 @@ export default class MessageEntrance extends Emiter { let m3u8Stream = _video_ape.getPlayVideoPath({"type": "m3u8", "streamId": streamId}); let rtmpStream = _video_ape.getPlayVideoPath({"type": "rtmp", "streamId": streamId}); _webRtc.setRtmpM3u8Path({m3u8Url: m3u8Stream.playUrl, rtmpUrl: rtmpStream.playUrl}); + }else { + //获取频道失败,不能自动推流 + isPublish=false; } } clearTimeout(this.joinChannelTimer); @@ -3159,7 +3166,7 @@ export default class MessageEntrance extends Emiter { info: "" + GlobalConfig.userRole, immediatePublish:isPublish }); - }, 1000); + }, 1600); } } diff --git a/src/EngineUtils.js b/src/EngineUtils.js index a621f4a..0df60c8 100644 --- a/src/EngineUtils.js +++ b/src/EngineUtils.js @@ -45,6 +45,22 @@ class EngineUtils { return randNumStr; } + /* + * 生成随机数 randomLen随机数范围; minLen 随机数的最小长度 + * */ + static getRandomInt(randomLen, minLen) { + let randNumStr = ""; + randNumStr=""+parseInt(Math.random() * randomLen); + let distance=minLen-randNumStr.length; + if(distance>0){ + for (let i = 0; i < distance; i++) { + randNumStr="0"+randNumStr; + } + } + return randNumStr; + } + + //生成时间戳后9位 保证唯一 static creatSoleNumberFromTimestamp() { let time = new Date().getTime(); diff --git a/src/EverSocket.js b/src/EverSocket.js index 6b80c8a..e3e16a2 100644 --- a/src/EverSocket.js +++ b/src/EverSocket.js @@ -98,7 +98,7 @@ class EverSocket extends Emiter { * */ send2mcu(len,type){ this.sendToMcuList.push(""+len+":"+type); - if(this.sendToMcuList.length>=100){ + if(this.sendToMcuList.length>=200){ loger.log("发送到MCU数据统计->",this.sendToMcuList); this.sendToMcuList=[]; } @@ -111,7 +111,7 @@ class EverSocket extends Emiter { * */ mcu2client(len,type){ this.receiveFromMcuList.push(""+len+":"+type); - if(this.receiveFromMcuList.length>100){ + if(this.receiveFromMcuList.length>200){ loger.log("收到MCU数据统计->",this.receiveFromMcuList); this.receiveFromMcuList=[]; } @@ -241,15 +241,15 @@ class EverSocket extends Emiter { let len=bufferData.byteLength; if (len> 0) { this._emit(EverSocket.MESSAGE, bufferData); - this.mcu2client(len,"消息"); + this.mcu2client(len,"msg"); }else { - this.mcu2client(0,"回应"); + this.mcu2client(0,"pong"); } } _sendPingHandler() { if (this._connected) { - this.send2mcu(0,"心跳"); + this.send2mcu(0,"ping"); this.websocket.send(new ArrayBuffer); } else { this._reConnection(); diff --git a/src/LogManager.js b/src/LogManager.js index 2aa9b5c..54cc472 100644 --- a/src/LogManager.js +++ b/src/LogManager.js @@ -2,12 +2,58 @@ * * LOG 信息管理(上传和输出) * */ - +const WEBRTC_LOG="WebRtcLog-" class LogManager { constructor() { } - + //捕获日志输出 + static catchConsole(){ + console.oldLog = console.log; + console.log("捕获日志输出"); + console.log = (...args)=> { + if(args[0]=="INFO:"||args[0]=="DEBUG:"||args[0]=="WARNING:"||args[0]=="ERROR:") { + LogManager.addLog(LogManager.LOG,WEBRTC_LOG+JSON.stringify(args)); + }else { + if(!args){ + return; + } + if(args.length==1){ + console.oldLog(args[0]); + }else{ + console.oldLog(args); + } + } + } + console.warn = (...args)=> { + if(args[0]=="INFO:"||args[0]=="DEBUG:"||args[0]=="WARNING:"||args[0]=="ERROR:") { + LogManager.addLog(LogManager.LOG,WEBRTC_LOG+JSON.stringify(args)); + }else { + if(!args){ + return; + } + if(args.length==1){ + console.oldLog(args[0]); + }else{ + console.oldLog(args); + } + } + } + console.error = (...args)=> { + if(args[0]=="INFO:"||args[0]=="DEBUG:"||args[0]=="WARNING:"||args[0]=="ERROR:") { + LogManager.addLog(LogManager.LOG,WEBRTC_LOG+JSON.stringify(args)); + }else { + if(!args){ + return; + } + if(args.length==1){ + console.oldLog(args[0]); + }else{ + console.oldLog(args); + } + } + } + } /* * 添加需要上报的日志信息到队列中 * _type diff --git a/src/SystemConfig.js b/src/SystemConfig.js index 3b24189..c6f9729 100644 --- a/src/SystemConfig.js +++ b/src/SystemConfig.js @@ -243,7 +243,7 @@ class SystemConfig { var isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1; if (isWin7) return "Win7"; } - return "other"; + return String(navigator.platform)||String(sUserAgent); } } export default SystemConfig; diff --git a/src/apes/MediaModule.js b/src/apes/MediaModule.js index 795730f..0dca66d 100644 --- a/src/apes/MediaModule.js +++ b/src/apes/MediaModule.js @@ -353,14 +353,16 @@ class MediaModule { let counter = 0; for (let key in this.mediaChannels) { let item = this.mediaChannels[key]; - if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) { - loger.log("已获取空闲的通道->channelId:" + item.channelId); - return item.channelId; + if (item ) { + if(item.status == ApeConsts.CHANNEL_STATUS_RELEASED||(item.userId ==GlobalConfig.userId&&item.userRole==GlobalConfig.userRole)){ + loger.log("已获取空闲的通道->channelId:" + item.channelId); + return item.channelId; + } } counter++; } loger.log("获取空闲的通道", "mediaChannels", this.mediaChannels, "counter:", counter); - //loger.log(this.mediaChannels); + if(this.maxMediaChannel>0){ if (counter < this.maxMediaChannel) { return this.MEDIA_OBJ_TABLE_ID + (counter); diff --git a/src/apes/VideoApe.js b/src/apes/VideoApe.js index b868fd7..bd486ab 100644 --- a/src/apes/VideoApe.js +++ b/src/apes/VideoApe.js @@ -51,13 +51,13 @@ class VideoApe extends Ape { /////////////发送数据操作//////////////////////////////////////////// //获取播流地址 getPlayVideoPath(_param) { - loger.log('getPlayVideoPath'); + //loger.log('getPlayVideoPath'); return this.mediaModule.getMediaPlayPath(_param); } //获取推流地址 getPublishVideoPath(_param) { - loger.log('获取推流地址->'); + //loger.log('获取推流地址->'); if (!this.mcu.connected) { loger.warn(GlobalConfig.getCurrentStatus()); return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; @@ -75,7 +75,9 @@ class VideoApe extends Ape { let allChannels = MediaModule.allMediaChannelsList; for (let i in allChannels) { let channel = allChannels[i]; - if (channel && channel.status == ApeConsts.CHANNEL_STATUS_OPENING && channel.userRole != ApeConsts.invisible) { + if (channel && channel.status == ApeConsts.CHANNEL_STATUS_OPENING && + channel.userRole != ApeConsts.invisible&& + channel.userId!=GlobalConfig.userId) { //正在开启的才计数,监课开启的不计算在内 openChannel++; } @@ -177,6 +179,10 @@ class VideoApe extends Ape { } } + //每次推流的时候重置状态 + GlobalConfig.videoEnabled=true; + GlobalConfig.audioEnabled=true; + let channelInfo = this.mediaModule.getDefaultChannelInfo(); channelInfo.owner = GlobalConfig.nodeId; channelInfo.status = ApeConsts.CHANNEL_STATUS_OPENING; @@ -748,6 +754,8 @@ class VideoApe extends Ape { if (unpackChannelInfo.status == ApeConsts.CHANNEL_STATUS_OPENING) { GlobalConfig.openCamera = EngineUtils.creatTimestamp(); GlobalConfig.openMicrophones = GlobalConfig.openCamera; + GlobalConfig.videoEnabled=true; + GlobalConfig.audioEnabled=true; } else { GlobalConfig.openCamera = 0; GlobalConfig.openMicrophones = 0; diff --git a/src/apes/WebRtcApe.js b/src/apes/WebRtcApe.js index 4091a56..0edf83c 100644 --- a/src/apes/WebRtcApe.js +++ b/src/apes/WebRtcApe.js @@ -59,13 +59,15 @@ class WebRtcApe extends Emiter { //240P 20 320x240 15 200 //360P_8 37 480x360 30 490 this.videoResolution = "240P"; - this.isOpenVideo = true; + this.isOpenVideo = true;//是否开启摄像头,默认为开启,如果获取不到麦克风的时候会设置为false this.firstPublishSuccess = false;//记录加入频道成功之后是否推流成功过,离开频道之后需要设置为false this.isPublish = false;//当前是否正在推流 this.videoScale = 1;//视图的缩放比例,默认为1; + this.isEnableVideo=true; + this.isEnableAudio=true; this.normalRemoteViewId = ""; this.normalRemoteStyle = ""; @@ -172,10 +174,6 @@ class WebRtcApe extends Emiter { }); this.client.on('stream-added', (evt)=> { let stream = evt.stream; - /* loger.log("添加一个远程视频流: " + stream.getId(),new Date().getTime()); - this.client.subscribe(stream, (err)=> { - loger.log("添加一个远程视频流->failed", err); - });*/ this.reAddRemoteStream(stream); }); this.client.on('stream-subscribed', (evt)=> { @@ -189,7 +187,6 @@ class WebRtcApe extends Emiter { $('#' + this.xdyRemote + stream.getId()).remove(); loger.log("远程视频流已经断开:" + stream.getId()); } - }); this.client.on('peer-leave', (evt)=> { @@ -266,6 +263,9 @@ class WebRtcApe extends Emiter { 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;">${nameDiv + videoAndAudioBox}</div>`; $(this.normalRemoteViewId).append(viewDiv); } + let audioPlayIcoBox=`<div class="audioPlayIcoBox " id=${"audioPlayIcoBox" + uid} ></div>`; + $("#" + this.xdyRemote + uid).append(audioPlayIcoBox); + $("#" + this.videoMutedIdName + uid).off("click", this._clickVideoMuted.bind(this)); $("#" + this.audioMutedIdName + uid).off("click", this._clickAudioMuted.bind(this)); @@ -401,6 +401,10 @@ class WebRtcApe extends Emiter { //一般只有在刷新重进频道的时候会用到 this.immediatePublish = _params.immediatePublish || false; + this.isEnableVideo=true; + this.isEnableAudio=true; + GlobalConfig.videoEnabled=true; + GlobalConfig.audioEnabled=true; //根据不同身份设置不同的分辨率 if (GlobalConfig.isTeachOrAssistant) { if (GlobalConfig.maxMediaChannels == 1) { @@ -474,9 +478,15 @@ class WebRtcApe extends Emiter { }); if (this.isOpenVideo) { - //设置分辨率 + loger.log("摄像头已经获取->设置本地视频分辨率:"+this.videoResolution); + //设置视频分辨率 this.localStream.setVideoProfile(this.videoResolution); + }else{ + //没有视频,设置为最低 + loger.log("摄像头没有获取到->设置本地流分辨率:120P"); + this.localStream.setVideoProfile("120P"); } + } leaveChannel() { @@ -502,9 +512,7 @@ class WebRtcApe extends Emiter { //loger.log("立即删除停止推流人员的视图"); $('#' + this.xdyRemote + _data.nodeId).remove(); } catch (err) { - } - } /* @@ -578,6 +586,8 @@ class WebRtcApe extends Emiter { //自己的视图往前添加 $(this.localViewId).prepend(videoBox); $("#" + viewName).css("transform", 'rotateY(180deg)'); + let audioPlayIcoBox=`<div class="audioPlayIcoBox " id=${"audioPlayIcoBox" + this.uid} ></div>`; + $("#" + viewName).append(audioPlayIcoBox); //显示自己的名字 let user = GlobalConfig.getUserInfoFromeNodeId(this.uid); @@ -857,6 +867,11 @@ class WebRtcApe extends Emiter { } } } + if( GlobalConfig.cameras&& GlobalConfig.cameras.length<1){ + this.isOpenVideo=false; + }else { + this.isOpenVideo=true; + } let _deviceData = {cameras: GlobalConfig.cameras, microphones: GlobalConfig.microphones}; if (_callback) { _callback(_deviceData); @@ -922,27 +937,18 @@ class WebRtcApe extends Emiter { if (_data.nodeId != GlobalConfig.nodeId) { //不是自己的只设置状态显示即可 //音频 - if (_data.audio == false) { - //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOn"); - //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOff"); - this.setUidAudioEnabledStatus(_data.nodeId,false); - } else { - //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOff"); - //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOn"); - this.setUidAudioEnabledStatus(_data.nodeId,true); - } + this.setUidAudioEnabledStatus(_data.nodeId,Boolean(_data.audio)); //视频 - if (_data.video == false) { - //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOn"); - //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOff"); - this.setUidVideoEnabledStatus(_data.nodeId,false); - } else { - //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOff"); - //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOn"); - this.setUidVideoEnabledStatus(_data.nodeId,true); - } + this.setUidVideoEnabledStatus(_data.nodeId,Boolean(_data.video)); } else { //控制自己的音频 + if(this.isEnableVideo==_data.video&&this.isEnableAudio==_data.audio){ + return; + } + //记录自己当前的音视频禁用状态 + this.isEnableVideo=_data.video; + this.isEnableAudio=_data.audio; + if (_data.audio == false) { this.disableAudio(_data.nodeId); } else { @@ -966,11 +972,9 @@ class WebRtcApe extends Emiter { * 开启禁音 * */ disableAudio(uid) { - loger.log("开启禁音:" + uid); if (parseInt(uid) == GlobalConfig.nodeId) { + loger.log("开启禁音:" + uid); if (this.localStream) { - //$("#" + this.audioMutedIdName + uid).removeClass("microphoneOn"); - //$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff"); this.setUidAudioEnabledStatus(uid,false); this.localStream.disableAudio(); } @@ -981,12 +985,10 @@ class WebRtcApe extends Emiter { * 开启音频 * */ enableAudio(uid) { - loger.log("开启音频:" + uid); if (parseInt(uid) == GlobalConfig.nodeId) { + loger.log("开启音频:" + uid); if (this.localStream) { this.localStream.enableAudio(); - //$("#" + this.audioMutedIdName + _uid).removeClass("microphoneOff"); - //$("#" + this.audioMutedIdName + _uid).addClass("audioAndVideMuted microphoneOn"); this.setUidAudioEnabledStatus(uid,true); } } @@ -1015,11 +1017,9 @@ class WebRtcApe extends Emiter { * 禁用摄像头 * */ disableVideo(uid) { - loger.log("禁用摄像头:" + uid); if (parseInt(uid) == GlobalConfig.nodeId) { + loger.log("禁用摄像头:" + uid); if (this.localStream) { - //$("#" + this.audioMutedIdName + uid).removeClass("microphoneOn"); - //$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff"); this.setUidVideoEnabledStatus(uid,false); this.localStream.disableVideo(); } @@ -1030,12 +1030,10 @@ class WebRtcApe extends Emiter { * 开启摄像头 * */ enableVideo(uid) { - loger.log("开启摄像头:" + uid); if (parseInt(uid) == GlobalConfig.nodeId) { if (this.localStream) { + loger.log("开启摄像头:" + uid); this.localStream.enableVideo(); - //$("#" + this.audioMutedIdName + _uid).removeClass("microphoneOff"); - //$("#" + this.audioMutedIdName + _uid).addClass("audioAndVideMuted microphoneOn"); this.setUidVideoEnabledStatus(uid,true); } } @@ -1053,11 +1051,13 @@ class WebRtcApe extends Emiter { $("#" + this.videoMutedIdName + uid).removeClass("cameraOff"); $("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOn"); $("#" + this.videoMutedIdName + uid).attr("title",this.closeCameraTitle); + $("#audioPlayIcoBox" + uid).hide(); }else{ //禁用 $("#" + this.videoMutedIdName + uid).removeClass("cameraOn"); $("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOff"); $("#" + this.videoMutedIdName + uid).attr("title",this.openCameraTitle); + $("#audioPlayIcoBox" + uid).show(); } } diff --git a/src/assets/css/mcuStyle.css b/src/assets/css/mcuStyle.css index e46a00a..8f59d6f 100644 --- a/src/assets/css/mcuStyle.css +++ b/src/assets/css/mcuStyle.css @@ -42,4 +42,18 @@ } .cameraOn { background-image: url(../../assets/img/cameraOn_22.png); +} + +/*只开启音频时的界面图标*/ +.audioPlayIcoBox{ + display: none; + position: absolute; + pointer-events: none; + width: 100%; + height: 100%; + background-position: center; + z-index: 1; + /*background-size: 100%;*/ + background-repeat: no-repeat; + background-image: url(../../assets/img/audioPlayIco.png); } \ No newline at end of file diff --git a/src/assets/img/audioPlayIco.png b/src/assets/img/audioPlayIco.png new file mode 100644 index 0000000..a57bdea Binary files /dev/null and b/src/assets/img/audioPlayIco.png differ diff --git a/src/mcu.js b/src/mcu.js index 49ab308..f0913e9 100644 --- a/src/mcu.js +++ b/src/mcu.js @@ -227,7 +227,8 @@ class MCU extends Emiter { this.classInfo = _classInfo; // 创建刷新nodeId - let randNodeId =parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000); + //let randNodeId =parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000)+""+parseInt(Math.random()*1000); + let randNodeId=""+ EngineUtils.getRandomInt(1000,3)+ EngineUtils.getRandomInt(1000,3)+ EngineUtils.getRandomInt(1000,3); //生成的字符串nodeId转换为数字 randNodeId=parseInt(randNodeId);