SlothFriend
SlothFriend

Reputation: 641

WebRTC: Connection is successful but answering peer never receives "track" events

With two peers connected via WebRTC, we can see the peer connection is complete, yet only one client is receiving the video stream (the "offering" peer). The "answering" peer is never receiving "track" events (peerConnection.ontrack).

Code for the "answering" peer that displays the problem:

const peerConnection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun1.l.google.com:19302' }]});

const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach((track) => { peerConnection.addTrack(track, localStream) });

const { data } = await axios.get("http://{HIDDEN}/offer");
if (data) {
  // console.log('received offer', data.offer)
  await peerConnection.setRemoteDescription(data.offer);
  const answer = await peerConnection.createAnswer();
  await peerConnection.setLocalDescription(answer);
  connectionInfo.current.answer = peerConnection.localDescription;
  data.iceCandidates.forEach(async (candidate: any) => {
    await peerConnection.addIceCandidate(candidate);
  });

  // Set peer connection event handlers
  peerConnection.onicecandidate = (event) => {
    if (event.candidate) connectionInfo.current.iceCandidates.push(event.candidate);
  };
  peerConnection.onicegatheringstatechange = async () => {
    if (peerConnection.iceGatheringState === "complete" && connectionInfo.current.answer) {
      await axios.post("http://{HIDDEN}/answer", connectionInfo.current);
    }
  };
  peerConnection.ontrack = async (event) => {
    remoteStream.addTrack(event.track);
  };

  if (peerConnection.iceGatheringState === "complete") {
    await axios.post("http://{HIDDEN}/answer", connectionInfo.current);
  }
}

Upvotes: 2

Views: 1949

Answers (1)

SlothFriend
SlothFriend

Reputation: 641

I found this post which mentions your problem and suggests that the order in which event listeners are created relative to the peerConnection.setRemoteDescription() call is the problem: https://github.com/w3c/webrtc-pc/issues/198

Moving the event handlers immediately after the new RTCPeerConnection initialization (before the description setting) should fix the issue. For example:

const peerConnection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun1.l.google.com:19302' }]});

// Set peer connection event handlers - MOVED UP HERE
peerConnection.onicecandidate = (event) => {
  if (event.candidate) connectionInfo.current.iceCandidates.push(event.candidate);
};
peerConnection.onicegatheringstatechange = async () => {
  if (peerConnection.iceGatheringState === "complete" && connectionInfo.current.answer) {
    await axios.post("http://{HIDDEN}/answer", connectionInfo.current);
  }
};
peerConnection.ontrack = async (event) => {
  remoteStream.addTrack(event.track);
};

const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach((track) => { peerConnection.addTrack(track, localStream) });

const { data } = await axios.get("http://{HIDDEN}/offer");
if (data) {
  // console.log('received offer', data.offer)
  await peerConnection.setRemoteDescription(data.offer);
  const answer = await peerConnection.createAnswer();
  await peerConnection.setLocalDescription(answer);
  connectionInfo.current.answer = peerConnection.localDescription;
  data.iceCandidates.forEach(async (candidate: any) => {
    await peerConnection.addIceCandidate(candidate);
  });

  if (peerConnection.iceGatheringState === "complete") {
    await axios.post("http://{HIDDEN}/answer", connectionInfo.current);
  }
}

Upvotes: 3

Related Questions