简体   繁体   English

webRTC-未从其他对等方获取流和冰候选

[英]webRTC- not getting stream and ice candidates from other peer

I am working on a video call app using webRTC and socket.io.我正在使用 webRTC 和 socket.io 开发视频通话应用程序。 I had a look at other projects like this and am trying to implement those my own.我看过其他类似的项目,并正在尝试实现我自己的项目。

The first peer creates offer and the other peer gets the offer and saves it to its remote decription and creates answer which is recieved by the first peer.第一个对等点创建报价,另一个对等点获取报价并将其保存到其远程描述中,并创建第一个对等方收到的答案。 But the ice candidates are not exchanged and also the stream.但冰候选人没有交换,也流。 Here is the client-side code:下面是客户端代码:

var socket = io();
var peerConn,
  onlineUsers = [],
  username,
  caller;

function createOffer(callee) {
  peerConn = new RTCPeerConnection();
  peerConn.onicecandidate = onIce;
  peerConn.onaddstream = onAddStream;
  navigator.mediaDevices
    .getUserMedia({ audio: true, video: { height: 240, width: 320 } })
    .then(stream => (window.myVideo.srcObject = stream))
    .then(stream => peerConn.addStream(stream));
  peerConn.createOffer().then(offer => {
    peerConn.setLocalDescription(offer);
    socket.emit("call", callee, peerConn.localDescription);
  });
  caller = callee;
}

socket.on("call", (callee, caller, sdp) => {
  if (callee == username) createAnswer(sdp, caller);
});
function createAnswer(sdp, caller) {
  peerConn = new RTCPeerConnection();
  peerConn.onicecandidate = onIce;
  peerConn.onaddstream = onAddStream;
  window.caller = caller;
  navigator.mediaDevices
    .getUserMedia({ audio: true, video: { height: 240, width: 320 } })
    .then(stream => (window.myVideo.srcObject = stream))
    .then(stream => peerConn.addStream(stream));
  peerConn.setRemoteDescription(new RTCSessionDescription(sdp));
  peerConn.createAnswer().then(answer => {
    peerConn.setLocalDescription(answer);
    socket.emit("answer", caller, peerConn.localDescription);
  });
  console.log(peerConn.localDescription);
  console.log(peerConn.remoteDescription);
}

function onIce(event) {
  if (event.candidate) {
    socket.emit("ice", caller, event.candidate);
    console.log("sent ice");
  } else {
    console.log("Sent all ice");
  }
}

function onAddStream(event) {
  console.log("remote stream added");
  frndsVideo.srcObject = event.stream;
}

socket.on("answer", (callee, caller, sdp) => {
  if (caller == username) setRemoteDes(sdp);
});
function setRemoteDes(sdp) {
  peerConn.setRemoteDescription(sdp);
  console.log(peerConn.localDescription);
  console.log(peerConn.remoteDescription);
}

function addIce(caller, callee, ice) {
  peerConn.addIceCandidate(new RTCIceCandidate(ice));
  console.log("ice added");
}

socket.on("ice", addIce);

And the server-side js code:和服务器端js代码:

socket.on("call", (callee, sdp) => {
    console.log(`${socket.username} calling ${callee}  ${sdp}`);
    onlineUsers.forEach((user, i) => {
      if (user.username == callee || user.username == socket.username) {
        onlineUsers[i].inCall = true;
      }
    });
    socket.broadcast.emit(`call`, callee, socket.username, sdp);
  });
  socket.on("answer", (caller, sdp) => {
    console.log(`${socket.username} answered ${caller}  ${sdp}`);
    socket.broadcast.emit("answer", socket.username, caller, sdp);
  });
  socket.on("ice", (caller, ice) => {
    socket.broadcast.emit("ice", socket.username, caller, ice);
    console.log("ice recived and sent");
  });

Please help me with this.请帮我解决一下这个。

Run it in Firefox, and you'll see this error:在 Firefox 中运行它,你会看到这个错误:

InvalidStateError: Cannot create offer when there are no valid transceivers.

You're calling createOffer before addStream , which produces an empty offer and no candidates.你打电话createOfferaddStream ,产生一个空的报价,没有候选人。

You're also using peerConn.localDescription before setLocalDescription has finished.您还在setLocalDescription完成之前使用peerConn.localDescription

These are asynchronous methods that need to run in sequence, not in parallel.这些是需要按顺序运行的异步方法,而不是并行运行。 Try chaining them:尝试链接它们:

function createOffer(callee) {
  peerConn = new RTCPeerConnection();
  peerConn.onicecandidate = onIce;
  peerConn.onaddstream = onAddStream;
  navigator.mediaDevices
    .getUserMedia({audio: true, video: {height: 240, width: 320}})
    .then(stream => {
      peerConn.addStream(myVideo.srcObject = stream);
      return peerConn.createOffer();
    })
    .then(offer => peerConn.setLocalDescription(offer))
    .then(() => socket.emit("call", callee, peerConn.localDescription))
    .catch(e => console.log(e));
  caller = callee;
}

Furthermore, on the answering side, never delay calling setRemoteDescription or you risk missing candidates.此外,在回答方面,永远不要延迟调用setRemoteDescription否则你可能会错过候选人。 This is time sensitive, as I explain in another answer .这是时间敏感的,正如我在另一个答案中解释的那样。

function createAnswer(sdp, caller) {
  peerConn = new RTCPeerConnection();
  peerConn.onicecandidate = onIce;
  peerConn.onaddstream = onAddStream;
  window.caller = caller;
  peerConn.setRemoteDescription(sdp)
  .then(() => navigator.mediaDevices
    .getUserMedia({audio: true, video: {height: 240, width: 320}}))
  .then(stream => {
    peerConn.addStream(myVideo.srcObject = stream);
    return peerConn.createAnswer();
  })
  .then(answer => peerConn.setLocalDescription(answer))
  .then(() => socket.emit("answer", caller, peerConn.localDescription))
  .catch(e => console.log(e));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM