李勇

1.腾讯云录制增加flv格式;2.视频模块获取空闲频道的时候增加对当前最大允许路数值为0时的处理;3.测试声网旁路功能

... ... @@ -62,7 +62,7 @@ export default class MessageEntrance extends Emiter {
constructor() {
super();
//sdk 信息
GlobalConfig.sdkVersion = "v2.12.8.20170926";
GlobalConfig.sdkVersion = "v2.12.14.20170927";
loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
//设置
... ... @@ -1209,9 +1209,17 @@ export default class MessageEntrance extends Emiter {
if(GlobalConfig.appId&&!GlobalConfig.openFlash){
setTimeout(()=>{
/* //加入之前先设置旁录地址,只有直播支持旁路
if(_webRtc){
let publishData=this._getVideoPublishPath();
loger.log("加入之前先设置旁录地址",publishData);
if(publishData&&publishData.code==0){
_webRtc.setConfigPublisherUrl(publishData.publishUrl);
}
}*/
//加入音视频通话模块,延迟一秒处理,因为视频需要根据用户列表信息来判断放的位置,太早的话用户列表没有数据
this._joinChannel({channelId:GlobalConfig.channelId,channelKey:GlobalConfig.channelKey ,uid:GlobalConfig.userUid,info:""+GlobalConfig.userRole});
},1000);
},1600);
}
}
... ... @@ -2740,6 +2748,7 @@ export default class MessageEntrance extends Emiter {
});
}
}
/*
* 加入视频通话
* */
... ... @@ -2798,6 +2807,7 @@ export default class MessageEntrance extends Emiter {
_webRtc.publish(_params);
}
}
/*
* 停止发布流
* */
... ...
... ... @@ -143,7 +143,7 @@ class MediaModule {
txTime=txTime.toString(16);
let txSecret= MD5(publishSuffix + streamId+txTime);
//rtmp://11220.livepush.myqcloud.com/live/11220_c5a1ea0bce?bizid=11220&txSecret=b1d8af72bf62366eef31cbb5dc5c8778&txTime=59C5337F
newUrl=url +"?bizid=11220&txSecret="+txSecret+"&txTime="+txTime+"&record=hls&record_interval=5400";
newUrl=url +"?bizid=11220&txSecret="+txSecret+"&txTime="+txTime+"&record=hls|flv&record_interval=5400";
loger.log("生成的推流地址->"+newUrl);
return newUrl;
}
... ... @@ -343,10 +343,14 @@ class MediaModule {
}
loger.log("获取空闲的通道", "mediaChannels", this.mediaChannels, "counter:", counter);
//loger.log(this.mediaChannels);
if (counter < this.maxMediaChannel) {
if(this.maxMediaChannel>0){
if (counter < this.maxMediaChannel) {
return this.MEDIA_OBJ_TABLE_ID + (counter);
}
return 0;//没有空闲的
}else {
return this.MEDIA_OBJ_TABLE_ID + (counter);
}
return 0;//没有空闲的
}
//获取准备推流的频道信息
... ...
... ... @@ -14,18 +14,20 @@ let loger = Loger.getLoger('WebRtcApe');
class WebRtcApe extends Emiter {
constructor() {
super();
this.nameDisplay="block";//默认显示名字
this.nameDisplay = "block";//默认显示名字
this.appId = '';
this.appCertificate = "";
this.appRecordingKey = "";
this.channelKey=null;
this.configPublisherUrl = "";//旁路地址;
this.channelKey = null;
this.channelId = "";
this.uid = 0;
this.info = ""
this.reAddRemoteStreamDelay=0;//重连远程视频的计时器
this.rePublishDelay=0;//重新推流的间隔
this.reAddRemoteStreamDelay = 0;//重连远程视频的计时器
this.rePublishDelay = 0;//重新推流的间隔
this.mode = "interop";
this.client = null;
... ... @@ -35,40 +37,40 @@ class WebRtcApe extends Emiter {
this.curCameraId = "";
this.curMicrophoneId = "";
this.remoteVideoList={};//记录远程视频流
this.remoteVideoList = {};//记录远程视频流
this.videoResolution = "240P";
this.isOpenVideo = true;
this.isPublish=false;//当前是否正在推流
this.isPublish = false;//当前是否正在推流
this.normalRemoteViewId ="";
this.normalRemoteStyle ="";
this.normalRemoteVideoWidth=320;
this.normalRemoteVideoHeight=240;
this.normalRemoteViewId = "";
this.normalRemoteStyle = "";
this.normalRemoteVideoWidth = 320;
this.normalRemoteVideoHeight = 240;
this.localViewId = "";
this.localStyle = "";
this.localVideoWidth=320;
this.localVideoHeight=240;
this.localVideoWidth = 320;
this.localVideoHeight = 240;
this.hostRemoteViewId = "";
this.hostRemoteStyle = "";
this.hostRemoteVideoWidth=320;
this.hostRemoteVideoHeight=240;
this.hostRemoteVideoWidth = 320;
this.hostRemoteVideoHeight = 240;
this.invisibleViewId ="";
this.invisibleStyle ="";
this.invisibleVideoWidth=320;
this.invisibleVideoHeight=240;
this.invisibleViewId = "";
this.invisibleStyle = "";
this.invisibleVideoWidth = 320;
this.invisibleVideoHeight = 240;
this.xdyRemote = "xdy_remote";
//webRtc sdk
this.client = AgoraRTC.createClient({mode: this.mode});
this.getDevices(null,(devices)=>{
this.getDevices(null, (devices)=> {
if (this.cameras && this.cameras.length > 0) {
this.curCameraId = this.cameras[0].deviceId || "";
GlobalConfig.curCamera =this.cameras[0].label || "";
GlobalConfig.curCamera = this.cameras[0].label || "";
}
if (this.microphones && this.microphones.length > 0) {
this.curMicrophoneId = this.microphones[0].deviceId || "";
... ... @@ -77,7 +79,7 @@ class WebRtcApe extends Emiter {
});
}
initApp(_params,_callback) {
initApp(_params, _callback) {
loger.log("初始化WebRtc");
if (_params) {
this.appId = _params.appId;
... ... @@ -85,13 +87,13 @@ class WebRtcApe extends Emiter {
if (this.client) {
this.client.init(this.appId, () => {
loger.log("初始化WebRtc->成功");
if(_callback){
_callback({isSuccess:true});
if (_callback) {
_callback({isSuccess: true});
}
}, (err)=> {
loger.error("初始化WebRtc->失败", err);
if(_callback){
_callback({isSuccess:false,error:err});
if (_callback) {
_callback({isSuccess: false, error: err});
}
});
this.addEvent();
... ... @@ -116,8 +118,8 @@ class WebRtcApe extends Emiter {
}
});
this.client.on('stream-published', (evt)=> {
loger.log("webRtc->推流成功->",new Date().getTime());
this.isPublish=true;
loger.log("webRtc->推流成功->", new Date().getTime());
this.isPublish = true;
GlobalConfig.openCamera = EngineUtils.creatTimestamp();
GlobalConfig.openMicrophones = GlobalConfig.openCamera;
this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
... ... @@ -132,63 +134,63 @@ 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);
});*/
/* 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)=> {
let stream = evt.stream;
this.addRemoetStreamView(stream);
});
/* this.client.on('stream-subscribed', (evt)=> {
let stream = evt.stream;
if(stream){
//let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;"></div>`;
let uid=stream.getId();
let user=GlobalConfig.getUserInfoFromeNodeId(uid);
let userName="";
let userRole=""
if(user){
userName=user.name||"";
userRole=user.userRole;
}
let nameDiv=`<div style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
if(userRole==ApeConsts.invisible){
//把远程视频添加到监课列表
loger.log("获取远程视频流成功->监课:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.invisibleVideoWidth}px;height:${this.invisibleVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.invisibleViewId).append(viewDiv);
}else if(userRole==ApeConsts.host){
//把远程视图添加到老师列表
loger.log("获取远程视频流成功->老师:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.hostRemoteViewId).append(viewDiv);
}else {
//把视图添加到学生列表
loger.log("获取远程视频流成功->学生:"+userName+"->" +uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.normalRemoteVideoWidth}px;height:${this.normalRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.normalRemoteViewId).append(viewDiv);
}
//播放视频,隐藏控制条
try{
$("bar_"+stream.getId()).hide();
stream.play(this.xdyRemote + stream.getId());
}catch (err){
}
if(user.deviceType==1||user.deviceType==2){
this.remoteVideoList[user.nodeId]=stream;
}
console.log("移动端远程视频流集合->",this.remoteVideoList);
}
});*/
/* this.client.on('stream-subscribed', (evt)=> {
let stream = evt.stream;
if(stream){
//let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;"></div>`;
let uid=stream.getId();
let user=GlobalConfig.getUserInfoFromeNodeId(uid);
let userName="";
let userRole=""
if(user){
userName=user.name||"";
userRole=user.userRole;
}
let nameDiv=`<div style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
if(userRole==ApeConsts.invisible){
//把远程视频添加到监课列表
loger.log("获取远程视频流成功->监课:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.invisibleVideoWidth}px;height:${this.invisibleVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.invisibleViewId).append(viewDiv);
}else if(userRole==ApeConsts.host){
//把远程视图添加到老师列表
loger.log("获取远程视频流成功->老师:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.hostRemoteViewId).append(viewDiv);
}else {
//把视图添加到学生列表
loger.log("获取远程视频流成功->学生:"+userName+"->" +uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.normalRemoteVideoWidth}px;height:${this.normalRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.normalRemoteViewId).append(viewDiv);
}
//播放视频,隐藏控制条
try{
$("bar_"+stream.getId()).hide();
stream.play(this.xdyRemote + stream.getId());
}catch (err){
}
if(user.deviceType==1||user.deviceType==2){
this.remoteVideoList[user.nodeId]=stream;
}
console.log("移动端远程视频流集合->",this.remoteVideoList);
}
});*/
this.client.on('stream-removed', (evt)=> {
let stream = evt.stream;
if(stream){
if (stream) {
stream.stop();
$('#' + this.xdyRemote + stream.getId()).remove();
loger.log("远程视频流已经断开:" + stream.getId());
... ... @@ -210,109 +212,116 @@ class WebRtcApe extends Emiter {
});
}
addRemoetStreamView(stream){
if(stream){
addRemoetStreamView(stream) {
if (stream) {
//let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;"></div>`;
let uid=stream.getId();
let user=GlobalConfig.getUserInfoFromeNodeId(uid);
let userName="";
let userRole=""
if(user){
userName=user.name||"unknow";
userRole=user.userRole;
let uid = stream.getId();
let user = GlobalConfig.getUserInfoFromeNodeId(uid);
let userName = "";
let userRole = ""
if (user) {
userName = user.name || "unknow";
userRole = user.userRole;
}
let nameDiv=`<div style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
let nameDiv = `<div style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
if(userRole==ApeConsts.invisible){
if (userRole == ApeConsts.invisible) {
//把远程视频添加到监课列表
loger.log("获取远程视频流成功->监课:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.invisibleVideoWidth}px;height:${this.invisibleVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
loger.log("获取远程视频流成功->监课:" + userName + "->" + uid, new Date().getTime());
let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.invisibleVideoWidth}px;height:${this.invisibleVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.invisibleViewId).append(viewDiv);
}else if(userRole==ApeConsts.host){
} else if (userRole == ApeConsts.host) {
//把远程视图添加到老师列表
loger.log("获取远程视频流成功->老师:"+userName+"->" + uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
loger.log("获取远程视频流成功->老师:" + userName + "->" + uid, new Date().getTime());
let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.hostRemoteVideoWidth}px;height:${this.hostRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.hostRemoteViewId).append(viewDiv);
}else {
} else {
//把视图添加到学生列表
loger.log("获取远程视频流成功->学生:"+userName+"->" +uid,new Date().getTime());
let viewDiv=`<div id="${this.xdyRemote + uid}" style="width:${this.normalRemoteVideoWidth}px;height:${this.normalRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
loger.log("获取远程视频流成功->学生:" + userName + "->" + uid, new Date().getTime());
let viewDiv = `<div id="${this.xdyRemote + uid}" style="width:${this.normalRemoteVideoWidth}px;height:${this.normalRemoteVideoHeight}px;float: left;margin-right: 1px;pointer-events: none;">${nameDiv}</div>`;
$(this.normalRemoteViewId).append(viewDiv);
}
//播放视频,隐藏控制条
try{
$("bar_"+stream.getId()).hide();
try {
$("bar_" + stream.getId()).hide();
stream.play(this.xdyRemote + stream.getId());
}catch (err){
} catch (err) {
}
if(user&&(user.deviceType==1||user.deviceType==2)){
this.remoteVideoList[user.nodeId]=stream;
if (user && (user.deviceType == 1 || user.deviceType == 2)) {
this.remoteVideoList[user.nodeId] = stream;
}
console.log("移动端远程视频流集合->",this.remoteVideoList);
console.log("移动端远程视频流集合->", this.remoteVideoList);
}
}
//重新添加远程视频
reAddRemoteStream(_stream){
if(!_stream){
reAddRemoteStream(_stream) {
if (!_stream) {
return;
}
let user=GlobalConfig.getUserRoleFromeNodeId(_stream.getId());
if(user.openCamera<=0){
loger.log("远程流已经停止,不需要再连接: " + _stream.getId(),new Date().getTime());
let user = GlobalConfig.getUserRoleFromeNodeId(_stream.getId());
if (user.openCamera <= 0) {
loger.log("远程流已经停止,不需要再连接: " + _stream.getId(), new Date().getTime());
return;
}
loger.log("添加一个远程视频流: " + _stream.getId(),new Date().getTime());
loger.log("添加一个远程视频流: " + _stream.getId(), new Date().getTime());
this.client.subscribe(_stream, (err)=> {
//clearTimeout(this.reAddRemoteStreamDelay);
if(err=="INVALID_REMOTE_STREAM"){
if (err == "INVALID_REMOTE_STREAM") {
//流已经无效,不需要再重连
loger.warn("流已经无效->不需要再重连", err);
return;
}
if(err=="PEERCONNECTION_FAILED"){
setTimeout(()=>{
loger.warn("连接远程的流失败->尝试重新连接",err);
if (err == "PEERCONNECTION_FAILED") {
setTimeout(()=> {
loger.warn("连接远程的流失败->尝试重新连接", err);
this.reAddRemoteStream(_stream);
},1400);
}else {
loger.warn("添加一个远程视频流->失败", err); }
}, 1400);
} else {
loger.warn("添加一个远程视频流->失败", err);
}
});
}
//尝试添加远程的移动设备视频流
tryAddMobileStream(nodeId){
let stream=this.remoteVideoList[nodeId];
if(!stream){
tryAddMobileStream(nodeId) {
let stream = this.remoteVideoList[nodeId];
if (!stream) {
return;
}
let remoteView=document.getElementById(this.xdyRemote +nodeId);
console.log("remoteView->",remoteView)
if(remoteView){
let player=document.getElementById("player_" +nodeId);
if(player){
loger.log(nodeId+" 流已经添加显示,不需要再处理");
let remoteView = document.getElementById(this.xdyRemote + nodeId);
console.log("remoteView->", remoteView)
if (remoteView) {
let player = document.getElementById("player_" + nodeId);
if (player) {
loger.log(nodeId + " 流已经添加显示,不需要再处理");
return;
}else {
loger.log(nodeId+" 删除无效的视图->创建新的视图remoteView");
} else {
loger.log(nodeId + " 删除无效的视图->创建新的视图remoteView");
remoteView.remove();
}
}
if(stream) {
if (stream) {
loger.log("收到移动端推流的消息,主动添加一个远程视频流");
this.addRemoetStreamView(stream);
}
}
joinChannel(_params) {
this.channelId = _params.channelId||"";
this.uid = parseInt(_params.uid)||0;
this.info =_params.info || "";
this.channelKey = _params.channelKey||null;
if (!this.client) {
loger.warn("入视频通话频道->失败->未初始化对象");
return;
}
this.channelId = _params.channelId || "";
this.uid = parseInt(_params.uid) || 0;
this.info = _params.info || "";
this.channelKey = _params.channelKey || null;
loger.log("开始加入视频通话频道->channelId:"+this.channelId,"uid:"+this.uid);
this.client.join(this.channelKey , ""+this.channelId, this.uid, (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);
loger.log("加入视频通话频道->成功->channelId:" + this.channelId, "uid:" + this.uid);
this._emit(MessageTypes.WEB_RTC_JOIN_SUCCESS);
this.openLoaclStream();
}, (err)=> {
... ... @@ -320,28 +329,29 @@ class WebRtcApe extends Emiter {
this._emit(MessageTypes.WEB_RTC_JOIN_FAILED);
});
}
//重新获取摄像头和麦克风并重新推流
reGetLoaclStream(){
if(this.isPublish){
reGetLoaclStream() {
if (this.isPublish) {
loger.log("重新获取摄像头和麦克风并重新推流");
//this.changePublishStatusAndServerRecord(WebRtcApe.RECORD_STATUS_0);
this.unpublish();
this.openLoaclStream();
//切换设备后自动重推流
this.rePublishDelay=setTimeout(()=>{
this.rePublishDelay = setTimeout(()=> {
this.publish();
},1200);
}, 1200);
//this.publish();
}else {
} else {
this.openLoaclStream();
}
}
openLoaclStream() {
/* if(this.localStream){
this.localStream.close();
this.localStream=null;
}*/
/* if(this.localStream){
this.localStream.close();
this.localStream=null;
}*/
this.localStream = AgoraRTC.createStream({
streamID: this.uid,
audio: true,
... ... @@ -369,60 +379,76 @@ class WebRtcApe extends Emiter {
});
}
closeRemoteVideoView(_data){
if(!_data){
closeRemoteVideoView(_data) {
if (!_data) {
return;
}
//根据nodeId查找视频
try{
try {
loger.log("立即删除停止推流人员的视图");
$('#' + this.xdyRemote + _data.nodeId).remove();
}catch (err){
} catch (err) {
}
}
/*
* 设置旁录地址
* */
setConfigPublisherUrl(_publishUrl){
loger.warn("设置旁路地址->",_publishUrl);
this.configPublisherUrl=_publishUrl;
if(this.client&& this.configPublisherUrl){
this.client.configPublisher(
{width: 320, height: 240, framerate: 15, bitrate: 200, publishUrl: this.configPublisherUrl}
);
}else {
loger.warn("设置旁路地址->失败->为初始化或旁路地址无效",_publishUrl);
}
}
publish(_params) {
if (!this.client||!this.localStream) {
if (!this.client || !this.localStream) {
return;
}
this.localStream.init(()=> {
let viewName='localVideoBox_'+this.uid;
let videoBox=document.createElement("div");
videoBox.id=viewName;
videoBox.style.width=this.localVideoWidth+'px';
videoBox.style.height=this.localVideoHeight+'px';
videoBox.style.float='left';
videoBox.style.marginRight="1px";
videoBox.style.pointerEvents='none';
let viewName = 'localVideoBox_' + this.uid;
let videoBox = document.createElement("div");
videoBox.id = viewName;
videoBox.style.width = this.localVideoWidth + 'px';
videoBox.style.height = this.localVideoHeight + 'px';
videoBox.style.float = 'left';
videoBox.style.marginRight = "1px";
videoBox.style.pointerEvents = 'none';
//自己的视图往前添加
$(this.localViewId).prepend(videoBox);
$("#"+viewName).css("transform", 'rotateY(180deg)');
$("#" + viewName).css("transform", 'rotateY(180deg)');
//显示自己的名字
let user=GlobalConfig.getUserInfoFromeNodeId(this.uid);
let userName="";
if(user){
userName=user.name||"";
let user = GlobalConfig.getUserInfoFromeNodeId(this.uid);
let userName = "";
if (user) {
userName = user.name || "";
}
let nameDiv=`<div id="${"videoOwnerName_"+this.uid}" style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
let nameDiv = `<div id="${"videoOwnerName_" + this.uid}" style="width:98%;height:20px; position: absolute; z-index: 1;left: 4px;overflow:hidden;font-size: 14px; color: #cccccc;display:${this.nameDisplay}">${userName}</div>`;
$(this.localViewId).prepend(nameDiv);
loger.log("webRtc->推流->",viewName,new Date().getTime());
loger.log("webRtc->推流->", viewName, new Date().getTime());
this.localStream.play(viewName);
this.client.publish(this.localStream, (err)=> {
loger.log("webRtc->推流失败: " + err);
GlobalConfig.openCamera =0;
GlobalConfig.openMicrophones =0;
this.isPublish=false;
GlobalConfig.openCamera = 0;
GlobalConfig.openMicrophones = 0;
this.isPublish = false;
this.unpublish();
});
}, (err)=> {
loger.warn("webRtc->推流->本地流开启失败", err);
this.isPublish=false;
this.isPublish = false;
this.clearLocalView();
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED,err);
if(err&&err.msg=="STREAM_ALREADY_INITIALIZED"){
this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED, err);
if (err && err.msg == "STREAM_ALREADY_INITIALIZED") {
this.unpublish();
}
});
... ... @@ -430,8 +456,8 @@ class WebRtcApe extends Emiter {
unpublish() {
clearTimeout(this.rePublishDelay);
loger.log("webRtc->停止推流 ",new Date().getTime());
if (!this.client||!this.localStream) {
loger.log("webRtc->停止推流 ", new Date().getTime());
if (!this.client || !this.localStream) {
return;
}
this.client.unpublish(this.localStream, (err)=> {
... ... @@ -439,9 +465,9 @@ class WebRtcApe extends Emiter {
});
this.localStream.close();
this.clearLocalView();
this.isPublish=false;
GlobalConfig.openCamera =0;
GlobalConfig.openMicrophones =0;
this.isPublish = false;
GlobalConfig.openCamera = 0;
GlobalConfig.openMicrophones = 0;
this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
nodeId: GlobalConfig.nodeId,
userRole: GlobalConfig.userRole,
... ... @@ -451,21 +477,23 @@ class WebRtcApe extends Emiter {
openMicrophones: GlobalConfig.openMicrophones
});
}
//清除本地视图
clearLocalView(){
clearLocalView() {
$('#localVideoBox_' + this.uid).remove();
$("#videoOwnerName_"+this.uid).remove();
$("#videoOwnerName_" + this.uid).remove();
}
/*
* 设置本地回显视图
* */
setLoaclView(_params) {
loger.log("设置自己本地回显视图");
this.localViewId = _params.divId||"";
this.localStyle = _params.styleStr||"";
this.localVideoWidth=parseInt(_params.width)||320;
this.localVideoHeight=parseInt(_params.height)||240;
this.nameDisplay=_params.nameDisplay||"block";
this.localViewId = _params.divId || "";
this.localStyle = _params.styleStr || "";
this.localVideoWidth = parseInt(_params.width) || 320;
this.localVideoHeight = parseInt(_params.height) || 240;
this.nameDisplay = _params.nameDisplay || "block";
}
/*
... ... @@ -473,10 +501,10 @@ class WebRtcApe extends Emiter {
* */
setHostRemoteMediaView(_params) {
loger.log("设置老师视图容器");
this.hostRemoteViewId = _params.divId||"";
this.hostRemoteStyle = _params.styleStr||"";
this.hostRemoteVideoWidth=parseInt(_params.width)||320;
this.hostRemoteVideoHeight=parseInt(_params.height)||240;
this.hostRemoteViewId = _params.divId || "";
this.hostRemoteStyle = _params.styleStr || "";
this.hostRemoteVideoWidth = parseInt(_params.width) || 320;
this.hostRemoteVideoHeight = parseInt(_params.height) || 240;
}
/*
... ... @@ -484,10 +512,10 @@ class WebRtcApe extends Emiter {
* */
setNormalRemoteMediaView(_params) {
loger.log("设置学生视图容器");
this.normalRemoteViewId = _params.divId||"";
this.normalRemoteStyle = _params.styleStr||"";
this.normalRemoteVideoWidth=parseInt(_params.width)||320;
this.normalRemoteVideoHeight=parseInt(_params.height)||240;
this.normalRemoteViewId = _params.divId || "";
this.normalRemoteStyle = _params.styleStr || "";
this.normalRemoteVideoWidth = parseInt(_params.width) || 320;
this.normalRemoteVideoHeight = parseInt(_params.height) || 240;
}
/*
... ... @@ -495,80 +523,81 @@ class WebRtcApe extends Emiter {
* */
setInvisibleMediaView(_params) {
loger.log("设置监课视图容器");
this.invisibleViewId = _params.divId||"";
this.invisibleStyle = _params.styleStr||"";
this.invisibleVideoWidth=parseInt(_params.width)||320;
this.invisibleVideoHeight=parseInt(_params.height)||240;
this.invisibleViewId = _params.divId || "";
this.invisibleStyle = _params.styleStr || "";
this.invisibleVideoWidth = parseInt(_params.width) || 320;
this.invisibleVideoHeight = parseInt(_params.height) || 240;
}
/*
* 切换当前使用的设备
* */
changeDevices(_params){
loger.log("切换设备->",_params);
if(!_params){
* 切换当前使用的设备
* */
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;
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;
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
if (_params.videoResolution) {
this.videoResolution = _params.videoResolution || "240P";//默认是240P 20 320x240 15 200
}
clearTimeout(this.changeDevicesDelay);
this.changeDevicesDelay=setTimeout(()=>{
this.changeDevicesDelay = setTimeout(()=> {
this.changePublishStatusAndServerRecord(WebRtcApe.RECORD_STATUS_0);
//重新获取本地视图流
this.reGetLoaclStream();
},1400);
}, 1400);
}
/*
* 获取设备信息
* */
getDevices(_params,_callback) {
* 获取设备信息
* */
getDevices(_params, _callback) {
AgoraRTC.getDevices((devices)=> {
//下面的数组存的是对象
this.microphones=[];
this.cameras=[];
this.microphones = [];
this.cameras = [];
//选的数组存的是设备名称
GlobalConfig.cameras=[];
GlobalConfig.microphones=[];
GlobalConfig.cameras = [];
GlobalConfig.microphones = [];
loger.log("devices", devices)
for (let i = 0; i < devices.length; i++) {
let device = devices[i];
//{"deviceId":"default","kind":"audiooutput","label":"默认","groupId":"cf49a03ca26700235629fc13d3e6630bd34407c66438d157056a34dd3ae03ef5"}
if (device.kind == 'audioinput') {
if(!device.label){
device.label="麦克风_"+i;
if (!device.label) {
device.label = "麦克风_" + i;
}
this.microphones.push(device);
GlobalConfig.microphones.push(device.label);
} else if (device.kind == 'videoinput') {
if(!device.label){
device.label="摄像头_"+i;
if (!device.label) {
device.label = "摄像头_" + i;
}
this.cameras.push(device);
GlobalConfig.cameras.push(device.label);
... ... @@ -576,45 +605,45 @@ class WebRtcApe extends Emiter {
loger.warn('其他设备: ', device);
}
}
let _deviceData={cameras:GlobalConfig.cameras,microphones:GlobalConfig.microphones};
if(_callback){
let _deviceData = {cameras: GlobalConfig.cameras, microphones: GlobalConfig.microphones};
if (_callback) {
_callback(_deviceData);
}
this._emit(MessageTypes.GET_DEVICES_SUCCESS,_deviceData);
this._emit(MessageTypes.GET_DEVICES_SUCCESS, _deviceData);
});
}
//组织数据,发送给服务器,控制录制和开启录制-推流和停止推流 status:0 停止推流 1:开始推流(同时开启录制),2:停止录制(同时停止推流)
packMediaInfoData(_status){
let curTimestamp= new Date().getTime();
let data=`appId=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.appCertificate}&uid=${GlobalConfig.userUid}&status=${_status}&userId=${GlobalConfig.userId}&userName=${GlobalConfig.userName}&userRole=${GlobalConfig.userRole}&timestamp=${curTimestamp}&recordTimestamp=${GlobalConfig.recordTimestamp}`;
//mcu记录一份数据
this._emit(MessageTypes.MEDIA_PUBLISH_STATUS_CHANGE, {
appId:GlobalConfig.appId,
channel:GlobalConfig.channelId,
channelKey:GlobalConfig.appCertificate,
uid:GlobalConfig.userUid,
status:_status,
userId:GlobalConfig.userId,
userName:GlobalConfig.userName,
userRole:GlobalConfig.userRole,
timestamp:curTimestamp,
recordTimestamp:GlobalConfig.recordTimestamp
});
packMediaInfoData(_status) {
let curTimestamp = new Date().getTime();
let data = `appId=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.appCertificate}&uid=${GlobalConfig.userUid}&status=${_status}&userId=${GlobalConfig.userId}&userName=${GlobalConfig.userName}&userRole=${GlobalConfig.userRole}&timestamp=${curTimestamp}&recordTimestamp=${GlobalConfig.recordTimestamp}`;
//mcu记录一份数据
this._emit(MessageTypes.MEDIA_PUBLISH_STATUS_CHANGE, {
appId: GlobalConfig.appId,
channel: GlobalConfig.channelId,
channelKey: GlobalConfig.appCertificate,
uid: GlobalConfig.userUid,
status: _status,
userId: GlobalConfig.userId,
userName: GlobalConfig.userName,
userRole: GlobalConfig.userRole,
timestamp: curTimestamp,
recordTimestamp: GlobalConfig.recordTimestamp
});
return data;
}
//调用服务端接口
//调用推流/停止推流->并且告诉服务器端开启录制
//status:0 停止推流 1:开始推流(同时开启录制),2:停止录制(同时停止推流)
changePublishStatusAndServerRecord(_status){
if(!GlobalConfig.recordInterfaces){
changePublishStatusAndServerRecord(_status) {
if (!GlobalConfig.recordInterfaces) {
loger.log("调用服务器端开启录制->失败->接口地址无效");
return;
}
let url=GlobalConfig.locationProtocol+GlobalConfig.recordInterfaces;
let data=this.packMediaInfoData(_status);
let url = GlobalConfig.locationProtocol + GlobalConfig.recordInterfaces;
let data = this.packMediaInfoData(_status);
fetch(encodeURI(url), {
method: 'POST',
headers: {
... ... @@ -633,7 +662,7 @@ class WebRtcApe extends Emiter {
})
.then(ret => {
if (ret) {
loger.log('调用服务器端开启录制完成',ret);
loger.log('调用服务器端开启录制完成', ret);
} else {
loger.warn('调用服务器端开启录制 失败.', ret);
}
... ... @@ -644,14 +673,14 @@ class WebRtcApe extends Emiter {
}
//调用媒体服务停止录制
stopRecordingMedia(){
stopRecordingMedia() {
//192.168.31.8:3000/recordInfo/stopRecording/
if(!GlobalConfig.stopRecordingInterfaces){
if (!GlobalConfig.stopRecordingInterfaces) {
loger.log("调用服务器端开启录制->失败->接口地址无效");
return;
}
let url=GlobalConfig.locationProtocol+GlobalConfig.stopRecordingInterfaces;
let data=this.packMediaInfoData(WebRtcApe.RECORD_STATUS_2);
let url = GlobalConfig.locationProtocol + GlobalConfig.stopRecordingInterfaces;
let data = this.packMediaInfoData(WebRtcApe.RECORD_STATUS_2);
fetch(encodeURI(url), {
method: 'POST',
headers: {
... ... @@ -670,7 +699,7 @@ class WebRtcApe extends Emiter {
})
.then(ret => {
if (ret) {
loger.log('调用服务器端开启录制完成',ret);
loger.log('调用服务器端开启录制完成', ret);
} else {
loger.warn('调用服务器端开启录制 失败.', ret);
}
... ... @@ -680,9 +709,9 @@ class WebRtcApe extends Emiter {
});
}
}
WebRtcApe.prototype.RECORD_STATUS_0 = WebRtcApe.RECORD_STATUS_0 =0; //停止推流
WebRtcApe.prototype.RECORD_STATUS_1 = WebRtcApe.RECORD_STATUS_1 =1; //开始推流
WebRtcApe.prototype.RECORD_STATUS_2 = WebRtcApe.RECORD_STATUS_2 =2; //停止录制
WebRtcApe.prototype.RECORD_STATUS_0 = WebRtcApe.RECORD_STATUS_0 = 0; //停止推流
WebRtcApe.prototype.RECORD_STATUS_1 = WebRtcApe.RECORD_STATUS_1 = 1; //开始推流
WebRtcApe.prototype.RECORD_STATUS_2 = WebRtcApe.RECORD_STATUS_2 = 2; //停止录制
export default new WebRtcApe;
... ...