I have the following server code and frontend react code. I have a server running using ngrok. the server connection is working fine. ICE candidates are also generating. But the video is not exchanging as expected.
I want to connect this two calls exchange automaticaly without adding any reference. How is possible to do that. I can use broadcast option to send the candidate or ICE reference automaticaly.
client react code
import React, { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:8000/');
const config = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun1.l.google.com:19302' },
{ urls: 'stun:stun2.l.google.com:19302' },
{ urls: 'stun:stun3.l.google.com:19302' },
{ urls: 'stun:stun4.l.google.com:19302' },
],
};
const App = () => {
const [peerConnection, setPeerConnection] = useState(null);
const [localStream, setLocalStream] = useState(null);
const [remoteStream, setRemoteStream] = useState(null);
const localVideoRef = useRef();
const remoteVideoRef = useRef();
useEffect(() => {
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => {
setLocalStream(stream);
localVideoRef.current.srcObject = stream;
})
.catch(error => console.log('Error accessing media devices: ', error));
}, []);
useEffect(() => {
if (peerConnection) {
peerConnection.onicecandidate = event => {
if (event.candidate) {
console.log('Candidate', event.candidate);
socket.emit('iceCandidate', event.candidate);
}
};
peerConnection.ontrack = event => {
setRemoteStream(event.streams[1]);
remoteVideoRef.current.srcObject = event.streams[0];
};
socket.on('iceCandidate', candidate => {
peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
});
socket.on('sdp', async sdp => {
if (sdp.type === 'offer') {
await peerConnection.setRemoteDescription(new RTCSessionDescription(sdp));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
socket.emit('sdp', answer);
} else if (sdp.type === 'answer') {
await peerConnection.setRemoteDescription(new RTCSessionDescription(sdp));
}
});
}
}, [peerConnection]);
const createPeerConnection = () => {
console.log("hello");
const pc = new RTCPeerConnection(config);
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
setPeerConnection(pc);
};
const initiateCall = async () => {
if (localStream) {
createPeerConnection();
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
console.log("offer", offer);
socket.emit('sdp', offer);
}
};
return (
<div>
<video ref={localVideoRef} autoPlay muted width={300}/>
<video ref={remoteVideoRef} autoPlay />
<button onClick={initiateCall}>Start Call</button>
</div>
);
};
export default App;
server
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require("socket.io")(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
const PORT = process.env.PORT || 8000;
const peers = {};
io.on('connection', socket => {
socket.on('sdp', sdp => {
console.log('sdp',sdp);
socket.broadcast.emit('sdp', sdp);
});
socket.on('iceCandidate', candidate => {
socket.broadcast.emit('iceCandidate', candidate);
});
socket.on('joinRoom', room => {
socket.join(room);
peers[socket.id] = room;
const otherPeers = Object.keys(peers)
.filter(id => peers[id] === room && id !== socket.id);
socket.emit('otherPeers', otherPeers);
socket.broadcast.to(room).emit('newPeer', socket.id);
});
socket.on('disconnect', () => {
const room = peers[socket.id];
if (room) {
delete peers[socket.id];
io.to(room).emit('peerDisconnected', socket.id);
}
});
});
server.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});