Reputation: 641
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
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