Webrtc视频聊天在不同网络中不工作

Webrtc视频聊天在不同网络中不工作,webrtc,turn,coturn,Webrtc,Turn,Coturn,我正在尝试使用来自的代码实现与webrtc的视频聊天。它可以在同一个网络上正常工作,但不能在不同的网络上工作。我已经在我的服务器上安装了coturn。我不确定它是否工作正常 有人用过谷歌代码实验室的代码并让它工作了吗 这是修改后的main.js文件 'use strict'; var isChannelReady = false; var isInitiator = false; var isStarted = false; var localStream; var pc; var remot

我正在尝试使用来自的代码实现与webrtc的视频聊天。它可以在同一个网络上正常工作,但不能在不同的网络上工作。我已经在我的服务器上安装了coturn。我不确定它是否工作正常

有人用过谷歌代码实验室的代码并让它工作了吗

这是修改后的main.js文件

'use strict';

var isChannelReady = false;
var isInitiator = false;
var isStarted = false;
var localStream;
var pc;
var remoteStream;
var turnReady;

var pcConfig = {
  "iceServers":[
      {'urls': 'stun:stun.l.google.com:19302'},
      {"urls":["turn:78.129.167.90"],"username":"wyzturner1","credential":"wyzturnp2ss"}]
};

// Set up audio and video regardless of what devices are present.
var sdpConstraints = {
  offerToReceiveAudio: true,
  offerToReceiveVideo: true
};

/////////////////////////////////////////////

var room = 'foo';
// Could prompt for room name:
// room = prompt('Enter room name:');

var socket = io.connect('https://www.samplesite.com:8080');

if (room !== '') {
  socket.emit('create or join', room);
  console.log('Attempted to create or  join room', room);
}

socket.on('created', function(room) {
  console.log('Created room ' + room);
  isInitiator = true;
});

socket.on('full', function(room) {
  console.log('Room ' + room + ' is full');
});

socket.on('join', function (room){
  console.log('Another peer made a request to join room ' + room);
  console.log('This peer is the initiator of room ' + room + '!');
  isChannelReady = true;
});

socket.on('joined', function(room) {
  console.log('joined: ' + room);
  isChannelReady = true;
});

socket.on('log', function(array) {
  console.log.apply(console, array);
});

////////////////////////////////////////////////

function sendMessage(message) {
  console.log('Client sending message: ', message);
  socket.emit('message', message);
}

// This client receives a message
socket.on('message', function(message) {
  console.log('Client received message:', message);
  if (message === 'got user media') {
    maybeStart();
  } else if (message.type === 'offer') {
    if (!isInitiator && !isStarted) {
      maybeStart();
    }
    pc.setRemoteDescription(new RTCSessionDescription(message));
    doAnswer();
  } else if (message.type === 'answer' && isStarted) {
    pc.setRemoteDescription(new RTCSessionDescription(message));
  } else if (message.type === 'candidate' && isStarted) {
    var candidate = new RTCIceCandidate({
      sdpMLineIndex: message.label,
      candidate: message.candidate
    });
    pc.addIceCandidate(candidate);
  } else if (message === 'bye' && isStarted) {
    handleRemoteHangup();
  }
});

////////////////////////////////////////////////////

var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');

navigator.mediaDevices.getUserMedia({
  audio: false,
  video: true
})
.then(gotStream)
.catch(function(e) {
  alert('getUserMedia() error: ' + e.name);
});

function gotStream(stream) {
  console.log('Adding local stream.');
  localVideo.src = window.URL.createObjectURL(stream);
  localStream = stream;
  sendMessage('got user media');
  if (isInitiator) {
    maybeStart();
  }
}

var constraints = {
  video: true
};

console.log('Getting user media with constraints', constraints);

//if (location.hostname !== 'localhost') {
//  requestTurn(
//    'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
//  );
//} 

function maybeStart() {
  console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady);
  if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
    console.log('>>>>>> creating peer connection');
    createPeerConnection();

    isStarted = true;
    console.log('isInitiator', isInitiator);
    if (isInitiator) {
      doCall();
    }
  }
}

window.onbeforeunload = function() {
  sendMessage('bye');
};

/////////////////////////////////////////////////////////







function createPeerConnection() {




  try {
    pc = new RTCPeerConnection(pcConfig);
    pc.addStream(localStream);
    pc.onicecandidate = handleIceCandidate;
    pc.onaddstream = handleRemoteStreamAdded;
    pc.oniceconnectionstatechange = function(){
       console.log('ICE state: ',pc.iceConnectionState);
    }
    pc.onremovestream = handleRemoteStreamRemoved;
    console.log('Created RTCPeerConnnection');
  } catch (e) {
    console.log('Failed to create PeerConnection, exception: ' + e.message);
    alert('Cannot create RTCPeerConnection object.');
    return;
  }
}

function handleIceCandidate(event) {
  console.log('icecandidate event: ', event);
  if (event.candidate) {
    sendMessage({
      type: 'candidate',
      label: event.candidate.sdpMLineIndex,
      id: event.candidate.sdpMid,
      candidate: event.candidate.candidate
    });
  } else {
    console.log('End of candidates.');
  }
}

