How to fix remote video not showing up on peerjs video call in nextjs?

In my next.js project, I’m trying to create a way to have p2p video calls; however, the remote caller’s video isn’t showing up. This works fin in different tabs but not different browsers or computers. I’m trying to figure out what the problem is. I tried using an open relay turn server, but that didn’t yield different results. Here is my code:

import { useEffect, useRef, useState } from 'react';
import Peer from 'peerjs';

const VideoChat = () => {
  const [peerId, setPeerId] = useState(null);
  const [remoteStreams, setRemoteStreams] = useState([]);
  const userVideoRef = useRef();
  const peerRef = useRef();

  useEffect(() => {
    const peer = new Peer(undefined, {
      path: '/myapp',
      host: 'my-server-url',
      port: 443,
      secure: true,
      config: {
        iceServers: [
          { url: 'stun:stun.l.google.com:19302' },
          {
            url: 'turn:open-relay-app-url.metered.live',
            credential: 'open-relay-API-key',
            username: 'open-relay-username'
          }
        ]
      }
    });

    peerRef.current = peer;

    peer.on('open', id => {
      setPeerId(id);
      console.log('My Peer ID:', id);
    });

    peer.on('call', call => {
      navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(localStream => {
        if (userVideoRef.current) {
          userVideoRef.current.srcObject = localStream;
          userVideoRef.current.play().catch(err => console.error('Error playing local video:', err));
        }
        call.answer(localStream);

        call.on('stream', remoteStream => {
          if (remoteStream && remoteStream.getTracks().length > 0) {
            const remoteVideo = document.createElement('video');
            remoteVideo.autoplay = true;
            remoteVideo.style.width = '300px';
            remoteVideo.style.height = '200px';
            document.getElementById('remote-videos').appendChild(remoteVideo);

            remoteVideo.srcObject = remoteStream;
            remoteVideo.play().catch(err => console.error('Error playing remote video:', err));

            setRemoteStreams(prev => [...prev, { id: call.peer, stream: remoteStream }]);
          } else {
            console.error('Remote stream not available.');
            alert('Error: Remote stream not available.');
          }
        });

        call.on('error', err => {
          console.error('Call error:', err);
          alert('Error during call: ' + err.message);
        });
      }).catch(err => {
        console.error('Error accessing media devices.', err);
        alert('Error accessing media devices: ' + err.message);
      });
    });

    peer.on('error', err => {
      console.error('Peer error:', err);
      alert('Error with peer connection: ' + err.message);
    });

    return () => {
      peer.destroy();
    };
  }, []);

  const callPeer = peerIdToCall => {
    navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(localStream => {
      if (userVideoRef.current) {
        userVideoRef.current.srcObject = localStream;
        userVideoRef.current.play().catch(err => console.error('Error playing local video:', err));
      }

      const call = peerRef.current.call(peerIdToCall, localStream);

      call.on('stream', remoteStream => {
        if (remoteStream && remoteStream.getTracks().length > 0) {
          const remoteVideo = document.createElement('video');
          remoteVideo.autoplay = true;
          remoteVideo.style.width = '300px';
          remoteVideo.style.height = '200px';
          document.getElementById('remote-videos').appendChild(remoteVideo);

          remoteVideo.srcObject = remoteStream;
          remoteVideo.play().catch(err => console.error('Error playing remote video:', err));

          setRemoteStreams(prev => [...prev, { id: peerIdToCall, stream: remoteStream }]);
        } else {
          console.error('Remote stream not available.');
          alert('Error: Remote stream not available.');
        }
      });

      call.on('error', err => {
        console.error('Call error:', err);
        alert('Error during call: ' + err.message);
      });
    }).catch(err => {
      console.error('Error accessing media devices.', err);
      alert('Error accessing media devices: ' + err.message);
    });
  };

  return (
    <div className="bg-red-500">
      <h1>Video Chat</h1>
      <p>Your Peer ID: <strong>{peerId}</strong></p>
      <div id="user-video">
        <video ref={userVideoRef} autoPlay muted style={{ width: '300px', height: '200px' }} />
      </div>
      <div id="remote-videos">
        {remoteStreams.length > 0 ? (
          remoteStreams.map(({ id, stream }) => (
            <div key={id}>
              <video
                ref={el => {
                  if (el) {
                    el.srcObject = stream;
                    el.play().catch(err => console.error('Error playing remote video:', err));
                  }
                }}
                autoPlay
                style={{ width: '300px', height: '200px' }}
              />
            </div>
          ))
        ) : (
          <p>No remote video streams available.</p>
        )}
      </div>
      <button onClick={() => callPeer(prompt('Enter peer ID to call:'))}>
        Call Peer
      </button>
    </div>
  );
};

export default VideoChat;

I’m using an express server. Here is my code for that:

// server.js
const { PeerServer } = require('peer');
const peerServer = PeerServer({ port: 9000, path: '/myapp' });