ontrack 事件不会为呼叫者触发

ontrack event not firing for caller

我正在尝试开发一个视频会议应用程序,但在使用 RTCpeerconnection 的 ontrack() track event 时遇到了一些问题。

在下面的代码中,第一个用户加入设置为 userType=caller,其他用户设置为 userType=receiver。课程描述 Obejcts 和 ICe Candidates 在它们之间正确传递并且 peerConnection.iceConnectionState 显示 connected 用于调用者和接收者。

问题是 ontrack 在接收方端被正确触发,但在调用方端它没有被触发。接收者能够看到呼叫者和他自己。 这是我为客户端编写的全部代码:

const socket = io();

const $localStream = document.querySelector("#local-stream");
const $remoteStream = document.querySelector("#remote-stream");

const config = {
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
};

let mediaStream,
  remoteStream = new MediaStream(),
  userType = null;
const peerConnection = new RTCPeerConnection(config);

$remoteStream.srcObject = remoteStream;

peerConnection.onicecandidate = (e) => {
  if (e.candidate) {
    socket.emit("send-icecandidate", { candidate: e.candidate });
  }
};

peerConnection.onconnectionstatechange = (e) => {
  if (peerConnection.connectionState === "connected") {
    console.log("connection established");
  }
};

peerConnection.ontrack = (e) => {
  console.log("Event " + e);
  remoteStream.addTrack(e.track, remoteStream);
};

const init = async function () {
  mediaStream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: {
      facingMode: { exact: "user" },
    },
  });
  mediaStream
    .getTracks()
    .forEach((track) => peerConnection.addTrack(track, mediaStream));
  $localStream.srcObject = mediaStream;
};

init();

socket.emit("start");

socket.on("start", (user) => {
  userType = user.userType;
  console.log(userType);
  if (userType === "receiver") {
    socket.emit("ready");
  }
});

socket.on("ready", () => {
  console.log("receiver is ready for connection establishment");
  makeCall();
});

const makeCall = async () => {
  const offer = await peerConnection.createOffer({
    offerToReceiveAudio: true,
    offerToReceiveVideo: true,
  });
  await peerConnection.setLocalDescription(offer);
  socket.emit("offer", { offer });
};

socket.on("offer", async ({ offer }) => {
  console.log("offer received", offer);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
  const answer = await peerConnection.createAnswer({
    offerToReceiveAudio: true,
    offerToReceiveVideo: true,
  });
  await peerConnection.setLocalDescription(answer);
  socket.emit("answer", { answer });
});

socket.on("answer", async ({ answer }) => {
  console.log("answer received", answer);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
});

socket.on("send-icecandidate", async ({ candidate }) => {
  console.log("ice candidate received", candidate);
  await peerConnection.addIceCandidate(candidate);
});

我找到了解决我自己问题的方法,init() 用于请求标记为异步函数的媒体权限。结果,在接受媒体许可请求并将流添加到 peerconnection 对象之前,我没有正确处理承诺和启动连接。发起连接建立和第一个加入呼叫的呼叫者有时间访问媒体,但当涉及页面时作为接收者直接去建立连接并且流不会添加到 peerConnection 对象。从而阻止 ontrack 事件在调用端触发。

代码从 init() 更改而来。如果有人遇到同样的问题,请在下面粘贴代码:

init().then(()=>{ 
socket.emit("start");

socket.on("start", (user) => {
  userType = user.userType;
  console.log(userType);
  if (userType === "receiver") {
    socket.emit("ready");
  }
});

socket.on("ready", () => {
  console.log("receiver is ready for connection establishment");
  makeCall();
});

const makeCall = async () => {
  const offer = await peerConnection.createOffer({
    offerToReceiveAudio: true,
    offerToReceiveVideo: true,
  });
  await peerConnection.setLocalDescription(offer);
  socket.emit("offer", { offer });
};

socket.on("offer", async ({ offer }) => {
  console.log("offer received", offer);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
  const answer = await peerConnection.createAnswer({
    offerToReceiveAudio: true,
    offerToReceiveVideo: true,
  });
  await peerConnection.setLocalDescription(answer);
  socket.emit("answer", { answer });
});

socket.on("answer", async ({ answer }) => {
  console.log("answer received", answer);
  await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
});

socket.on("send-icecandidate", async ({ candidate }) => {
  console.log("ice candidate received", candidate);
  await peerConnection.addIceCandidate(candidate);
});

})