function handleRemoteStreamAdded(event) {
  console.log('Remote stream added.');
  remoteVideo.src = window.URL.createObjectURL(event.stream);
  remoteStream = event.stream;
}

function handleCreateOfferError(event) {
  console.log('createOffer() error: ', event);
}

function doCall() {
  console.log('Sending offer to peer');
  pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
}

function doAnswer() {
  console.log('Sending answer to peer.');
  pc.createAnswer().then(
    setLocalAndSendMessage,
    onCreateSessionDescriptionError
  );
}

function setLocalAndSendMessage(sessionDescription) {
  // Set Opus as the preferred codec in SDP if Opus is present.
  //  sessionDescription.sdp = preferOpus(sessionDescription.sdp);
  pc.setLocalDescription(sessionDescription);
  console.log('setLocalAndSendMessage sending message', sessionDescription);
  sendMessage(sessionDescription);
}

function onCreateSessionDescriptionError(error) {
  trace('Failed to create session description: ' + error.toString());
}

function requestTurn(turnURL) {
  var turnExists = false;
  for (var i in pcConfig.iceServers) {
    if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
      turnExists = true;
      turnReady = true;
      break;
    }
  }
//  if (!turnExists) {
//    console.log('Getting TURN server from ', turnURL);
//    // No TURN server. Get one from computeengineondemand.appspot.com:
//    var xhr = new XMLHttpRequest();
//    xhr.onreadystatechange = function() {
//      if (xhr.readyState === 4 && xhr.status === 200) {
//        var turnServer = JSON.parse(xhr.responseText);
//        console.log('Got TURN server: ', turnServer);
//        pcConfig.iceServers.push({
//          'url': 'turn:' + turnServer.username + '@' + turnServer.turn,
//          'credential': turnServer.password
//        });
//        turnReady = true;
//      }
//    };
//    xhr.open('GET', turnURL, true);
//    xhr.send();
//  }
}

function handleRemoteStreamAdded(event) {
  console.log('Remote stream added.');
  remoteVideo.src = window.URL.createObjectURL(event.stream);
  remoteStream = event.stream;
}

function handleRemoteStreamRemoved(event) {
  console.log('Remote stream removed. Event: ', event);
}

function hangup() {
  console.log('Hanging up.');
  stop();
  sendMessage('bye');
}

function handleRemoteHangup() {
  console.log('Session terminated.');
  stop();
  isInitiator = false;
}

function stop() {
  isStarted = false;
  // isAudioMuted = false;
  // isVideoMuted = false;
  pc.close();
  pc = null;
}

///////////////////////////////////////////

// Set Opus as the default audio codec if it's present.
function preferOpus(sdp) {
  var sdpLines = sdp.split('\r\n');
  var mLineIndex;
  // Search for m line.
  for (var i = 0; i < sdpLines.length; i++) {
    if (sdpLines[i].search('m=audio') !== -1) {
      mLineIndex = i;
      break;
    }
  }
  if (mLineIndex === null) {
    return sdp;
  }

  // If Opus is available, set it as the default in m line.
  for (i = 0; i < sdpLines.length; i++) {
    if (sdpLines[i].search('opus/48000') !== -1) {
      var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
      if (opusPayload) {
        sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex],
          opusPayload);
      }
      break;
    }
  }

  // Remove CN in m line and sdp.
  sdpLines = removeCN(sdpLines, mLineIndex);

  sdp = sdpLines.join('\r\n');
  return sdp;
}

function extractSdp(sdpLine, pattern) {
  var result = sdpLine.match(pattern);
  return result && result.length === 2 ? result[1] : null;
}

// Set the selected codec to the first in m line.
function setDefaultCodec(mLine, payload) {
  var elements = mLine.split(' ');
  var newLine = [];
  var index = 0;
  for (var i = 0; i < elements.length; i++) {
    if (index === 3) { // Format of media starts from the fourth.
      newLine[index++] = payload; // Put target payload to the first.
    }
    if (elements[i] !== payload) {
      newLine[index++] = elements[i];
    }
  }
  return newLine.join(' ');
}

