李勇

1.升级声网SDK;2.视频模块增加状态的处理和增加重连新接口

... ... @@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter {
super();
this.lastClassActiveTime=0;//最后一次课堂激活的时间戳
//sdk 信息
GlobalConfig.sdkVersion = "v2.36.8.20171206";
GlobalConfig.sdkVersion = "v2.38.1.201712011";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
console.log("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -307,6 +307,7 @@ export default class MessageEntrance extends Emiter {
this.setHostRemoteMediaView = this._setHostRemoteMediaView.bind(this);//设置远程老师的视图
this.setNormalRemoteMediaView = this._setNormalRemoteMediaView.bind(this);//设置远程学生的视图
this.setInvisibleMediaView = this._setInvisibleMediaView.bind(this);//设置监课身份的视图
this.leaveVideoChannel = this._leaveChannel.bind(this);//离开视频频道
this.setAppConfig = this._setAppConfig.bind(this);
this.recordControl = this._changeMediaRecordStatus.bind(this);//切换控制音视频的录制状态
... ... @@ -527,12 +528,12 @@ export default class MessageEntrance extends Emiter {
if (_whiteboard_ape) {
_whiteboard_ape.updaterRecordApeStatus();
}
if (_video_ape) {
/* if (_video_ape) {
_video_ape.updaterRecordApeStatus();
}
if (_audio_ape) {
_audio_ape.updaterRecordApeStatus();
}
}*/
if (_mediaShareApe) {
_mediaShareApe.updaterRecordApeStatus();
}
... ...
... ... @@ -67,8 +67,12 @@ class EngineUtils {
let timestamp = time % 1000000000;//time后9位
return timestamp;
}
//生成时间戳毫秒
static creatNowTime() {
let time = new Date().getTime();
return time;
}
//生成时间戳秒
static creatTimestamp() {
let time = parseInt(new Date().getTime() / 1000);//精确到秒
return time;
... ...
... ... @@ -184,7 +184,6 @@ class EverSocket extends Emiter {
loger.log('ignore errors');
}
this.websocket = undefined;
}
_clearHistory() {
... ...
... ... @@ -670,7 +670,7 @@ GlobalConfig.allowRecordMaxTime = 48 * 60 * 60; //(秒)允许录制的最长时
GlobalConfig.siteId_letv = 'shchuanbao'; //乐视,MS不需要动态选点的站点
GlobalConfig.ssTunnelAppURL = ''; //屏幕共享插件的地址
GlobalConfig.serverTime = 0; //服务器当前时间戳
GlobalConfig.serverAndLoacTimeDistanc = 0; //本地时间和服务器时间错的差值
GlobalConfig.serverAndLoacTimeDistanc = 0; //当前系统时间和服务器时间的差值 (秒)
GlobalConfig.logUrl = ""; //日志上报地址;
GlobalConfig.rosterNum = 0;//当前总人数
... ...
... ... @@ -109,6 +109,7 @@ MessageTypes.WEB_RTC_INIT_FAILED = "web_rtc_init_failed";
MessageTypes.WEB_RTC_JOIN_SUCCESS = "web_rtc_join_success";
MessageTypes.WEB_RTC_JOIN_FAILED = "web_rtc_join_failed";
MessageTypes.WEB_RTC_LEAVE_CHANNEL = "web_rtc_leave_channel";//离开频道
MessageTypes.WEB_RTC_REJOIN_SUCCESS = "web_rtc_rejoin_success";//重连成功
MessageTypes.WEB_RTC_PUBLISH_FAILED = "web_rtc_publish_failed";
MessageTypes.GET_DEVICES_SUCCESS = "get_devices_success";
MessageTypes.MEDIA_PUBLISH_STATUS_CHANGE = "media_publish_status_change";//音视频推流的状态发生改变
... ...
... ... @@ -518,7 +518,8 @@ class AudioApe extends Ape {
packPduModel.screenHeight = _param.screenHeight || GlobalConfig.screenHeight;
packPduModel.deviceType = _param.deviceType || GlobalConfig.deviceType;
packPduModel.optionJsonData = GlobalConfig.optionJsonData;
loger.log("packPdu->", packPduModel);
packPduModel.sendTimestamp =EngineUtils.creatNowTime()- GlobalConfig.serverAndLoacTimeDistanc*1000;//当前时间减去服务器时间差
loger.log("packPdu------>", packPduModel);
return packPduModel;
}
... ... @@ -529,7 +530,7 @@ class AudioApe extends Ape {
}
try {
let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData);
loger.log("unPackPdu->", packChannelInfo);
loger.log("unPackPdu------>", packChannelInfo);
return packChannelInfo;
} catch (err) {
loger.log("unPackPdu error->itemIdx=" + itemIdx + " err:" + err.message);
... ...
... ... @@ -886,6 +886,7 @@ class VideoApe extends Ape {
packPduModel.screenHeight = _param.screenHeight || GlobalConfig.screenHeight;
packPduModel.deviceType = _param.deviceType || GlobalConfig.deviceType;
packPduModel.optionJsonData = GlobalConfig.optionJsonData;
packPduModel.sendTimestamp =EngineUtils.creatNowTime()- GlobalConfig.serverAndLoacTimeDistanc*1000;//当前时间减去服务器时间差
loger.log('packPdu--------------->', packPduModel);
return packPduModel;
}
... ...
... ... @@ -10,7 +10,7 @@ import GlobalConfig from 'GlobalConfig';
import ApeConsts from './ApeConsts';
import EngineUtils from 'EngineUtils';
import MessageTypes from 'MessageTypes';
var AgoraRTC = require('../AgoraRTCSDK-1.14.0');
var AgoraRTC = require('../AgoraRTCSDK-2.0.0');
let loger = Loger.getLoger('WebRtcApe');
const SIZE_480 = 480;
const SIZE_360 = 360;
... ... @@ -63,7 +63,7 @@ class WebRtcApe extends Emiter {
this.isOpenVideo = true;//是否开启摄像头,默认为开启,如果获取不到麦克风的时候会设置为false
this.firstPublishSuccess = false;//记录加入频道成功之后是否推流成功过,离开频道之后需要设置为false
this.isWebSocketDisconnect=false;//记录中途是否已经断开
this.isPublish = false;//当前是否正在推流
this.videoScale = 1;//视图的缩放比例,默认为1;
... ... @@ -149,15 +149,30 @@ class WebRtcApe extends Emiter {
this.channelKey = "";
this.client.on('error', (err) => {
loger.log("WebRtc异常:", err);
if (err.reason === 'DYNAMIC_KEY_TIMEOUT') {
this.client.renewChannelKey(this.channelKey, ()=> {
loger.log("Renew channel key successfully");
}, (err)=> {
loger.log("Renew channel key failed: ", err);
});
switch (err.reason){
case "DYNAMIC_KEY_TIMEOUT":
this.client.renewChannelKey(this.channelKey, ()=> {
loger.log("Renew channel key successfully");
}, (err)=> {
loger.log("Renew channel key failed: ", err);
});
break;
case "SOCKET_DISCONNECTED":
//连接断开
this.isWebSocketDisconnect=true;
this._emit(MessageTypes.WEB_RTC_LEAVE_CHANNEL);
break;
case "SOCKET_ERROR":
//连接断开
this.isWebSocketDisconnect=true;
this._emit(MessageTypes.WEB_RTC_LEAVE_CHANNEL);
break;
default :
break;
}
});
this.client.on('stream-published', (evt)=> {
this.reJoinChannelSuccess();
loger.log("webRtc->推流成功->", new Date().getTime());
this.isPublish = true;
this.firstPublishSuccess = true;
... ... @@ -305,10 +320,21 @@ class WebRtcApe extends Emiter {
this.remoteVideoList[user.nodeId] = stream;
}
}
this.clearInvalidVideoView();
this.reJoinChannelSuccess();
}
/*
*
* 断线后重连成功
* */
reJoinChannelSuccess(){
if(this.isWebSocketDisconnect){
loger.log("断线重连成功");
this._emit(MessageTypes.WEB_RTC_REJOIN_SUCCESS);
}
this.isWebSocketDisconnect=false;
}
//清除无效的视图
clearInvalidVideoView() {
let normalList = document.getElementsByClassName(this.normalWebRtcVideoClass);
... ... @@ -445,6 +471,7 @@ class WebRtcApe extends Emiter {
this.client.join(this.channelKey, "" + this.channelId, this.uid, (uid)=> {
this.uid = uid;
loger.log("加入视频通话频道->成功->channelId:" + this.channelId, "uid:" + this.uid);
this.isWebSocketDisconnect=false;
this._emit(MessageTypes.WEB_RTC_JOIN_SUCCESS);
this.openLoaclStream();
... ... @@ -473,7 +500,6 @@ class WebRtcApe extends Emiter {
this.rePublishDelay = setTimeout(()=> {
this.publish();
}, 1200);
//this.publish();
} else {
this.openLoaclStream();
}
... ... @@ -494,6 +520,15 @@ class WebRtcApe extends Emiter {
screen: false
});
this.localStream.on("accessAllowed", function(){
loger.warn("摄像头麦克风->已经获取权限");
})
// The user has denied access to the camera and mic.
this.localStream.on("accessDenied", function(){
loger.warn("摄像头和麦克风->权限获取失败");
})
if (this.isOpenVideo) {
loger.log("摄像头已经获取->设置本地视频分辨率:" + this.videoResolution);
//设置视频分辨率
... ... @@ -507,7 +542,7 @@ class WebRtcApe extends Emiter {
}
leaveChannel() {
loger.log("调用离开视频通话频道->isPublish" + this.isPublish);
loger.log("调用离开视频通话频道->isPublish:" + this.isPublish);
this._emit(MessageTypes.WEB_RTC_LEAVE_CHANNEL);
if (!this.client) {
return;
... ... @@ -519,6 +554,7 @@ class WebRtcApe extends Emiter {
}, (err)=> {
loger.log("离开视频通话频道->失败");
});
this.clearAllRemoteView();
}
closeRemoteVideoView(_data) {
... ... @@ -575,7 +611,8 @@ class WebRtcApe extends Emiter {
return;
}
if (!this.localStream) {
loger.warn("推流失败->本地流获取失败!");
loger.warn("推流失败->本地流获取失败!->尝试重新获取本地流");
this.openLoaclStream();
return;
}
//老师-助教-主讲人-->设置旁路大于30秒没有推流,推流服务会停止,需要重设旁录和重加频道;
... ... @@ -635,6 +672,7 @@ class WebRtcApe extends Emiter {
this.localStream.play(viewName);
this.client.publish(this.localStream, (err)=> {
loger.log("webRtc->推流失败: " + err);
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED, {type:"error",msg:err.msg||err});
this.isPublish = false;
this.unpublish();
});
... ... @@ -642,7 +680,7 @@ class WebRtcApe extends Emiter {
loger.warn("webRtc->推流->本地流开启失败", err);
this.isPublish = false;
this.clearLocalView();
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED, err);
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED, {type:"error",msg:err.msg||err});
if (err) {
switch (err.msg) {
case "DEVICES_NOT_FOUND":
... ... @@ -719,6 +757,14 @@ class WebRtcApe extends Emiter {
$("." + this.localWebRtcVideoClass).remove();
}
//清除所有远程视图
clearAllRemoteView() {
loger.log("清除所有远程视图");
$("." + this.localWebRtcVideoClass).remove();
$("." + this.hostWebRtcVideoClass).remove();
$("." + this.normalWebRtcVideoClass).remove();
}
/*
* 更新所有视频的尺寸大小
* */
... ... @@ -912,11 +958,18 @@ class WebRtcApe extends Emiter {
if (idArr && idArr.length > 1) {
uid = parseInt(idArr[1]);
}
let user = GlobalConfig.getUserInfoFromeNodeId(parseInt(uid));
let userName="";
let roleRole="";
if (user) {
roleRole = GlobalConfig.getUserRoleToString(user.role);
userName = user.name;
}
if (className.indexOf("cameraOn") > 0) {
loger.log("点击禁用视频->" + uid);
loger.log("点击禁用视频按钮->用户:["+roleRole+"] " +userName+" uid:"+uid);
this.sendChangeUserMediaEnabled({nodeId: uid, video: false, audio: true});
} else {
loger.log("点击解除视频禁用->" + uid);
loger.log("点击解除视频禁用按钮->用户:["+roleRole+"] " +userName+" uid:"+uid);
this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
}
}
... ... @@ -931,11 +984,19 @@ class WebRtcApe extends Emiter {
if (idArr && idArr.length > 1) {
uid = parseInt(idArr[1]);
}
let user = GlobalConfig.getUserInfoFromeNodeId(parseInt(uid));
let userName="";
let roleRole="";
if (user) {
roleRole = GlobalConfig.getUserRoleToString(user.role);
userName = user.name;
}
if (className.indexOf("microphoneOn") > 0) {
loger.log("点击禁音->" + uid);
loger.log("点击禁音按钮->用户:["+roleRole+"] " +userName+" uid:"+uid);
this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: false});
} else {
loger.log("点击解除禁音");
loger.log("点击解除禁音按钮->用户:["+roleRole+"] " +userName+" uid:"+uid);
this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
}
}
... ... @@ -955,7 +1016,6 @@ class WebRtcApe extends Emiter {
if (!_data) {
return;
}
if (_data.nodeId != GlobalConfig.nodeId) {
//不是自己的只设置状态显示即可
//音频
... ... @@ -965,7 +1025,7 @@ class WebRtcApe extends Emiter {
} else {
//控制自己的音频
if (this.isEnableVideo == _data.video && this.isEnableAudio == _data.audio) {
loger.log("收到控制音视频禁用消息->自己当前状态一不需要设置:", _data);
loger.log("收到控制音视频禁用消息->自己当前状态一不需要设置:", _data);
return;
}
//记录自己当前的音视频禁用状态
... ... @@ -984,7 +1044,7 @@ class WebRtcApe extends Emiter {
this.enableVideo(_data.nodeId);
}
//更新同步用户的媒体禁用状态
loger.log("更新同步用户的媒体禁用状态", _data);
//loger.log("更新同步用户的媒体禁用状态", _data);
if (_data) {
this._emit(WebRtcApe.UPDATE_USER_MEDIA_MUTED_STATUS, _data);
}
... ... @@ -1024,12 +1084,13 @@ class WebRtcApe extends Emiter {
*
* */
setUidAudioEnabledStatus(uid, isEnable) {
loger.log("设置音频禁用按钮的状态", uid, isEnable);
if (isEnable == true) {
loger.log("设置音频禁用按钮的状态", uid, "开启");
$("#" + this.audioMutedIdName + uid).removeClass("microphoneOff");
$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOn");
$("#" + this.audioMutedIdName + uid).attr("title", this.closeMicrophoneTitle);
} else {
loger.log("设置音频禁用按钮的状态", uid, "禁用");
$("#" + this.audioMutedIdName + uid).removeClass("microphoneOn");
$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff");
$("#" + this.audioMutedIdName + uid).attr("title", this.openMicrophoneTitle);
... ... @@ -1069,16 +1130,17 @@ class WebRtcApe extends Emiter {
*
* */
setUidVideoEnabledStatus(uid, isEnable) {
loger.log("设置视频禁用按钮的状态", uid, isEnable);
let user = GlobalConfig.getUserInfoFromeNodeId(parseInt(uid));
if(user&&user.cameras&&user.cameras.length<1){
//用户没有摄像头 显示音频封面
$("#audioPlayIcoBox" + uid).show();
$("#" + this.videoMutedIdName + uid).hide();
loger.log("设置视频禁用按钮的状态->没有摄像头不需要设置", uid, isEnable)
return;
}
if (isEnable == true) {
//开启
loger.log("设置视频禁用按钮的状态", uid, "开启");
$("#audioPlayIcoBox" + uid).hide();
$("#" + this.videoMutedIdName + uid).removeClass("cameraOff");
$("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOn");
... ... @@ -1086,6 +1148,7 @@ class WebRtcApe extends Emiter {
} else {
//禁用
loger.log("设置视频禁用按钮的状态", uid, "禁用");
$("#audioPlayIcoBox" + uid).show();
$("#" + this.videoMutedIdName + uid).removeClass("cameraOn");
$("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOff");
... ...
... ... @@ -838,6 +838,10 @@ message RCAudioChannelInfoPdu {
optional uint32 screenHeight = 14;//屏幕分辨率高
optional uint32 deviceType = 15;//设备类型
optional string optionJsonData =16;//其他参数的json对象
optional string m3u8Url =17;//m3u8拉流地址
optional string rtmpUrl =18;//rtmp拉流地址
optional string replay =19;//回放的拉流地址
optional uint64 sendTimestamp =20;//发送消息的时间戳
}
message RCVideoChannelInfoPdu {
... ... @@ -860,6 +864,7 @@ message RCVideoChannelInfoPdu {
optional string m3u8Url =17;//m3u8拉流地址
optional string rtmpUrl =18;//rtmp拉流地址
optional string replay =19;//回放的拉流地址
optional uint64 sendTimestamp =20;//发送消息的时间戳
}
message RCVideoChannelInfoRecordPdu {
... ...