javascriptnode.jswebrtcvideochatpeerjs

Problem in creating A Video Chat App With WebRTC


I want to create a video chat app. But My app is not showing others participate video. Please help. When others participate joined. It doesn't show his video on my window. Here is my code. Thanks in advance.

Here is the code for the server. Server.js -

    const express = require('express');
    
    const app = express();
    const server = require('http').Server(app);
    const io = require('socket.io')(server)
    const { v4: uuidV4 } = require('uuid')
    const { ExpressPeerServer } = require('peer');
    const peerServer = ExpressPeerServer(server,{
      debug: true
    })
    
    app.set('view engine', 'ejs')
    app.use(express.static('public'))
    
    app.use('/peerjs', peerServer)
    
    app.get('/', (req,res)=>{
      res.redirect(`/${uuidV4()}`)
    })
    
    
    app.get('/:room', (req, res) => {
      res.render('room', { roomId: req.params.room })
    })
    
    
    io.on('connection',socket =>{
      socket.on('join-room',(roomId, userId)=>{
        socket.join(roomId);
        socket.to(roomId).broadcast.emit('user-connected', userId);
      })
    })


server.listen(process.env.PORT || 3030);

It is the main script. Script.js-

const socket = io('/')

const videoGrid = document.getElementById('video_grid')

let myVideoStream;
const myVideo = document.createElement('video')
myVideo.muted = true;

var peer = new Peer(undefined, {
  path: '/peerjs',
  host: '/',
  port: '3030'
}); 

navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(stream => {
  myVideoStream = stream;
  addVideoStream(myVideo, stream)

  peer.on('call', call=>{
    call.answer(stream)
    const video = document.createElement('video')
    call.on('stream', userVideoStream=>{
      addVideoStream(video, userVideoStream)
      
    })
  })

  socket.on('user-connected', userId =>{
    connecToNewUSer(userId, stream);
    alert('Somebody connect', userId)
    
  })
  
}
)
  peer.on('open', id =>{
    socket.emit('join-room', ROOM_ID, id) ;
  })
   

  


  const connecToNewUSer = (userId, stream) => {
    const call = peer.call(userId, stream)
    const video = document.createElement('video')
    call.on('stream', userVideoStream =>{
      addVideoStream(video, userVideoStream)
      
    }) 
  }

  

  function addVideoStream(video, stream) {
    video.srcObject = stream
    video.addEventListener('loadedmetadata', () => {
      video.play()
    })
    videoGrid.append(video)
  }

It is the ejs file. room.ejs -

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ZOOM</title>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>
  <script>
    const ROOM_ID = "<%= roomId %>"
  </script>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="video_grid">
      
  </div>
  <script src="script.js"></script>
</body>
</html>

Solution

  • You need STUN and TURN server. These two servers help connect/find users behind the NAT.

    Here's some basic:

    var peer = new Peer(undefined, {
      path: '/peerjs',
      host: '/',
      port: '3030',key: "peerjs",
        config: {
            "iceServers" : [
                {urls: "stun:<yourstunserver.addres>:5349"},
                { 
                    urls: "turn:<yourturnserver.address>:5349",
                    username: "<turn username>",
                    credential: "<turn password>",
                }
            ]
        }
    }); 
    

    You can setup your own STUN/TURN server using coturn, it's free and easy installation.

    I believe that google provide FREE STUN server, but I find noone provide free TURN server.