An Interest In:
Web News this Week
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
Create simple voice chat app with nodejs
Hi, I'm Hossein in this article we will build a simple voice chat web application with nodejs and socketIo.
In the first step, we will create a simple interface for our app. To did that we use handlebars.
Before starting coding we must install dependencies, run commands below:npm init -y
npm i express socket.io express-handlebars
After installing dependencies, create and open index.js file and put codes below into it:
const express = require("express");const app = express();const handlebars = require("express-handlebars");const http = require("http").Server(app);const io = require("socket.io")(http);//To holding users information const socketsStatus = {};//config and set handlebars to expressconst customHandlebars = handlebars.create({ layoutsDir: "./views" });app.engine("handlebars", customHandlebars.engine);app.set("view engine", "handlebars");//enable user access to public folder app.use("/files", express.static("public"));app.get("/home" , (req , res)=>{ res.render("index");});http.listen(3000, () => { console.log("the app is run in port 3000!");});
Now we jump into handlebars files first create main.handlebars in views directory:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hossein Mobarakian - voice chat application</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.2/socket.io.js" integrity="sha512-iZIBSs+gDyTH0ZhUem9eQ1t4DcEn2B9lHxfRMeGQhyNdSUz+rb+5A3ummX6DQTOIs1XK0gOteOg/LPtSo9VJ+w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script></head><body> {{{body}}}</body></html>
Note: main.handlebars is the base template in handlebars and you can change it in config your handlebars setting.
In this step we can go to create index.handlebars in the views directory.
<header> <div class="user-controller"> <p id="username-label"></p> <div id="username-div"> <input type="text" id="username"> <button class="username-btn" onclick="changeUsername()">Change username</button> </div> </div> <div class="controller"> <button class="control-btn disable-btn" onclick="toggleMicrophone(this)">Open microphone</button> <button class="control-btn disable-btn" onclick="toggleMute(this)">Mute</button> <button class="control-btn disable-btn" onclick="toggleConnection(this)">Go online</button> </div></header><h2>users list</h2><ul class="users" id="users"></ul><script src="/files/js/index.js"></script><link rel="stylesheet" href="https://dev.to/files/css/index.css">
Add some style to our interface with create index.css in /public/css/ folder.
html , body { width: 100%; height: 100%; overflow: hidden;}.controller{ margin: 0; padding: 0; overflow: hidden; display: flex; justify-content: center;}body{ display: flex; text-align: center; flex-flow: column; margin: 0; padding: 0; background-color: rgb(12 11 25); color: #fff;}header{ margin:0; padding: 20px 0; width: 100%; height: fit-content; background-color: rgb(15, 15, 44); color: #fff;}.control-btn{ width: 120px; padding: 10px 0; border: none; border-radius: 8px; cursor: pointer;}.enable-btn{ background-color: rgb(26, 184, 26); color: #fff; border-bottom: 5px solid rgb(18, 131, 18); margin: 10px ;}.enable-btn:hover{ border-bottom: none; margin-top: 15px;}.disable-btn{ margin: 10px ; background-color: rgb(172, 25, 25); color: #fff; border-bottom: 5px solid rgb(184, 57, 57);}.disable-btn:hover{ border-bottom: none; margin-top: 15px;}.username-btn{ width: 200px; margin: 10px auto; padding: 10px 0;}input{ width: 200px; padding: 10px; margin: 10px auto;}#username-div{ display: none;}#username-label{ width: 200px; height: fit-content; margin: 0 auto; padding: 10px 20px; background-color: rgb(12 11 25); border-radius: 8px; border: 2px solid rgb(26, 26, 77); cursor: pointer;}ul.users{ width: 100%; margin: 0; padding: 0;}ul.users li{ width: 90%; margin: 10px auto; padding: 10px 0; text-align: center; background-color: rgb(15 15 44); list-style: none; color: #fff; border-radius: 8px;}
In the last part of this project, we use socket to make our app in realtime.Now put socket codes into index.js above the http.listen(...):
io.on("connection", function (socket) { const socketId = socket.id; socketsStatus[socket.id] = {}; console.log("connect"); socket.on("voice", function (data) { var newData = data.split(";"); newData[0] = "data:audio/ogg;"; newData = newData[0] + newData[1]; for (const id in socketsStatus) { if (id != socketId && !socketsStatus[id].mute && socketsStatus[id].online) socket.broadcast.to(id).emit("send", newData); } }); socket.on("userInformation", function (data) { socketsStatus[socketId] = data; io.sockets.emit("usersUpdate",socketsStatus); }); socket.on("disconnect", function () { delete socketsStatus[socketId]; });});
After that create a front-end javascript file in /public/js/index.js and put codes below into it:
const userStatus = { microphone: false, mute: false, username: "user#" + Math.floor(Math.random() * 999999), online: false,};const usernameInput = document.getElementById("username");const usernameLabel = document.getElementById("username-label");const usernameDiv = document.getElementById("username-div");const usersDiv = document.getElementById("users");usernameInput.value = userStatus.username;usernameLabel.innerText = userStatus.username;window.onload = (e) => { mainFunction(1000);};var socket = io("ws://localhost:3000");socket.emit("userInformation", userStatus);function mainFunction(time) { navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { var madiaRecorder = new MediaRecorder(stream); madiaRecorder.start(); var audioChunks = []; madiaRecorder.addEventListener("dataavailable", function (event) { audioChunks.push(event.data); }); madiaRecorder.addEventListener("stop", function () { var audioBlob = new Blob(audioChunks); audioChunks = []; var fileReader = new FileReader(); fileReader.readAsDataURL(audioBlob); fileReader.onloadend = function () { if (!userStatus.microphone || !userStatus.online) return; var base64String = fileReader.result; socket.emit("voice", base64String); }; madiaRecorder.start(); setTimeout(function () { madiaRecorder.stop(); }, time); }); setTimeout(function () { madiaRecorder.stop(); }, time); }); socket.on("send", function (data) { var audio = new Audio(data); audio.play(); }); socket.on("usersUpdate", function (data) { usersDiv.innerHTML = ''; for (const key in data) { if (!Object.hasOwnProperty.call(data, key)) continue; const element = data[key]; const li = document.createElement("li"); li.innerText = element.username; usersDiv.append(li); } });}usernameLabel.onclick = function () { usernameDiv.style.display = "block"; usernameLabel.style.display = "none";}function changeUsername() { userStatus.username = usernameInput.value; usernameLabel.innerText = userStatus.username; usernameDiv.style.display = "none"; usernameLabel.style.display = "block"; emitUserInformation();}function toggleConnection(e) { userStatus.online = !userStatus.online; editButtonClass(e, userStatus.online); emitUserInformation();}function toggleMute(e) { userStatus.mute = !userStatus.mute; editButtonClass(e, userStatus.mute); emitUserInformation();}function toggleMicrophone(e) { userStatus.microphone = !userStatus.microphone; editButtonClass(e, userStatus.microphone); emitUserInformation();}function editButtonClass(target, bool) { const classList = target.classList; classList.remove("enable-btn"); classList.remove("disable-btn"); if (bool) return classList.add("enable-btn"); classList.add("disable-btn");}function emitUserInformation() { socket.emit("userInformation", userStatus);}
run command:node index.js
Congratulation! Now you have a realtime voice chat app created with nodejs and socketIo.I hope useful this article to you and thank you to read it.
Original Link: https://dev.to/hosseinmobarakian/create-simple-voice-chat-app-with-nodejs-1b70
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To