李勇

1.修复音视频频道占用的问题;2.修复音视频禁用状态切换显示问题;3.修改nodeId的生成规则

... ... @@ -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);
}
}
... ...
... ... @@ -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();
... ...
... ... @@ -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();
... ...
... ... @@ -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
... ...
... ... @@ -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;
... ...
... ... @@ -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);
... ...
... ... @@ -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;
... ...
... ... @@ -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();
}
}
... ...
... ... @@ -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
... ...
... ... @@ -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);
... ...