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.
Here the Peer object is getting created before Camera and/or Mic are ready to use.
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
//peer.on('call')
})
peer.on('call') will be implemented by browser only once getUserMedia() will finish execution.
Thing is that you are receiving a call event but there is no handler is ready to handle that event yet. Best solution would be to join the room once the media is ready to use.
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
const myPeer = new Peer(undefined, {
host: '/',
port: '3001'
})
myPeer.on('open', id => {
socket.emit('join-room', ROOM_ID, id)
})
myPeer.on('call', call => { })
})
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