Welcome folks today in this blog post we will be building a zoom clone video chat app in node.js and express using socket.io & webrtc library called peerjs using javascript. All the full source code of the application is shown below.
Get Started
In order to get started you need to make a node.js
project using the below command as shown below
npm init -y
Now you need to install the below dependencies using the npm
command as shown below
npm i express
npm i uuid
npm i ejs
npm i socket.io
And now you need to install the peerjs
library globally inside your system using the below command as shown below
npm i -g peerjs
The directory structure of the app is shown below
Now you need to make the server.js
file inside the root directory and copy paste the following code
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
const express = require('express') const app = express() const server = require('http').Server(app) const io = require('socket.io')(server) const { v4: uuidV4 } = require('uuid') app.set('view engine', 'ejs') app.use(express.static('public')) 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) socket.on('disconnect', () => { socket.to(roomId).broadcast.emit('user-disconnected', userId) }) }) }) server.listen(3000) |
As you can see we are importing the express and the required libraries. And then we are making a simple get
request to the homepage
where we are generating the random room id for the zoom app. And inside it we are redirecting to that random url. And now we need to handle this request. So we have defined the get request to the random room. And inside it we are loading the ejs
template called room.ejs
which will be stored inside the views folder. And we are passing the roomId to the template file. This roomId we are receiving as a query parameter. And also we are using the socket.io
server to keep track whether the new client connected or disconnected. Based upon which roomId is generated we allow the users inside this to join the room using the join()
method. And then we broadcast to each client connected in this zoom app that new user has joined or left the chat.
Now make a views
folder and inside it make a room.ejs
file and copy paste the following code
views/room.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <script> const ROOM_ID = "<%= roomId %>" </script> <script defer src="https://unpkg.com/peerjs@1.2.0/dist/peerjs.min.js"></script> <script src="/socket.io/socket.io.js" defer></script> <script src="script.js" defer></script> <title>Document</title> <style> #video-grid { display: grid; grid-template-columns: repeat(auto-fill, 300px); grid-auto-rows: 300px; } video { width: 100%; height: 100%; object-fit: cover; } </style> </head> <body> <div id="video-grid"></div> </body> </html> |
As you can see in the above file we have a div
tag where we will be showing the user webcam video
on the webpage. Now we need to make a public folder and inside it we will be creating the script.js
file
public/script.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
const socket = io('/') const videoGrid = document.getElementById('video-grid') const myPeer = new Peer(undefined, { host: '/', port: '3001' }) const myVideo = document.createElement('video') myVideo.muted = true const peers = {} navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => { addVideoStream(myVideo, stream) myPeer.on('call', call => { call.answer(stream) const video = document.createElement('video') call.on('stream', userVideoStream => { addVideoStream(video, userVideoStream) }) }) socket.on('user-connected', userId => { connectToNewUser(userId, stream) }) }) socket.on('user-disconnected', userId => { if (peers[userId]) peers[userId].close() }) myPeer.on('open', id => { socket.emit('join-room', ROOM_ID, id) }) function connectToNewUser(userId, stream) { const call = myPeer.call(userId, stream) const video = document.createElement('video') call.on('stream', userVideoStream => { addVideoStream(video, userVideoStream) }) call.on('close', () => { video.remove() }) peers[userId] = call } function addVideoStream(video, stream) { video.srcObject = stream video.addEventListener('loadedmetadata', () => { video.play() }) videoGrid.append(video) } |
As you can see we have defined and started the peerjs
server on port 3001. This server we need to start on the different command line.
peerjs --port 3001
Now run the express app
in the command line as shown below
node server.js
Now if you open the browser and type http://localhost:3000
then a new roomId will be assigned and you will be able to video chat with multiple people at same time.