Why PeerJs changes MediaStream when sending it to someone?

36 views Asked by At

I am writing video chat app using Next.js 14, Express, socket.io, peerjs

And the problem is that I send one stream and the user receives a changed one. And this is happens when I join a room with the camera turned off.

If I am already in the room and user joins this room

useUpdateEffect(() => {
    if (!peer) return;

    socket.on(
      "user:joined",
      ({
        peerId: remotePeerId,
        muted: remoteMuted,
        visible: remoteVisible,
        name: remoteName,
        email: remoteEmail,
        image: remoteImage,
      }) => {
        toast.success(`${remoteName} joined`);
        // Calling new user
        console.log("My stream", stream?.getTracks());

        const call = peer.call(
          remotePeerId,
          stream as MediaStream, // my stream
          {
            metadata: {
              user: {
                email: data?.user?.email,
                name: data?.user?.name,
                image: data?.user?.image,
              },
              muted,
              visible,
            },
          },
        );
        call.on("stream", (remoteStream: MediaStream) => {
          console.log("User b stream", remoteStream.getTracks());
          addConnection({
            peerId: remotePeerId,
            connection: call,
            stream: remoteStream,
            muted: remoteMuted,
            visible: remoteVisible,
            name: remoteName,
            email: remoteEmail,
            image: remoteImage,
          });
        }); // On new user answer
      },
    );
    return () => {
      socket.off("user:joined");
    };
  }, [peer]);

Me as a new user

useUpdateEffect(() => {
    if (!peer) return;

    peer.on("call", (call: any) => {
      const { peer: remotePeerId, metadata } = call;
      const {
        user: remoteUser,
        muted: remoteMuted,
        visible: remoteVisible,
      } = metadata;

      call.answer(stream); // * answers incoming call with my stream
      console.log("My stream", stream?.getTracks());

      call.on("stream", (remoteStream: MediaStream) => {
        console.log("User a stream", remoteStream.getTracks());
        addConnection({
          peerId: remotePeerId,
          connection: call,
          stream: remoteStream,
          muted: remoteMuted,
          visible: remoteVisible,
          name: remoteUser.name,
          image: remoteUser.image,
          email: remoteUser.email,
        });
      }); // * new stream stream
      call.on("close", () =>
        toast.success(`${remoteUser.name} has left the room`),
      );
    });
  }, [peer]);
Video tracks the first user sends Video tracks that second user gets
enter image description here enter image description here
Video tracks that first user gets Video tracks that second user sends
enter image description here enter image description here

But I am expecting same tracks

Here is the git link https://github.com/ZAKHAROV-Artem/stack-overflow-problem

1

There are 1 answers

0
Артем Захаров On

I think that I found the solution :)

<video
    ref={(node) => {
        if (node) node.srcObject = stream;
    }}
    autoPlay
    muted={true}
    className="aspect-video h-full w-full -scale-x-100 rounded-xl object-contain"
/>
<audio
    ref={(node) => {
        if (node) {
            node.srcObject = stream;
        }
    }}
    autoPlay
    muted={isMe}
/>

I think the following code bounds audio and video together, so as soon as we set enabled=false to audio it sets muted=true to video:

await navigator.mediaDevices.getUserMedia({
    audio: !muted,
    video: visible,
});

Maybe, it is possible to handle them and independent tracks, so if you know how, please share.