I am just creating peerjs video streaming application in NodeJs and ReactJs
The below code is working fine, i am able to create new peer and open event is also working.
const peer = new Peer(undefined,{
host:"/",
port:"5001"
});
peer.on('open',id=>{
socket.emit('join-room', roomId,id);
})
On server side whenever 'join-room' event is emitted, server will emit another event 'user-disconnected' and passes userId (peerjs) to client.
// server.js
socket.on('join-room',(roomId,userId)=>{
console.log(`user ${userId} joined ${roomId}`);
socket.join(roomId);
socket.to(roomId).emit('user-connected',userId);
socket.on('disconnect', () => {
socket.to(roomId).emit('user-disconnected', userId)
})
})
Whenever 'user-connected' is triggered on client side I'm calling connectToNewUser and up to this is working fine.
socket.on('user-connected',userId=>{
console.log("New user connected...")
connectToNewUser(userId, stream)
});
This is being logged on console console.log('connectToNewUser',1222.....) there is no error.
But, this call.on('stream') is never being called
connectToNewUser(userId, stream) {
console.log('connectToNewUser',userId)
const call = peer.call(userId, stream);
const video = getVideo();
call.on('stream', userVideoStream => {
// never called
console.log('connectToNewUser','on','stream')
addVideoStream(video, userVideoStream)
});
call.on('close', () => {
video.remove()
})
peers[userId] = call
}
The reason of call.on('stream') is never being called is peer.on('call') is never being called.
peer.on('call', call => {
// never called
console.log('This peer is being called...');
call.answer(stream)
const video = getVideo();
call.on('stream', userVideoStream => {
console.log('This peer is being called...on-stream...');
addVideoStream(video, userVideoStream)
})
});
I also had the same problem, after going through more than 10+ solutions on StackOverflow, here is the thing I suggest.
connectToNewUser() gets triggered before the user has finished the navigator promise.
Try to modify to this:
socket.on('user-connected',userId=>{
console.log("New user connected...")
//connectToNewUser(userId, stream)
setTimeout(connectToNewUser,1000,userId,stream)
});
It worked for me.
The only problem with your code is that you are emitting user-connected event from server before initializing peer.on("call") event on client which eventually leads this event to be missed by new client. The best solution for this is to emit a ready event after initializing peer.on("call",...) event.
peer.on('call', call => {
console.log('This peer is being called...');
call.answer(stream)
const video = getVideo();
call.on('stream', userVideoStream => {
console.log('This peer is being called...on-stream...');
addVideoStream(video, userVideoStream)
})})
socket.emit("ready")`
And then on server side call the "user-connected" broadcast event inside the listener for "ready" event:
socket.on('join-room',(roomId,userId)=>{
console.log(`user ${userId} joined ${roomId}`);
socket.join(roomId);
socket.on('ready',()=>{
socket.broadcast.to(roomId).emit('user-connected',userId);
})
socket.on('disconnect', () => {
socket.to(roomId).emit('user-disconnected', userId)
})})
This will broadcast user-connected event after the client is ready to recieve peer.on("call". .. .) event
I think your code is something like this
const peer = new Peer(undefined,{host:"/",port:"5001"})
peer.on('open',id=>{
socket.emit('join-room', roomId,id)
})
navigator.mediaDevices.getUserMedia({
video : true,
audio : true
}).then( stream => {
socket.on('user-connected',userId=>{
// call the new user and send our stream
});
peer.on('call',call=>{
// pick up the call and send our stream
})
})
whenever a new client joins a new peer Object is created after which the socket emits join-room and the server broadcasts the user-connected to all the other clients
so now when the new user joins the user-connected function of all the other client is called in which all the other clients call the new client .
one key thing to note is that the navigator.mediaDevices.getUserMedia(video : true,audio : true}) takes some time
So when a new client joins all the other clients instantly call the new client but the function to pick up the call i.e. peer.on('call',call=>{}) may not be defined yet on the new client so that's why the new clients does not response because it is still setting up its video stream
to fix this you must join the room after setting up the video stream so something like this
navigator.mediaDevices.getUserMedia({
video : true,
audio : true
}).then( stream => {
const peer = new Peer(undefined,{host:"/",port:"5001"})
peer.on('open',id=>{
socket.emit('join-room', roomId,id)
})
socket.on('user-connected',userId=>{
// call the new user and send our stream
});
peer.on('call',call=>{
// pick up the call and send our stream
})
})