李勇

webRtc增加设备切换

... ... @@ -59,7 +59,7 @@ export default class MessageEntrance extends Emiter {
constructor() {
super();
//sdk 信息
GlobalConfig.sdkVersion = "v2.1.22.20170904";
GlobalConfig.sdkVersion = "v2.2.7.20170904";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -131,8 +131,10 @@ export default class MessageEntrance extends Emiter {
_confer_ape.on(MessageTypes.CLASS_RUN_EXIT, this._runClassExit.bind(this)); //监听自己的关闭事件
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this)); //当前课堂状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this)); //当前课堂人员离开
_confer_ape.on(MessageTypes.CLASS_UPDATE_ROSTER, this._onClassUpdateRoster.bind(this)); //当前课堂人员更新信息
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER, this._onClassNonentityRoster.bind(this)); //当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START, this._onClassRecordStart.bind(this)); //课堂开始录制
_confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this)); //课堂开启录制成功
... ... @@ -277,6 +279,7 @@ export default class MessageEntrance extends Emiter {
//webrtc
this.publishMedia=this._publishMedia.bind(this);
this.unpublishMedia=this._unpublishMedia.bind(this);
this.changeDevices=this._changeDevices.bind(this);
this.setLocalMediaView=this._setLocalMediaView.bind(this);
this.setRemoteMediaView=this._setRemoteMediaView.bind(this);
this.setInvisibleMediaView=this._setInvisibleMediaView.bind(this);
... ... @@ -469,10 +472,25 @@ export default class MessageEntrance extends Emiter {
}
}
//人员离开
//人员离开
_onClassDeleteRoster(_data) {
}
//人员更新
_onClassUpdateRoster(_data){
if(!_data){
return;
}
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2||_data.nodeId==GlobalConfig.nodeId){
return;
}
if(_webRtc){
let user=GlobalConfig.rosters[_data.nodeId];
if(user&&user.openCamera==0){
_webRtc.closeRemoteVideoView(_data);
}
}
}
//当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
//的占用状态导致,对于这种情况,需要释放掉
... ... @@ -1544,6 +1562,13 @@ export default class MessageEntrance extends Emiter {
return {"code": ApeConsts.RETURN_FAILED, "data": ""};
}
//离开视频通话频道
if(GlobalConfig.deviceType==0||GlobalConfig.deviceType==3){
if(_webRtc){
_webRtc.leaveChannel();;
}
}
//停止推流
if (_video_ape) {
_video_ape.stopPublishVideo();
... ... @@ -1704,10 +1729,16 @@ export default class MessageEntrance extends Emiter {
loger.warn("开启录制回放流程失败->还未创建模块");
}
} else {
//初始化音视频通话sdk
this._initWebRtcSdk(null,()=>{
//音视频通话SDK初始化完成之后,根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU
this.loadServerJsonAndgetUserIpInfo();
});
/*
//根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU
this.loadServerJsonAndgetUserIpInfo();
//初始化音视频通话sdk
this._initWebRtcSdk();
*/
}
}
... ... @@ -2581,13 +2612,26 @@ export default class MessageEntrance extends Emiter {
/*
* 初始化webRtc
* */
_initWebRtcSdk(_params){
_initWebRtcSdk(_params,_callback){
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){
loger.warn("移动端不需要处理初始化webRtc");
if(_callback){
_callback();
}
return ;
}
if(_webRtc){
_webRtc.initApp(_params)
_webRtc.initApp(_params,(_callbackData)=>{
//_callback({isSuccess:false,error:err});
if(_callbackData&&_callbackData.isSuccess==true){
this._emit(MessageTypes.WEB_RTC_INIT_SUCCESS,_callbackData);
}else {
this._emit(MessageTypes.WEB_RTC_INIT_FAILED,_callbackData);
}
if(_callback){
_callback();
}
});
}
}
/*
... ... @@ -2661,18 +2705,26 @@ export default class MessageEntrance extends Emiter {
_webRtc.unpublish(_params);
}
}
/*
* 获取设备信息
* */
_getDevices(_params, _callback){
* 切换摄像头和麦克风设备
* */
_changeDevices(_params){
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){
return;
}
if(_webRtc){
_webRtc.getDevices(_params,_callback);
_webRtc.changeDevices(_params);
}
}
/*
* 设置本地video视图
* */
_setLocalMediaView(_params){
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){
return;
}
if(_webRtc){
_webRtc.setLoaclView(_params);
}
... ... @@ -2681,6 +2733,9 @@ export default class MessageEntrance extends Emiter {
* 设置房间内其他人的视图
* */
_setRemoteMediaView(_params){
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){
return;
}
if(_webRtc){
_webRtc.setRemoteView(_params);
}
... ... @@ -2689,6 +2744,9 @@ export default class MessageEntrance extends Emiter {
* 设置监课和需要隐藏显示的用户视图
* */
_setInvisibleMediaView(_params){
if(GlobalConfig.deviceType==1||GlobalConfig.deviceType==2){
return;
}
if(_webRtc){
_webRtc.setInvisibleMediaView(_params);
}
... ...
... ... @@ -103,6 +103,15 @@ MessageTypes.UPDATE_QUESTION_TIME = "update_question_time"; //更新答题时间
//白板笔记事件定义
MessageTypes.WHITEBOARD_ANNOTATION_UPDATE = "whiteboard_annotation_update"; // 'whiteboard.annotation.update';
//webRtc
MessageTypes.WEB_RTC_INIT_SUCCESS = "web_rtc_init_success";
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_PUBLISH_FAILED = "web_rtc_publish_failed";
MessageTypes.GET_DEVICES_SUCCESS = "get_devices_success";
//MCU MS
MessageTypes.SWITCH_MCU_IP = "switch_mcu_ip"; //切换mcu 重新选点
MessageTypes.SWITCH_MS_IP = "switch_ms_ip"; //切换ms 重新选点
... ...
... ... @@ -28,11 +28,14 @@ class WebRtcApe extends Emiter {
this.localStream = null;
this.cameras = [];
this.microphones = [];
this.curCamera = "";
this.curMicrophone = "";
this.curCameraId = "";
this.curMicrophoneId = "";
this.videoResolution = "240P";
this.isOpenVideo = true;
this.isPublish=false;//当前是否正在推流
this.localViewId = "";
this.localStyle = "";
... ... @@ -45,10 +48,20 @@ class WebRtcApe extends Emiter {
this.xdyRemote = "xdy_remote";
//webRtc sdk
this.client = AgoraRTC.createClient({mode: this.mode});
this.getDevices();
this.getDevices(null,(devices)=>{
if (this.cameras && this.cameras.length > 0) {
this.curCameraId = this.cameras[0].deviceId || "";
GlobalConfig.curCamera =this.cameras[0].label || "";
}
if (this.microphones && this.microphones.length > 0) {
this.curMicrophoneId = this.microphones[0].deviceId || "";
GlobalConfig.curMicrophone = this.microphones[0].label || "";
}
});
}
initApp(_params) {
initApp(_params,_callback) {
loger.log("初始化WebRtc");
if (_params) {
this.appId = _params.appId;
... ... @@ -56,9 +69,14 @@ class WebRtcApe extends Emiter {
if (this.client) {
this.client.init(this.appId, () => {
loger.log("初始化WebRtc->成功");
if(_callback){
_callback({isSuccess:true});
}
}, (err)=> {
loger.error("初始化WebRtc->失败", err);
if(_callback){
_callback({isSuccess:false,error:err});
}
});
this.addEvent();
}
... ... @@ -93,14 +111,18 @@ class WebRtcApe extends Emiter {
this.client.on('stream-subscribed', (evt)=> {
let stream = evt.stream;
loger.log("Subscribe remote stream successfully: " + stream.getId());
if(GlobalConfig.getUserRoleFromeNodeId(stream.getId())==ApeConsts.invisible){
//显示隐藏用户
$(this.invisibleViewId).append('<div id="' + this.xdyRemote + stream.getId() + '" style="float:left; width:320px;height:240px;"></div>');
}else {
$(this.remoteViewId).append('<div id="' + this.xdyRemote + stream.getId() + '" style="float:left; width:320px;height:240px;"></div>');
if(stream){
loger.log("获取远程视频流成功: " + stream.getId());
let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:320px;height:240px;"></div>`;
if(GlobalConfig.getUserRoleFromeNodeId(stream.getId())==ApeConsts.invisible){
//显示隐藏用户
$(this.invisibleViewId).append(viewDiv);
}else {
$(this.remoteViewId).append(viewDiv);
}
stream.play(this.xdyRemote + stream.getId());
}
stream.play('' + this.xdyRemote + stream.getId());
});
this.client.on('stream-removed', (evt)=> {
... ... @@ -134,25 +156,45 @@ 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._emit(MessageTypes.WEB_RTC_JOIN_SUCCESS);
this.openLoaclStream();
}, (err)=> {
loger.log("加入视频通话频道->失败->", err);
loger.error("加入视频通话频道->失败->", err);
this._emit(MessageTypes.WEB_RTC_JOIN_FAILED);
});
}
//重新获取摄像头和麦克风并重新推流
reGetLoaclStream(){
if(this.isPublish){
loger.log("重新获取摄像头和麦克风并重新推流");
this.unpublish();
this.openLoaclStream();
//切换设备后自动重推流
this.rePublishDelay=setTimeout(()=>{
this.publish();
},1200);
this.publish();
}else {
this.openLoaclStream();
}
}
openLoaclStream() {
loger.log("摄像头", this.curCamera);
loger.log("麦克风", this.curMicrophone);
/* if(this.localStream){
this.localStream.close();
this.localStream=null;
}*/
this.localStream = AgoraRTC.createStream({
streamID: this.uid,
audio: true,
microphoneId: this.curMicrophone,
cameraId: this.curCamera,
microphoneId: this.curMicrophoneId,
cameraId: this.curCameraId,
video: this.isOpenVideo,
screen: false
});
if (this.isOpenVideo) {
//设置分辨率
this.localStream.setVideoProfile(this.videoResolution);
}
}
... ... @@ -162,26 +204,41 @@ class WebRtcApe extends Emiter {
if (!this.client) {
return;
}
this.client.leaveChannel(() => {
loger.log("Leavel channel successfully");
this.client.leave(() => {
loger.log("离开视频通话频道->成功");
}, (err)=> {
loger.log("Leave channel failed");
loger.log("离开视频通话频道->失败");
});
}
publish() {
closeRemoteVideoView(_data){
if(!_data){
return;
}
//根据nodeId查找视频
try{
loger.log("立即删除停止推流人员的视图");
$('#' + this.xdyRemote + _data.nodeId).remove();
}catch (err){
}
}
publish(_params) {
if (!this.client||!this.localStream) {
return;
}
this.localStream.init(()=> {
loger.log("webRtc->推流: ");
let viewName = this.localViewId.replace("#", "");
loger.log("webRtc->推流->",viewName);
this.localStream.play(viewName);
this.client.publish(this.localStream, (err)=> {
loger.log("webRtc->推流失败: " + err);
GlobalConfig.openCamera =0;
GlobalConfig.openMicrophones =0;
this.isPublish=false;
});
this.isPublish=true;
GlobalConfig.openCamera = EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones = GlobalConfig.openCamera;
... ... @@ -195,11 +252,13 @@ class WebRtcApe extends Emiter {
});
}, (err)=> {
loger.log("webRtc->推流->本地流开启失败", err);
loger.error("webRtc->推流->本地流开启失败", err);
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED,err);
});
}
unpublish() {
clearTimeout(this.rePublishDelay);
loger.log("webRtc->停止推流 ");
if (!this.client||!this.localStream) {
return;
... ... @@ -209,6 +268,7 @@ class WebRtcApe extends Emiter {
});
this.localStream.close();
$(this.localViewId).html("");
this.isPublish=false;
GlobalConfig.openCamera =0;
GlobalConfig.openMicrophones =0;
this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
... ... @@ -247,29 +307,80 @@ class WebRtcApe extends Emiter {
this.invisibleViewId = _params.divId||"";
this.invisibleStyle = _params.styleStr||"";
}
/*
* 切换当前使用的设备
* */
changeDevices(_params){
loger.log("切换设备->",_params);
if(!_params){
return;
}
//设置摄像头
if(_params.curCamera){
for(let k in this.cameras){
let item=this.cameras[k];
if(item&&item.label==_params.curCamera){
this.curCameraId=item.deviceId;
GlobalConfig.curCamera=_params.curCamera;
break;
}
}
}
//设置麦克风
if(_params.curMicrophone){
for(let k in this.microphones){
let item=this.microphones[k];
if(item&&item.label==_params.curMicrophone){
this.curMicrophoneId=item.deviceId;
GlobalConfig.curMicrophone=_params.curMicrophone;
break;
}
}
}
//分辨率
if(_params.videoResolution){
this.videoResolution=_params.videoResolution||"240P";//默认是240P 20 320x240 15 200
}
clearTimeout(this.changeDevicesDelay);
this.changeDevicesDelay=setTimeout(()=>{
//重新获取本地视图流
this.reGetLoaclStream();
},1400);
}
/*
* 获取设备信息
* */
getDevices(_params,_callback) {
AgoraRTC.getDevices((devices)=> {
console.log("devices", devices)
//下面的数组存的是对象
this.microphones=[];
this.cameras=[];
//选的数组存的是设备名称
GlobalConfig.cameras=[];
GlobalConfig.microphones=[];
loger.log("devices", devices)
for (let i = 0; i < devices.length; i++) {
let device = devices[i];
if (device.kind === 'audioinput') {
//{"deviceId":"default","kind":"audiooutput","label":"默认","groupId":"cf49a03ca26700235629fc13d3e6630bd34407c66438d157056a34dd3ae03ef5"}
if (device.kind == 'audioinput') {
this.microphones.push(device);
} else if (device.kind === 'videoinput') {
GlobalConfig.microphones.push(device.label);
} else if (device.kind == 'videoinput') {
this.cameras.push(device);
GlobalConfig.cameras.push(device.label);
} else {
loger.warn('未知的设备: ', device);
loger.warn('其他设备: ', device);
}
}
if (this.cameras && this.cameras.length > 0) {
this.curCamera = this.cameras[0].deviceId || "";
}
if (this.microphones && this.microphones.length > 0) {
this.curMicrophone = this.microphones[0].deviceId || "";
}
let _deviceData={cameras:GlobalConfig.cameras,microphones:GlobalConfig.microphones};
if(_callback){
_callback({cameras:this.cameras,microphones:this.microphones});
_callback(_deviceData);
}
this._emit(MessageTypes.GET_DEVICES_SUCCESS,_deviceData);
});
}
}
... ...