webRTC- не получает потоковых и ледовых кандидатов от других сверстников - PullRequest
0 голосов
/ 13 ноября 2018

Я работаю над приложением для видеозвонков, используя webRTC и socket.io.Я взглянул на другие подобные проекты и пытаюсь реализовать те, которые принадлежат мне.

Первый партнер создает предложение, а другой получает предложение и сохраняет его в своем удаленном расшифровке и создает ответ, который получаетпервый пэр.Но ледовые кандидаты не обмениваются, а также поток.Вот код на стороне клиента:

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);

И код 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");
  });

Пожалуйста, помогите мне с этим.

1 Ответ

0 голосов
/ 13 ноября 2018

Запустите его в Firefox, и вы увидите эту ошибку:

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

Вы звоните createOffer до addStream, что приводит к пустому предложению и без кандидатов.

Вы также используете peerConn.localDescription до окончания setLocalDescription.

Это асинхронные методы, которые должны выполняться последовательно, а не параллельно. Попробуйте приковать их цепочкой:

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;
}

Кроме того, на отвечающей стороне никогда не откладывайте вызов setRemoteDescription, иначе вы рискуете пропустить кандидатов. Это чувствительно ко времени, как я объясняю в другом ответе .

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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...