peer.on('calll') 永远不会被调用

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

Peer js 不工作

我只是在 NodeJs 和 ReactJs 中创建 peerjs 视频流应用程序


下面的代码工作正常,我能够创建新的对等点并且 open 事件也能正常工作。

const peer = new Peer(undefined,{
            host:"/",
            port:"5001"
        });

peer.on('open',id=>{
  socket.emit('join-room', roomId,id);
})

在服务器端,每当发出 'join-room' 事件时,服务器将发出另一个事件 'user-disconnected' 并将 userId (peerjs) 传递给客户端。

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

每当在客户端触发 'user-connected' 时,我都会调用 connectToNewUser,到目前为止一切正常。

socket.on('user-connected',userId=>{
    console.log("New user connected...")
    connectToNewUser(userId, stream)
});

错误

正在控制台上记录console.log('connectToNewUser',1222.....)没有错误。

但是,这个 call.on('stream') 永远不会被调用

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
}

call.on('stream') 从未被调用的原因是 peer.on('call') 从未被调用。

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

您的代码与我正在处理的一个项目相似。我在启动 peer 实例的位置时遇到了问题。我不得不将它在我的组件树中向上移动一个级别,因为我正在做的事情导致重新渲染并且正在重新创建 peer 实例,并使用新的 id.

还要检查您在何处创建套接字。请确保您的 user-connected 活动已在 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();
    };
  }, []);

我也遇到了同样的问题,在 Whosebug 上浏览了 10 多个解决方案后,这是我的建议。

connectToNewUser() 在用户完成导航器承诺之前被触发。

尝试修改为:

socket.on('user-connected',userId=>{
    console.log("New user connected...")
    //connectToNewUser(userId, stream)
    setTimeout(connectToNewUser,1000,userId,stream)
});

对我有用。

您的代码的唯一问题是您在客户端上初始化 peer.on("call") 事件之前从服务器发出用户连接事件,这最终导致新客户端错过此事件。 最好的解决方案是在初始化 peer.on("call",...) 事件后发出一个就绪事件。

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")`

然后在服务器端为“就绪”事件调用监听器中的“用户连接”广播事件:

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

这将在客户端准备好接收 peer.on("call".. .) 事件

我认为你的代码是这样的

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

})

每当一个新的客户端加入一个新的对等对象时,套接字发出 join-room 并且服务器向所有其他客户端广播 user-connected

所以现在当新用户加入时,调用所有其他客户端的 user-connected 函数,其中所有其他客户端调用新客户端。

需要注意的一个关键问题是 navigator.mediaDevices.getUserMedia(video : true,audio : true}) 需要一些时间

因此,当一个新客户端加入时,所有其他客户端会立即呼叫新客户端,但接听电话的功能,即 peer.on('call',call=>{}) 可能尚未在新客户端上定义,这就是为什么新客户端会这样做没有响应,因为它仍在设置其视频流

要解决此问题,您必须在设置视频流后加入房间 所以像这样

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

})

此处在相机 and/or 麦克风准备好使用之前创建对等对象。

navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(stream => { 
    //peer.on('call')
})

peer.on('call')浏览器只执行一次getUserMedia()执行完毕

问题是您正在接收呼叫事件,但还没有准备好处理该事件的处理程序。最佳解决方案是在媒体准备好使用后加入房间。

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

必须在流回调函数中声明peer如下:

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

        
    }) 

解决方法很简单...

在初始化peer的时候将调试级别设置为3,然后你会看到错误

peer.call 不是 运行 因为您可能没有传递参数、id 或流...