李勇

1.增加获取音视频通道token的接口;加入课堂成功之后会把当前加入音视频通话模块的数据返回给客户端

/**
*
* Base64Module
* */
import Emiter from 'Emiter';
import Loger from 'Loger';
class Base64Module extends Emiter {
constructor() {
super();
this._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
}
// public method for encoding
encode(input) {
let output = "";
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
let i = 0;
input = this._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
decode(input) {
let output = "";
let chr1, chr2, chr3;
let enc1, enc2, enc3, enc4;
let i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = this._utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode(string) {
string = string.replace(/\r\n/g, "\n");
let utftext = "";
for (let n = 0; n < string.length; n++) {
let c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode(utftext) {
let string = "";
let i = 0;
let c=0;
let c1 = 0;
let c2 = 0;
let c3=0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
export default Base64Module;
... ...
... ... @@ -62,7 +62,7 @@ export default class MessageEntrance extends Emiter {
constructor() {
super();
//sdk 信息
GlobalConfig.sdkVersion = "v2.2.16.20170905";
GlobalConfig.sdkVersion = "v2.3.6.20170907";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -99,6 +99,7 @@ export default class MessageEntrance extends Emiter {
_webRtc.on('*', (type, data) => this._emit(type, data));
_webRtc.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
// Sass平台层
_sass = Sass;
_sass.on('*', (type, data) => this._emit(type, data));
... ... @@ -1095,17 +1096,116 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.screenWidth = window.screen.width;
GlobalConfig.screenHeight = window.screen.height;
GlobalConfig.channelId = ""+GlobalConfig.siteId+"_"+GlobalConfig.classId;
GlobalConfig.userUid = GlobalConfig.nodeId;
GlobalConfig.channelKey=null;
GlobalConfig.channelKey="";
//判断是否需要获取加入音视频通话频道的channelKey
if(GlobalConfig.appCertificate){
loger.log("加入视频通话模块->需要先获取channelKey")
//获取channelKey
_sass.getChannelKeyToken((_data)=>{
//{"code":200,"channelKey":"005AQAoAEQzQUQxNzFDOEQwOEU3OTVGMjlCMzZDRUZENTNGOTU0RDY4N0ZGMUEQANylukzO70ocgrNX9hlkNNWvpLBZ9buDAy/fuVkAAA==","uid":"751373669"}
if(_data&&_data.channelKey){
GlobalConfig.channelKey=_data.channelKey||"";
}
this._joinClassSuccessSeting();
})
}else {
loger.log("加入视频通话模块->不需要获取channelKey")
this._joinClassSuccessSeting();
}
/*
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classStatus = GlobalConfig.classStatus;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.maxMediaChannels = GlobalConfig.maxMediaChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired; // 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_1;
joinClassSuccessCallBackData.country = GlobalConfig.country; //国家
joinClassSuccessCallBackData.city = GlobalConfig.city; //城市
joinClassSuccessCallBackData.province = GlobalConfig.province; //服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp; //服务商
joinClassSuccessCallBackData.classTimestamp = GlobalConfig.classTimestamp; //课堂进行的累积时间
joinClassSuccessCallBackData.recordTimestamp = GlobalConfig.recordTimestamp; //课堂录制的累积时间
joinClassSuccessCallBackData.recordPlaybackMaxTime = GlobalConfig.recordPlaybackMaxTime; //录制回放的总时间
joinClassSuccessCallBackData.fps = GlobalConfig.fps;
joinClassSuccessCallBackData.gop = GlobalConfig.gop;
joinClassSuccessCallBackData.videoQuality = GlobalConfig.videoQuality;
joinClassSuccessCallBackData.ssTunnelAppURL = GlobalConfig.ssTunnelAppURL;
joinClassSuccessCallBackData.currentSceneTableId = GlobalConfig.currentSceneTableId; //文档区域的模块显示
joinClassSuccessCallBackData.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;
joinClassSuccessCallBackData.deviceType = GlobalConfig.deviceType;
joinClassSuccessCallBackData.language = GlobalConfig.language;
joinClassSuccessCallBackData.explorer = GlobalConfig.explorer;
joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
joinClassSuccessCallBackData.os = GlobalConfig.os;
joinClassSuccessCallBackData.channelId =GlobalConfig.channelId ;
joinClassSuccessCallBackData.channelKey =GlobalConfig.channelKey ;
joinClassSuccessCallBackData.userUid = GlobalConfig.userUid;
joinClassSuccessCallBackData.appId = GlobalConfig.appId;
joinClassSuccessCallBackData.appCertificate = GlobalConfig.appCertificate;
joinClassSuccessCallBackData.appRecordingKey = GlobalConfig.appRecordingKey;
//设置日志上报所需的信息
LogManager.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;//本地时间和服务器时间的差值(秒)
LogManager.classId = GlobalConfig.classId;//课堂号
LogManager.userId = GlobalConfig.userId;//userId
LogManager.nodeId = GlobalConfig.nodeId;//nodeId
LogManager.userRole = GlobalConfig.userRole;//userRole
LogManager.userName = GlobalConfig.userName;//用户名称
LogManager.logUrl = GlobalConfig.logUrl;//日志服务器地址 //http://log.3mang.com
LogManager.platform=GlobalConfig.platform;
loger.log('加入课堂成功->');
loger.log(joinClassSuccessCallBackData);
//加入课堂成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
//加入音视频通话模块
this._joinChannel({channelId:GlobalConfig.channelId,channelKey:GlobalConfig.channelKey ,uid:GlobalConfig.userUid,info:""+GlobalConfig.userRole});*/
}
//加入课堂成功之后设置本地数据和返回数据给客户端
_joinClassSuccessSeting(){
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
... ... @@ -1163,7 +1263,6 @@ export default class MessageEntrance extends Emiter {
joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
joinClassSuccessCallBackData.os = GlobalConfig.os;
joinClassSuccessCallBackData.channelId =GlobalConfig.channelId ;
joinClassSuccessCallBackData.channelKey =GlobalConfig.channelKey ;
joinClassSuccessCallBackData.userUid = GlobalConfig.userUid;
... ... @@ -1185,7 +1284,6 @@ export default class MessageEntrance extends Emiter {
//加入课堂成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
//加入音视频通话模块
this._joinChannel({channelId:GlobalConfig.channelId,channelKey:GlobalConfig.channelKey ,uid:GlobalConfig.userUid,info:""+GlobalConfig.userRole});
}
... ... @@ -2796,11 +2894,24 @@ export default class MessageEntrance extends Emiter {
return;
}
loger.log("设置appConfig",_params);
GlobalConfig.appId=_params.appId||"eb253cc7b40c4a8b82f0a5b6f93c2ce0";
if(GlobalConfig.appId){
loger.log("本地已经设置appConfig,不需要再设置");
return;
}
GlobalConfig.appId=_params.appId||"";
GlobalConfig.appCertificate=_params.appCertificate||"";
GlobalConfig.appRecordingKey=_params.appRecordingKey||"";
GlobalConfig.recordInterfaces=_params.recordInterfaces||"";
GlobalConfig.getChannelToken=_params.getChannelToken||"";
GlobalConfig.getChannelToken=_params.getChannelToken||""
//去掉协议头
if(GlobalConfig.recordInterfaces){
GlobalConfig.recordInterfaces=GlobalConfig.recordInterfaces.replace('http://',"");
GlobalConfig.recordInterfaces=GlobalConfig.recordInterfaces.replace('https://',"");
}
if(GlobalConfig.getChannelToken){
GlobalConfig.getChannelToken=GlobalConfig.getChannelToken.replace('http://',"");
GlobalConfig.getChannelToken=GlobalConfig.getChannelToken.replace('https://',"");
}
}
//录制控制
_recordControl(_params){
... ...
... ... @@ -557,11 +557,11 @@ GlobalConfig.isHttps=false;//是否是https
//webRtc
GlobalConfig.appId = 'eb253cc7b40c4a8b82f0a5b6f93c2ce0';
GlobalConfig.appId = '';
GlobalConfig.appCertificate = "";
GlobalConfig.appRecordingKey = "";
GlobalConfig.channelId = "";
GlobalConfig.channelKey = null;
GlobalConfig.channelKey ="";
GlobalConfig.userUid = 0;
GlobalConfig.recordInterfaces="";//控制开启录制的接口
GlobalConfig.getChannelToken="";//获取token的地址
... ...
... ... @@ -537,17 +537,79 @@ class Sass extends Emiter {
loger.error(`保存开始录制信息异常.状态码:${err}`);
});
}
//调用服务器端获取加入音视频通话模块的token
getChannelKeyToken(_callback){
if(!GlobalConfig.getChannelToken){
loger.log("获取channelKey->失败->接口地址无效");
if(_callback){
_callback(null);
}
return;
}
/* let userIpInfo = {
"appId": key.value,
"appCertificate": channelKey.value,
"channel": channel.value,
"uid": userUid
}*/
let url=GlobalConfig.locationProtocol+GlobalConfig.getChannelToken;
fetch(encodeURI(url), {
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `appId=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&appCertificate=${GlobalConfig.appCertificate}&uid=${GlobalConfig.userUid}`,
timeout: 4000
})
.then(ret => {
if (ret.ok) {
return ret.json();
} else {
loger.error(`获取channelKey-网络异常.状态码:${ret.status}`);
if(_callback){
_callback(null);
}
throw '';
}
})
.then(ret => {
//channelKey :"005AQAoADZBQzk0M0UzMjVGQzgxREU5Njk1REUyRkVFMEYyMkRBRjFCRjIxN0QQANylukzO70ocgrNX9hlkNNWwKDdW9buDA68oN1YAAA=="
// code: 200
// uid:"2882341273"
if (ret.code == 200) {
loger.log('获取channelKey 完成',ret);
if(_callback){
_callback(ret);
}
} else {
loger.warn('获取channelKey 失败.', ret);
if(_callback){
_callback(null);
}
}
})
.catch(err => {
loger.error(`获取channelKey.状态码:${err}`);
if(_callback){
_callback(null);
}
});
}
//调用服务器端开启录制
startServerRecord(){
if(!GlobalConfig.recordInterfaces){
loger.log("调用服务器端开启录制->失败->接口地址无效")
loger.log("调用服务器端开启录制->失败->接口地址无效");
return;
}
fetch(encodeURI(GlobalConfig.recordInterfaces), {
//{"appId":"eb253cc7b40c4a8b82f0a5b6f93c2ce0","channel":"testcdn_580908347","channelKey":null,"uid":594312157} //录制的channelKey是appCertificate
let url=GlobalConfig.locationProtocol+GlobalConfig.recordInterfaces;
fetch(encodeURI(url), {
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `appID=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.channelKey}&uid=${GlobalConfig.userUid}`,
body: `appId=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.appCertificate}&uid=${GlobalConfig.userUid}`,
timeout: 4000
})
.then(ret => {
... ... @@ -559,9 +621,8 @@ class Sass extends Emiter {
}
})
.then(ret => {
if (ret.errorCode === 0) {
loger.log('调用服务器端开启录制 完成');
this._emit(Sass.CLASS_SAVE_RECORD_INFO_SUCCESS, _param);
if (ret) {
loger.log('调用服务器端开启录制完成',ret);
} else {
loger.warn('调用服务器端开启录制 失败.', ret);
}
... ...
... ... @@ -14,7 +14,7 @@ let loger = Loger.getLoger('WebRtcApe');
class WebRtcApe extends Emiter {
constructor() {
super();
this.appId = 'eb253cc7b40c4a8b82f0a5b6f93c2ce0';
this.appId = '';
this.appCertificate = "";
this.appRecordingKey = "";
... ... @@ -158,7 +158,7 @@ class WebRtcApe extends Emiter {
this.info =_params.info || "";
this.channelKey = _params.channelKey||null;
loger.log("加入视频通话频道->channelId:"+this.channelId,"uid:"+this.uid);
loger.log("开始加入视频通话频道->channelId:"+this.channelId,"uid:"+this.uid);
this.client.join(this.channelKey , ""+this.channelId, this.uid, (uid)=> {
this.uid = uid;
loger.log("加入视频通话频道->成功->channelId:"+this.channelId,"uid:"+this.uid);
... ... @@ -258,7 +258,7 @@ class WebRtcApe extends Emiter {
});
}, (err)=> {
loger.error("webRtc->推流->本地流开启失败", err);
loger.warn("webRtc->推流->本地流开启失败", err);
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED,err);
});
}
... ...