'peer.on('calll') is never being called

Peer js is not working

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)
});

Error

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)
    })
});

Github repo



Solution 1:[1]

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

Solution 2:[2]

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.

Solution 3:[3]

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
   })

})

Solution 4:[4]

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 => { })
  })

Solution 5:[5]

Your code is similar to a project that I'm working on. I had trouble with where I was initiating the peer instance. I had to move it up one level in my component tree, because something I was doing was causing a re-render and the peer instance was being re-created, with a new id.

Also check where you're creating your socket. Make sure that your user-connected event is being registered in a useEffect().

  useEffect(() => {
    videoSocket = initiateVideoSocket(roomId, username, peer.id);
    // When a viewer connects, this event is emitted and the streamer will connect to the viewer.
    videoSocket.on("user-connected", (roomId, viewerPeerId) => {
      connectToNewViewer(viewerPeerId, videoStream);
    });
  }, [videoStream]);
  const viewerVideoSocket = initiateVideoSocket(
    room,
    props.username,
    viewerPeerId
  );

  const viewerChatSocket = initiateChatSocket(room, props.username);
  let streamerVideoDiv;

  useEffect(() => {
    viewerVideoSocket.emit(
      "user-connected",
      room,
      props.username,
      viewerPeerId
    );

    viewerPeer.on("call", (call) => {
      call.answer();
      call.on("stream", (stream) => {
        streamerVideoDiv = document.getElementById("streamer-video");
        const content = document.createElement("video");
        content.srcObject = stream;
        content.addEventListener("loadedmetadata", () => {
          content.play();
        });
        streamerVideoDiv.append(content);
      });
    });

    return () => {
      disconnectSocket();
    };
  }, []);

Solution 6:[6]

You must declare peer in the stream call back function as below:

myVideo.muted = true;
navigator.mediaDevices.getUserMedia ({
    video: true,
    audio: true
}).then(
    stream => {
        const myPeer = new Peer (undefined, {


            host: '/',
            port: '4001'
        });
        
        myPeer.on('open', id => {
            
            socket.emit('join-room', ROOM_ID, id)
            console.log("!@1")
            
        })

        addVideoStream(myVideo,stream)
        
        socket.on('user-connected', userId => {
            console.log("user is connected with id: ", userId);
            // connectToNewUser(userId, stream)
            const call = myPeer.call(userId, stream);
            console.log('call');
            const video = document.createElement('video');
            call.on('stream', userVideoStream => {
                addVideoStream(video, userVideoStream);
            })
            call.on('close', () => {
                video.remove()
            })
        })
        myPeer.on('call', call => {
            call.answer(stream)
            console.log("CALL"); 
        })

        
    }) 

Solution 7:[7]

The solution is simple...

Set debug level to 3 when initializing the peer and then you will see the error

peer.call is not running since you may not be passing the parameters , id or stream...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ankur Powar
Solution 3 abhishek vaish
Solution 4 Pankaj Negi
Solution 5
Solution 6 Mohammadhossein Nejat
Solution 7 Interstellar CG