后台
nodejs , kurento
hhKmsV20.js
const kurento = require("kurento-client");
var db = require('./db');
var mqtt = require('mqtt');
var path = require('path');
var fs = require('fs');
var format = require('string-format');
const e = require("express");
format.extend(String.prototype);
class TKmsSession{
constructor(){
this.sessionId = ['sid' , ( new Date()).getTime() , parseInt( 1000* Math.random())].join("");
this.end = null;
this.endName ="";
this.endInfo = {};
this.onEndCandidate = null;
this.pipe = null;
this.candidateBuf=[];
}
}
class TKmsV20{
constructor(){
this.config={
kmsUrl:"ws://127.0.0.1:8888/kurento",
tagKey:"tagKey_KmsV20"
}
this.kmsClient = null;
this.kmsObjs ={};
this.sessions={};
this.candidateBuf={};
}
log( logData ){
console.log(logData);
}
getClient(){
var me = this;
return new Promise( (success , faild)=>{
try{
var client = me['kmsClient'];
if( !client){
kurento( me.config.kmsUrl , function (erClient , _client) {
me['kmsClient'] = _client;
_client.on('disconnect', function () {
delete me['kmsClient']
})
success(_client);
})
}
else{
success(client);
}
}
catch(er){
me.log(er);
success();
}
})
}
getKmsObjects(client){
var me = this;
return new Promise( (success , faild)=>{
try{
me.kmsObjs = {};
client.getServerManager().then(svr=>{
return svr.getPipelines();
}).then(pipes=>{
var scanPipes = function () {
if( pipes.length>0){
var p = pipes.shift();
me.getKmsObjData(p).then(pipe=>{
me.kmsObjs[pipe.id] = pipe;
pipe.getChildren().then(objs=>{
var scanObjs = function () {
if( objs.length>0){
var o = objs.shift();
me.getKmsObjData(o).then(obj=>{
me.kmsObjs[obj.id] = obj;
scanObjs();
})
}
else{
scanPipes();
}
}
scanObjs();
})
})
}
else{
success();
}
}
scanPipes();
})
}
catch(er){
me.log(er);
success();
}
})
}
setKmsObjData( obj , objName , objInfo){
var me = this;
return new Promise( (success , faild)=>{
try{
if( obj && obj!=null){
obj.setName( objName , function (erName) {
var info = ( objInfo && objInfo!=null)? objInfo :{};
info.name = objName;
info.kmsId = obj.id;
var content = JSON.stringify(info);
obj.addTag( me.config.tagKey , content).then(_=>{
obj.info = info;
obj.name = objName;
me.kmsObjs[obj.id] = obj;
success(obj);
})
})
}
else{
success(obj);
}
}
catch(er){
me.log(er);
success();
}
})
}
getKmsObjData( obj ){
var me = this;
return new Promise( (success , faild)=>{
try{
if( obj && obj!=null){
obj.getName( function (erName , name ) {
obj.name = name;
obj.info = {
name : name ,
kmsId: obj.id
};
obj.getTag( me.config.tagKey , function (erTag , tagContent) {
if( (!erTag) &&(tagContent && tagContent!=null)){
var info = {};
try{
info = JSON.parse( tagContent);
obj.info = info;
}
catch(eer){
;
}
}
success(obj);
})
})
}
else{
success(obj);
}
}
catch(er){
me.log(er);
success();
}
})
}
findObjByName( objName ){
var me = this;
var arrs = Object.values(me.kmsObjs).filter(o=>{
return o.name == objName;
});
return arrs.length>0? arrs[0]: null;
}
getSingletonPipeline( pipeName , pipeInfo ){
var me = this;
return new Promise( (success , faild)=>{
try{
var pipe = me.findObjByName(pipeName);
if( pipe!=null){
success(pipe);
}
else{
me.getClient().then( client=>{
client.create("MediaPipeline").then(p=>{
return me.setKmsObjData(p , pipeName , pipeInfo)
}).then( np=>{
success(np);
})
})
}
}
catch(er){
me.log(er);
success();
}
})
}
getSingletonPlayer( pipeName , playerName , playerUrl , playerInfo ){
var me = this;
return new Promise( (success , faild)=>{
try{
var player = me.findObjByName(playerName);
if( player != null){
success(player);
}
else{
var pipe = me.findObjByName(pipeName);
if( pipe==null){
success(null);
}
else{
pipe.create("PlayerEndpoint", {uri: playerUrl}).then(p=>{
return me.setKmsObjData(p , playerName , playerInfo)
}).then( np=>{
np.on("EndOfStream" , function () {
np.play();
})
np.play();
success(np);
})
}
}
}
catch(er){
me.log(er);
success();
}
})
}
createSession( pipeName ,endName , endInfo , onCandidate){
var me = this;
return new Promise( (success , faild)=>{
try{
var session = new TKmsSession();
me.sessions[session.sessionId] = session;
session.endName = endName ;
session.endInfo = endInfo ;
session.onEndCandidate = onCandidate;
session.pipe = me.findObjByName(pipeName);
session.iceSever ={
stunAddress:"",
stunPort:0,
turnUrl:""
};
if( session.pipe==null){
success(null);
}
else{
session.pipe.create("WebRtcEndpoint").then(end=>{
session.end = end;
return me.setKmsObjData( end , endName , endInfo)
}).then( end=>{
end.on('OnIceCandidate', function(event) {
var candidate = kurento.getComplexType('IceCandidate')(event.candidate);
if( session.onEndCandidate && session.onEndCandidate!=null){
try{
session.onEndCandidate(session.sessionId, candidate);
}
catch(eer){
me.log(eer);
}
}
});
while( session.candidateBuf.length>0){
var candidate = session.candidateBuf.shift();
end.addIceCandidate(candidate);
}
return end.getStunServerAddress();
}).then(stunAddress=>{
session.iceSever.stunAddress = stunAddress;
return session.end.getStunServerPort()
}).then( stunPort=>{
session.iceSever.stunPort = stunPort;
return session.end.getTurnUrl()
}).then( turnUrl=>{
session.iceSever.turnUrl = turnUrl;
success(session);
})
}
}
catch(er){
me.log(er);
success();
}
})
}
onPeerCandidate(sessionId , candidate){
var me = this;
try{
if( me.sessions[sessionId] ){
var session = me.sessions[sessionId];
if( session.end && session.end!=null){
session.end.addIceCandidate(candidate);
}
else{
session.candidateBuf.push(candidate);
}
}
}
catch(er){
me.log(er);
}
}
onPeerOffer(sessionId , sdpOffer){
var me = this;
return new Promise((success , faild)=>{
try{
if( me.sessions[sessionId] ){
var session = me.sessions[sessionId];
var end = session.end;
while( session.candidateBuf.length>0){
var candidate = session.candidateBuf.shift();
end.addIceCandidate(candidate);
}
end.processOffer( sdpOffer, function(erAnswer , sdpAnswer){
if( erAnswer ){
success(null)
}
else{
end.gatherCandidates(function(ere){
success({
sessionId: session.sessionId ,
sdpAnswer:sdpAnswer
});
})
}
})
}
}
catch(er){
me.log(er);
}
})
}
freeObj( obj ){
var me = this;
return new Promise((success , faild)=>{
try{
if( obj && obj!=null){
if( me.kmsObjs[obj.id]){
delete me.kmsObjs[obj.id];
}
obj.release(function (erFree) {
success();
})
}
else{
success();
}
}
catch(er){
me.log(er);
}
})
}
connectMedia( srcId , targetId , mediaType){
var me = this;
return new Promise((success , faild)=>{
try{
var res={
status:0 ,
srcFlag:0 ,
targetFlag:0
}
var src = null;
var target = null;
if( me.kmsObjs[srcId]){
src = me.kmsObjs[srcId];
res.srcFlag = 1;
}
if( me.kmsObjs[targetId]){
target = me.kmsObjs[targetId];
res.targetFlag = 1;
}
if( res.srcFlag >0 && res.targetFlag>0){
if( mediaType && mediaType!=null && (mediaType=="AUDIO" || mediaType=="VIDEO")){
src.connect(target , mediaType , function (erConn) {
res.status = (!erConn) ? 1:0 ;
success(res);
})
}
else{
src.connect(target , function (erConn) {
res.status = (!erConn) ? 1:0 ;
success(res);
})
}
}
else{
success(res);
}
}
catch(er){
me.log(er);
}
})
}
resetPipe( pipeName , pipeInfo){
var me = this;
return new Promise((success , faild)=>{
try{
var pipe = me.findObjByName(pipeName);
if( pipe==null){
me.getSingletonPipeline(pipeName , pipeInfo).then(np=>{
success(np);
});
}
else{
pipe.getChildren().then(objs=>{
var freeObjs= function () {
if( objs.length>0 ){
var obj = objs.shift();
me.freeObj(obj).then(_=>{
freeObjs();
})
}
else{
me.freeObj(pipe).then(_=>{
me.getSingletonPipeline(pipeName , pipeInfo).then(np=>{
success(np);
});
})
}
}
freeObjs();
})
}
}
catch(er){
me.log(er);
}
})
}
resetPlayer( pipeName , playerName , playerUrl , playerInfo ){
var me = this;
return new Promise( (success , faild)=>{
try{
var player = me.findObjByName(playerName);
if( player==null){
me.getSingletonPlayer(pipeName , playerName , playerUrl , playerInfo).then(np=>{
success(np);
})
}
else{
me.freeObj(player).then(_=>{
me.getSingletonPlayer(pipeName , playerName , playerUrl , playerInfo).then(np=>{
success(np);
})
})
}
}
catch(er){
me.log(er);
success();
}
})
}
}
class TMqV20{
constructor(){
this.config={
appId:"webrtc",
mq:{
clientId:"",
url:"tcp://gmggf8g.mqtt.iot.bj.baidubce.com:1883",
uid:"gmggf8g/peer",
pwd:"XXXXX"
}
}
this.mqClient = null;
this.actionHandler ={};
}
log( logData ){
console.log(logData);
}
openMq( ){
var me = this;
return new Promise((success, faild)=>{
try{
me.config.mq.clientId = (me.config.mq.clientId =="")?['scid',(new Date()).getTime() , parseInt(1000*Math.random())].join(""):me.config.mq.clientId ;
var options={
username: me.config.mq.uid ,
password: me.config.mq.pwd ,
clientId: me.config.clientId
};
var client=mqtt.connect( me.config.mq.url , options );
me.mqClient = client;
client.on('connect', function () {
console.log("connected to broker. topic:",topic) ;
var topic = 'hh/'+me.config.appId+"/svr/#";
client.subscribe([topic]);
console.log('mq topic :' , topic);
success( );
});
client.on('close',function(){
console.log("connection closed");
});
client.on('message', function (topic, message) {
var msg=JSON.parse(message.toString());
try{
if( msg.id && msg.id!=null && msg.id!=""){
var action = me.actionHandler[msg.id];
if( action && action!=null && action instanceof Function){
action(msg);
}
else{
console.log('rec Msg' , msg);
}
}
else
console.log('rec Msg' , msg);
}
catch(exr){
console.log(exr)
}
});
success();
}
catch(er){
me.log(er);
success();
}
})
}
respMsg( clientId , msgId , msgBody , reqId ){
var me = this;
try{
var topic = 'hh/'+me.config.appId+"/"+ clientId;
var msg = {
id:msgId ,
clientId:clientId ,
body:msgBody
};
if( reqId && reqId!=null && reqId!=""){
msg.reqId = reqId;
}
me.mqClient.publish(topic , JSON.stringify(msg));
}
catch(er){
me.log(er);
success();
}
}
}
class TMqKms {
constructor(){
this.config={
appId:"webrtc",
kms:{
kmsUrl:"ws://127.0.0.1:8888/kurento",
},
mq:{
clientId:"",
url:"tcp://gmggf8g.mqtt.iot.bj.baidubce.com:1883",
uid:"gmggf8g/peer",
pwd:"a52bwKg22dCAuQzB"
}
}
this.kms = new TKmsV20();
this.mq = new TMqV20();
}
log( logData ){
console.log(logData);
}
open(){
var me = this;
return new Promise( (success , faild)=>{
try{
me.kms.config.kmsUrl = me.config.kms.kmsUrl;
me.mq.config.appId = me.config.appId;
me.mq.config.mq = me.config.mq;
me.registActionHandler();
me.kms.getClient().then( client=>{
return me.kms.getKmsObjects(client);
}).then(_=>{
return me.mq.openMq();
}).then(_=>{
success();
});
}
catch(er){
me.log(er);
success();
}
})
}
registActionHandler(){
var me = this;
try{
me.mq.actionHandler.hello = function (msg) {
console.log( msg);
};
me.mq.actionHandler.getPipe = function (msg) {
try{
var pipeName = msg.body.pipeName ;
var pipeInfo = msg.body.pipeInfo ;
me.kms.getSingletonPipeline( pipeName , pipeInfo ).then(pipe=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , pipe.info , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.resetPipe = function (msg) {
try{
var pipeName = msg.body.pipeName ;
var pipeInfo = msg.body.pipeInfo ;
me.kms.resetPipe( pipeName , pipeInfo ).then(pipe=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , pipe.info , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.getPlayer = function (msg) {
try{
var pipeName = msg.body.pipeName ;
var playerName = msg.body.playerName ;
var playerInfo = msg.body.playerInfo ;
var playerUrl = msg.body.playerUrl ;
me.kms.getSingletonPlayer( pipeName , playerName , playerUrl , playerInfo ).then(player=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , player.info , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.resetPlayer = function (msg) {
try{
var pipeName = msg.body.pipeName ;
var playerName = msg.body.playerName ;
var playerInfo = msg.body.playerInfo ;
var playerUrl = msg.body.playerUrl ;
me.kms.resetPlayer( pipeName , playerName , playerUrl , playerInfo ).then(player=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , player.info , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.createSession = function (msg) {
try{
var pipeName = msg.body.pipeName ;
var endName = msg.body.endName ;
var endInfo = msg.body.endInfo ;
var onCandidate = function (sessionId , candidate) {
var msgBody ={
sessionId : sessionId ,
candidate : candidate
}
me.mq.respMsg( msg.clientId , "onEndCandidate" , msgBody );
}
me.kms.createSession( pipeName ,endName , endInfo , onCandidate ).then(session=>{
var info ={
sessionId: session.sessionId ,
iceServer : session.iceSever ,
endId: session.end.id
}
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , info , msg.reqId );
})
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.peerCandidate = function (msg) {
try{
var sessionId = msg.body.sessionId;
var candidate = msg.body.candidate;
me.kms.onPeerCandidate(sessionId, candidate);
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.peerSdpOffer = function (msg) {
try{
var sessionId = msg.body.sessionId;
var sdpOffer = msg.body.sdpOffer;
me.kms.onPeerOffer(sessionId, sdpOffer).then(res=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , res , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
me.mq.actionHandler.connectMedia = function (msg) {
try{
var srcId = msg.body.srcId;
var targetId = msg.body.targetId;
var mediaType = msg.body.mediaType;
me.kms.connectMedia(srcId , targetId , mediaType).then(res=>{
me.mq.respMsg( msg.clientId , "resp_"+ msg.id , res , msg.reqId );
});
}
catch(er){
me.log(er);
}
};
}
catch(er){
me.log(er);
}
}
}
var kms = new TMqKms();
kms.open();
前端库
/*
lib for TMqKmsV20(TKmsV20 , TMqV20 )
*/
var hhKmsV20={
config:{
appId:"webrtc" ,
apiUrl:"https://wss.hhdata.cn:20038" ,
mq:{
host:"gmggf8g.mqtt.iot.bj.baidubce.com",
port:443,
uid:"gmggf8g/peer",
pwd:"a52bwKg22dCAuQzB",
clientId:""
},
kmsPeerOptions :{
configuration: {
"iceServers": [
{
urls: "stun:223.68.161.139:3478"
//urls: "stun:223.112.194.253:40016"
},
{
urls: ["turn:223.68.161.139:3478" ],
//urls: ["turn:223.112.194.253:40016" ],
username: "kurento",
credential: "kurento"
}
]
},
mediaConstraints: {
audio: true,
//video: {width: {exact: 1280}, height: {exact: 720}},
video: {
width: { min: 1280, ideal: 1280, max: 1920 },
height: { min: 720, ideal: 720 , max: 1080}
}
}
},
kmsPeerTypes : {
s: kurentoUtils.WebRtcPeer.WebRtcPeerSendonly,
r: kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly,
sr: kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv
}
},
objs:{
mqClient: null,
sessions : {}
},
log(data){
console.log(data);
},
open(acHandler){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
me.config.mq.clientId = (me.config.mq.clientId =="")?['scid',(new Date()).getTime() , parseInt(1000*Math.random())].join(""):me.config.mq.clientId ;
me.objs.mqClient = createNewMqClient( me.config.appId ,
me.config.mq.host ,
me.config.mq.port ,
me.config.mq.uid ,
me.config.mq.pwd ,
me.config.mq.clientId ,
"");
var handler = me.getActionHandler();
if( acHandler && acHandler!=null){
Object.keys(acHandler).forEach(acKey=>{
handler[acKey] = acHandler[acKey];
})
}
openMqClient( me.objs.mqClient , handler).then( client =>{
me.objs.mqClient = client;
var flag = client && client!=null && client.isConnected();
if( flag ){
var topic = "hh/"+ me.config.appId+"/"+ me.config.mq.clientId+"/#";
client.subscribe(topic);
}
success(client);
})
}
catch(er) {
hhKmsV20.log(er);
}
})
},
getActionHandler( ){
var me = hhKmsV20;
handler ={};
try{
//接收到end.candidate
handler.onEndCandidate = function (msg) {
try{
var sessionId = msg.body.sessionId;
var candidate = msg.body.candidate;
if( !me.objs.sessions[sessionId]){
me.objs.sessions[sessionId]={
sessionId: sessionId ,
peer: null ,
candidates:[]
}
}
var session = me.objs.sessions[sessionId];
if( session.peer ==null){
session.candidates.push( candidate );
}
else{
session.peer.addIceCandidate(candidate);
}
}
catch(eer){
me.log(eer)
}
}
}
catch(er) {
hhKmsV20.log(er);
}
return handler;
},
requestMsg( msgId , msgBody ){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
me.objs.mqClient.requestMsg(msgId,msgBody).then(msg=>{
success(msg);
})
}
catch(er) {
hhKmsV20.log(er);
}
})
},
sendMsg(topic , msgId , msgBody ){
var me = hhKmsV20;
try{
me.objs.mqClient.sendMsg(topic , msgId,msgBody)
}
catch(er) {
hhKmsV20.log(er);
}
},
sendMsg2Svr( msgId , msgBody ){
var me = hhKmsV20;
try{
me.objs.mqClient.sendMsg2Svr( msgId,msgBody)
}
catch(er) {
hhKmsV20.log(er);
}
},
getPipe( pipeName , pipeInfo){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
pipeName: pipeName ,
pipeInfo: pipeInfo
};
me.requestMsg("getPipe" , msgBody ).then(res=>{
success(res);
});
}
catch(er) {
hhKmsV20.log(er);
}
})
},
resetPipe( pipeName , pipeInfo){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
pipeName: pipeName ,
pipeInfo: pipeInfo
};
me.requestMsg("resetPipe" , msgBody ).then(res=>{
success(res);
});
}
catch(er) {
hhKmsV20.log(er);
}
})
},
getPlayer( pipeName , playerName , playerUrl , playerInfo){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
pipeName: pipeName ,
playerName: playerName ,
playerUrl:playerUrl ,
playerInfo: pipeInfo
};
me.requestMsg("getPlayer" , msgBody ).then(res=>{
success(res);
});
}
catch(er) {
hhKmsV20.log(er);
}
})
},
resetPlayer( pipeName , playerName , playerUrl , playerInfo){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
pipeName: pipeName ,
playerName: playerName ,
playerUrl:playerUrl ,
playerInfo: pipeInfo
};
me.requestMsg("resetPlayer" , msgBody ).then(res=>{
success(res);
});
}
catch(er) {
hhKmsV20.log(er);
}
})
},
connectMedia( srcId , targetId , mediaType){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
srcId: srcId ,
targetId: targetId,
mediaType: mediaType
};
me.requestMsg("connectMedia" , msgBody ).then(res=>{
success(res);
});
}
catch(er) {
hhKmsV20.log(er);
}
})
},
createSession( pipeName , peerType , localVideo , remoteVideo , endName , endInfo){
var me = hhKmsV20;
return new Promise((success , faild)=>{
try{
var msgBody ={
pipeName: pipeName ,
endName: endName,
endInfo: endInfo
};
me.requestMsg("createSession" , msgBody ).then(sessionInfo=>{
var sessionId = sessionInfo.body.sessionId;
var endId = sessionInfo.body.endId;
var iceServer = sessionInfo.body.iceServer;
var session = {
sessionId: sessionId ,
peer: null ,
candidates:[]
};
me.objs.sessions[sessionId] = session;
var opts=JSON.parse(JSON.stringify( me.config.kmsPeerOptions));
opts.configuration.iceServers=[];
var stun = "stun://"+iceServer.stunAddress +":"+ iceServer.stunPort;
opts.configuration.iceServers.push({urls: stun});
var turnArr = iceServer.turnUrl.split("@");
var turnUrl = "turn:" + turnArr[1];
var userPwd = turnArr[0].split(":")
var userName = userPwd[0];
var pwd = userPwd[0];
opts.configuration.iceServers.push({
urls: [ turnUrl ],
username: userName,
credential: pwd
})
opts.onicecandidate = function (candidate , wp) {
var msgBody ={
sessionId: sessionId ,
candidate: candidate
}
me.sendMsg2Svr("peerCandidate", msgBody);
}
if( peerType=="s" || peerType =="sr"){
opts.localVideo = localVideo;
}
if( peerType=="r" || peerType =="sr"){
opts.remoteVideo = remoteVideo;
}
var factory = me.config.kmsPeerTypes[peerType];
var peer = factory( opts , function (erPeer) {
session.peer = peer;
peer.sessionId = sessionId ;
peer.endId = endId;
while( session.candidates.length>0){
var candidate = session.candidates.shift();
peer.addIceCandidate(candidates);
};
peer.generateOffer( function (er , offer , wp) {
var msgBody={
sessionId : sessionId,
sdpOffer: offer
};
me.requestMsg( "peerSdpOffer" , msgBody).then( recMsg=>{
peer.sessionId = recMsg.body.sessionId ;
var sdpAnswer = recMsg.body.sdpAnswer ;
peer.processAnswer( sdpAnswer , function (erAnswer) {
success(peer);
})
})
})
})
});
}
catch(er) {
hhKmsV20.log(er);
}
})
}
}
HTML调用
var acHandler ={};
hhKmsV20.open(acHandler).then(mqClient=>{
console.log(mqClient.clientId);
var pipeName = "kmsV20Pipe"
hhKmsV20.getPipe( pipeName ,{version:2.0}).then(pipeRes=>{
console.log(pipeRes);
var peerType ="sr" ;
var localVideo = document.getElementById('lv') ;
var remoteVideo = document.getElementById('rv') ;
var endName = "end-"+ hhKmsV20.config.mq.clientId ;
var endInfo ={
app:"hhKmsV20-App" ,
endUser:"张三"
}
return hhKmsV20.createSession(pipeName , peerType , localVideo , remoteVideo , endName , endInfo)
}).then(peer=>{
console.log(peer);
var srcId = peer.endId;
var targetId = peer.endId;
return hhKmsV20.connectMedia( srcId,targetId,"VIDEO" )
}).then(connRes=>{
console.log(connRes)
})
})