// Strip CN from sdp before CN constraints is ready.
function removeCN(sdpLines, mLineIndex) {
  var mLineElements = sdpLines[mLineIndex].split(' ');
  // Scan from end for the convenience of removing an item.
  for (var i = sdpLines.length - 1; i >= 0; i--) {
    var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
    if (payload) {
      var cnPos = mLineElements.indexOf(payload);
      if (cnPos !== -1) {
        // Remove CN payload from m line.
        mLineElements.splice(cnPos, 1);
      }
      // Remove CN line in sdp
      sdpLines.splice(i, 1);
    }
  }

  sdpLines[mLineIndex] = mLineElements.join(' ');
  return sdpLines;
}  
“严格使用”;
var isChannelReady=false;
var isInitiator=false;
var isStarted=假;
var-localStream;
var-pc;
远程流;
var-turnReady;
变量pcConfig={
“ICEServer”:[
{'URL':'stun:stun.l.google.com:19302'},
{“URL”:[“turn:78.129.167.90”],“用户名”:“wyzturner1”,“凭证”:“wyzturnp2ss”}]
};
//设置音频和视频,而不管有什么设备。
变量SDP约束={
offerToReceiveAudio:正确,
offerToReceiveVideo:正确
};
/////////////////////////////////////////////
变量室='foo';
//无法提示输入房间名称:
//房间=提示('输入房间名称:');
var socket=io.connect('https://www.samplesite.com:8080');
如果(房间!=''){
socket.emit('create或join',房间);
console.log('试图创建或加入文件室',文件室');
}
插座打开('已创建'),功能(房间){
console.log('创建的房间'+房间);
isInitiator=true;
});
插座打开(“满”,功能(房间){
console.log('房间'+房间+'已满');
});
插座开('join',功能(房间){
log('另一个对等方请求加入房间'+房间);
console.log('此对等方是文件室“+文件室+!”的发起方);
isChannelReady=true;
});
插座上的('连接',功能(房间){
控制台日志('已加入:'+房间);
isChannelReady=true;
});
socket.on('log',函数(数组){
console.log.apply(控制台,数组);
});
////////////////////////////////////////////////
函数sendMessage(消息){
log('客户端发送消息:',消息);
发出('message',message);
}
//此客户端接收一条消息
socket.on('message',函数(message){
log('客户端收到的消息:',消息);
如果(消息=='已获得用户媒体'){
maybeStart();
}else if(message.type==='offer'){
如果(!isInitiator&!isStarted){
maybeStart();
}
pc.setRemoteDescription(新的RTCSessionDescription(消息));
doAnswer();
}else if(message.type==='answer'&&isstart){
pc.setRemoteDescription(新的RTCSessionDescription(消息));
}else if(message.type==='candidate'&&isStarted){
var候选者=新的候选者({
sdpMLineIndex:message.label,
候选人:message.candidate
});
pc.addIceCandidate(候选人);
}else if(消息==='bye'&&istarted){
handleRemoteHangup();
}
});
////////////////////////////////////////////////////
var localVideo=document.querySelector('#localVideo');
var remoteVideo=document.querySelector(“#remoteVideo”);
navigator.mediaDevices.getUserMedia({
音频:错,
视频:真的
})
.然后(gotStream)
.catch(函数(e){
警报('getUserMedia()错误:'+e.name);
});
函数gotStream(stream){
log('添加本地流');
localVideo.src=window.URL.createObjectURL(流);
localStream=stream;
sendMessage('got user media');
if(isInitiator){
maybeStart();
}
}
变量约束={
视频:真的
};
log('获取带有约束的用户媒体',约束);
//if(location.hostname!=“localhost”){
//请求回合(
//    'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
//  );
//} 
函数maybeStart(){
log(“>>>>maybeStart()”,isStart,localStream,isChannelReady);
如果(!isStart&&typeof localStream!=='undefined'&&isChannelReady){
log(“>>>创建对等连接”);
createPeerConnection();
IsStart=true;
console.log('isinitator',isinitator);
if(isInitiator){
doCall();
}
}
}
window.onbeforeunload=函数(){
发送消息(“再见”);
};
/////////////////////////////////////////////////////////
函数createPeerConnection(){
试一试{
pc=新的RTPEERCONNECTION(pcConfig);
pc.addStream(localStream);
pc.onicecandidate=handleIceCandidate;
pc.onaddstream=handleRemoteStreamAdded;
pc.oniceconnectionstatechange=函数(){
console.log('ICE state:',pc.iceConnectionState);
}
pc.onremovestream=已移除把手移除测试流;
log('Created rtpeerconconnection');
}捕获(e){
console.log('创建对等连接失败,异常:'+e.message);
警报('无法创建RTPeerConnection对象');
返回;
}
}
函数handleIceCandidate(事件){
log('icecandidate事件:',事件);
if(事件候选){
发送消息({
键入:“候选人”,
标签:event.candidate.sdpMLineIndex,
id:event.candidate.sdpMid,
候选人:event.candidate.candidate
});
}否则{
console.log(“候选对象结束”);
}
}
添加函数handleremotestream(事件){
log('添加了远程流');
remoteVideo.src=window.URL.createObjectURL(event.stream);
remoteStream=event.stream;
}
函数handleCreateOfferError(事件){
日志('createOffer()错误:',事件);
}
函数doCall(){
console.log(“向对等方发送报价”);
pc.createOffer(setLocalAndSendMessage,handleCreateOfferError);
}
函数doAnswer(){
log('向对等方发送应答');
pc.createAnswer()。然后(
setLocalAndSendMessage,
onCreateSessionDescriptionError
);
}
函数setLocalAndSendMessage(sessionDescription){
//如果存在Opus,则将Opus设置为SDP中的首选编解码器。
//sessionDescription.sdp=preferOpus(sessionDescription.sdp);
pc.setLocalDescription(sessionDescription);
log('setLocalAndSendMessage发送消息',sessionDescription);
sendMessage(sessionDescription);
}
函数onCreateSessionDescriptionError(错误){
跟踪('未能创建会话描述:'+错误.toString());
}
函数requestTurn(turnURL){
var=false;
for(var)