To build a video call app, each client needs to send their video and audio streams to all other clients. We achieve this using Peer.js for peer-to-peer connections and Socket.io for client-server communication via WebSocket.

Prerequisites:

  1. Node.js: An open-source JavaScript backend technology, equipped with npm (Node Package Manager) for easy installation of various packages. Node.js allows developers to build scalable network applications using JavaScript on the server side. To learn more, visit the official Node.js website.
  2. Express.js: A server framework for Node.js that simplifies the development of web applications and APIs. It provides a robust set of features for building single-page, multi-page, and hybrid web applications. For more information, check out the Express.js documentation.
  3. Socket.io: Enables real-time, event-based, bidirectional communication between the server and clients. It is particularly useful for applications that require real-time updates, such as chat applications, live feeds, or online gaming. To get started, visit the Socket.io website.
  4. Peer.js: Facilitates the transmission and reception of audio and video streams between clients, making it easier to build WebRTC-based applications. Peer.js abstracts much of the WebRTC API, providing a simple interface for peer-to-peer communication. Learn more by visiting the Peer.js website.

Setting Up the Environment:

Begin by creating and initializing a new repository as the first step in setting up your development environment.

$ mkdir VideoCallApp 
$ cd VideoCallApp
$ npm init

Now, the next step is to install the required packages for our VideoCallApp.

  • Express: A server-side framework for Node.js.
  • EJS: A simple templating language that allows you to generate HTML markup using plain JavaScript.
  • Socket.io: Manages WebSocket for event-driven communication.
  • Nodemon (optional): Automatically restarts the server whenever project files are saved.
  • UUID module: Generates unique IDs, which will be utilized in this project.

Installing the required modules:

$ npm install express
$ npm install ejs
$ npm install socket.io
$ npm install nodemon

Now, we all set for the implementation part.

Implementation:

Step 1: Create a server file — server.js

// Importing express module
const express = require('express'); 
const app = express(); 
 
app.set("view engine", "ejs"); 
 
// Calling the public folder
app.use(express.static("public")); 
 
// Handling get request
app.get("/" , (req,res)=>{
  res.send("Welcome to NextBigBlog Video Call App"); 
});
 
// Listing the server 
app.listen(4000 , ()=>{
    console.log("Server running on port 4000");
})

Execution command for server.js

node server.js

Now, If you open the local host i.e. localhost:4000 You will see the output i.e. — Welcome to NextBigBlog Video Call App.

Now, For socket.io we need to write some more code. Here, we added code for socket.io and we just change app.listen() to server.listen() methods.

Now we are all set for the client side development.

const server = require('http').Server(app);
const io = require('socket.io')(server);
 
server.listen(4000 , ()=>{
    console.log("Server running on port 4000");
);

Step2: Create two folders one is public and the second is views.

Project structure:

video call
  • Now in views create an index.ejs file which contains all html code.
  • Here, we added three script files, first one is for peerjs, the second one is for socket.io and the last one is our main index.js file.

Index.ejs file

<!DOCTYPE html>
<html lang="en" dir="ltr">
 
<head>
    <meta charset="utf-8" />
    <title>Video App</title>
    <style media="screen">
        * {
            margin: 0;
        }
 
        #videoDiv {
            display: grid;
            grid-gap: 10px;
            height: 80%;
            position: relative;
            grid-template-columns: repeat(auto-fill, 300px);
            grid-auto-rows: 300px;
        }
 
        #footer {
            width: 100%;
            height: 50px;
            background-color: white;
            display: flex;
            justify-content: center;
            flex: 1;
            border-bottom: 1px solid grey;
            margin-top: 10px;
        }
 
        button {
            height: 30px;
            width: 80px;
            margin-top: 10px;
            text-align: center;
            border-radius: 10px;
            outline: none;
            border: none;
            text-decoration: none;
            background-color: red;
            cursor: pointer;
        }
 
        video {
            width: 100%;
            height: 100%;
            object-fit: cover;
            border: 2px solid white;
        }
    </style>
    <script>
        var roomID = "<%= RoomId %>"
    </script>
 
    <script src=
"https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"
        defer>
    </script>
     
    <script src="socket.io/socket.io.js" defer>
    </script>
     
    <script src="index.js" charset="utf-8" defer>
    </script>
</head>
 
<body>
    <div id="videoDiv"></div>
</body>
 
</html>

Note — you can create your own UI, I created a simple one.

  • Now in the public folder create an index.js file for your index.ejs file and write some code.
const socket = io('/');
const peer = new Peer();

peer.on('open' , (id)=>{
    socket.emit("newUser" , id);
});

So whenever the new user will get connected they will get a unique id through the peer.js and after that it emits a socket event for the server i.e newUser.

So to handle this event we need to add some more code in our server-side.

Javascript


io.on('connection' , (socket)=>{
    socket.on('newUser' , (id)=>{
        socket.join('/');
        socket.to('/').broadcast.emit("userJoined" , id);
    });
});

Now when this event occurs the server will tell all the other clients that the new user is connected.

Let’s Implement the main function of this app – 

Now we are going to take users audio, video streams and send that stream to another client. For this, we are going to use WebRTC here.

Code to take video and audio of the user

Javascript

navigator.mediaDevices.getUserMedia({
  video:true,
  audio:true
}).then((stream)=>{
 
      // Some more code
}).catch(err=>{
    alert(err.message)
})

Now we need to send the stream to all other clients, so let’s implement that part-

Here we have a peer.js method named as call. It will call the other client to send and receive streams.

Client 1: Client 1 will call client 2 as shown below.

Javascript

socket.on('userJoined' , id=>{
  console.log("new user joined")
 
  // Calling other client and sending our stream
  const call  = peer.call(id , myVideoStream);
  const vid = document.createElement('video');
  call.on('error' , (err)=>{
    alert(err);
  })
 
  // Taking the stream of the other client
  // when they will send it.
  call.on('stream' , userStream=>{
 
    // addVideo is a function which append
    // the video of the clients
    addVideo(vid , userStream);
  })

Client 2: let’s see how client 2 will respond to the client 1 call.

Javascript

peer.on('call' , call=>{
 
    // Here client 2 is answering the call
    // and sending back their stream
    call.answer(stream); 
        const vid = document.createElement('video');
 
    // This event append the user stream. 
    call.on('stream' , userStream=>{
        addVideo(vid , userStream);
    })
    call.on('error' , (err)=>{
        alert(err)
    })
  })

Note — You can deploy it on any platform you want, In my case I deployed it on heroku.com

Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *