Back to Blog

Building Your Own Group Voice Calling Application Using the Agora Web SDK

Building Your Own Group Voice Calling Application Using the Agora Web SDK

This blog was written by Akshat Gupta an Agora Superstar. The Agora Superstar program empowers developers around the world to share their passion and technical expertise, and create innovative real-time communications apps and projects using Agora’s customizable SDKs.


Introduction

Love talking to your friends or colleagues but feel current applications aren’t living up to your expectations? If you’re an enthusiastic developer like me, I bet you must be thinking of developing your own customizable group calling application!

In this tutorial, we will develop a web application that supports voice calling among multiple users using the Agora Web SDK.

Building Your Own Group Voice Calling Application Using the Agora Web SDK - Screenshot #1
Screenshot of the simple voice calling application we will be developing.

Prerequisites:

Project Setup

Let’s start by laying out our basic HTML structure. A few UI elements are necessary, such as the local audio stream uid, the remote audio streams’ uids, and buttons for joiningleaving, and muting and unmuting. I’ve also imported the necessary CDNs and linked the custom CSS and JS files.

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta Tags For SEO -->
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Group Voice Call || Agora Web SDK NG</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css"
integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<link rel="stylesheet" href="assets/css/o2o-voice.css">
<link rel="icon" href="assets/img/favicon.png" type="image/png">
<link rel="apple-touch-icon" href="assets/img/apple-touch-icon.png" type="image/png">
</head>
<body>
<!-- Title -->
<div class="container-fluid banner">
<p class="banner-text">Voice Call</p>
</div>
<div class="container">
<form id="join-form" name="join-form" class="mt-4">
<!-- Input Field -->
<div class="row join-info-group">
<div class="col-sm">
<p class="join-info-text">Channel</p>
<input id="channel" type="text" placeholder="Enter Channel Name" required class="form-control">
</div>
</div>
<!-- UI Controls -->
<div class="button-group mt-3">
<button id="join" type="submit" class="btn btn-live btn-sm">Join</button>
<button id="mic-btn" type="button" class="btn btn-live btn-sm" disabled>
<i id="mic-icon" class="fas fa-microphone"></i>
</button>
<button id="leave" type="button" class="btn btn-live btn-sm" disabled>Leave</button>
</div>
</form>
<!-- Streams -->
<div class="row video-group">
<div class="col">
<p id="local-player-name" class="player-name"></p>
<div id="local-player" class="player"></div>
</div>
<div class="w-100"></div>
<div class="col">
<div id="remote-playerlist"></div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"></script>
<script src="https://download.agora.io/sdk/release/AgoraRTC_N.js"></script>
<script src="assets/js/o2o-voice.js"></script>
</body>
</html>
view raw o2o-voice.html hosted with ❤ by GitHub
Building Your Own Group Voice Calling Application Using the Agora Web SDK - Screenshot #2
Screenshot of our site with the above code.

Adding Color

Now that our basic layout is ready, it’s time to add some CSS.
I’ve already added basic Bootstrap classes to the HTML to make the site presentable, but we’ll use custom CSS to match the site with a blue Agora-based theme.


https://gist.github.com/akshatvg/6f8a7297da5ecf942d1c51b10ee124b9

Building Your Own Group Voice Calling Application Using the Agora Web SDK - Screenshot #3
The magic of CSS.

Muting and Unmuting the Audio

Let’s add some functionality to our beautiful website. We will begin with the UI controls muting and unmuting the audio. A little JS here and a little JS there does the job:

enableUiControls();
// Action buttons
function enableUiControls() {
$("#mic-btn").click(function () {
toggleMic();
});
}
// Toggle Mic
function toggleMic() {
if ($("#mic-icon").hasClass('fa-microphone')) {
rtc.localAudioTrack.setEnabled(false);
console.log("Muted.");
} else {
rtc.localAudioTrack.setEnabled(true);
console.log("Unmuted.");
}
$("#mic-icon").toggleClass('fa-microphone').toggleClass('fa-microphone-slash');
}
view raw o2o-voice-ui.js hosted with ❤ by GitHub

Core Functionality (JS)

Now that we have the HTML/DOM structure laid out, we can add the JS, which uses the Agora Web SDK . It may look intimidating at first, but if you follow Agora’s official docs and demos and put in a little practice, it’ll be a piece of cake.

We first create a client and then create a microphone audio track (line 58). You can use a .env file or directly hardcode the App ID in the application and take in the channel name and token (optional) from the front end.
If you don’t use tokens, specify the tokens as null.

When a user joins a channel by clicking the button, you begin playing the tracks specified while creating the client. The user’s stream is then published (line 60)and subscribed (line 68) which can be toggled using the UI controls we wrote above.

When a track is unpublished (line 84), remove the uid from the user’s screen.

Finally, we give the user an option to end the call and leave (line 43) the channel.

var rtc = {
// For the local client.
client: null,
// For the local audio track.
localAudioTrack: null,
};
var options = {
appId: "<>",
channel: null,
token: null,
};
// the demo can auto join channel with params in url
$(() => {
var urlParams = new URL(location.href).searchParams;
options.appid = "<>";
options.channel = urlParams.get("channel");
if (options.appid && options.channel) {
$("#channel").val(options.channel);
$("#join-form").submit();
}
})
$("#join-form").submit(async function (e) {
e.preventDefault();
$("#join").attr("disabled", true);
try {
options.appid = "<>";
options.channel = $("#channel").val();
await join();
} catch (error) {
console.error(error);
} finally {
$("#leave").attr("disabled", false);
}
})
$("#leave").click(function (e) {
leaveCall();
})
async function leaveCall() {
// Destroy the local audio and track.
rtc.localAudioTrack.close();
// Leave the channel.
await rtc.client.leave();
$("#mic-btn").prop("disabled", true);
$("#join").attr("disabled", false);
$("#leave").attr("disabled", true);
}
async function join() {
rtc.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
const uid = await rtc.client.join(options.appId, options.channel, options.token, null);
$("#mic-btn").prop("disabled", false);
// Create an audio track from the audio sampled by a microphone.
rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
// Publish the local audio track to the channel.
await rtc.client.publish([rtc.localAudioTrack]);
$("#local-player-name").append(`<div id="player-wrapper-${uid}">
<p class="player-name">localUser(${uid})</p>
</div>`);
// publish local tracks to channel
console.log("Successfully published.");
rtc.client.on("user-published", async (user, mediaType) => {
// Subscribe to a remote user.
await rtc.client.subscribe(user, mediaType);
console.log("Successfully subscribed.");
// If the subscribed track is audio.
if (mediaType === "audio") {
const player = $(`
<div id="player-wrapper-${uid}">
<p class="player-name">remoteUser(${uid})</p>
</div>
`);
$("#remote-playerlist").append(player);
// Get `RemoteAudioTrack` in the `user` object.
const remoteAudioTrack = user.audioTrack;
// Play the audio track. No need to pass any DOM element.
remoteAudioTrack.play();
}
});
rtc.client.on("user-unpublished", user => {
// Get the dynamically created DIV container.
const playerContainer = document.getElementById("player-wrapper-" + uid);
// Destroy the container.
playerContainer.remove();
});
}
view raw o2o-voice.js hosted with ❤ by GitHub

Note: You need to enter your own App ID in the JS code above. I replaced my App ID by <> to avoid unnecessary charges.

You can now run and test the application.

Note: For testing, you can use two (or more) browser tabs to simulate multiple users on the call.

Conclusion

You did it!

We have successfully made our very own group voice calling application. In-case you weren’t coding along or want to see the finished product all together, I have uploaded all the code to GitHub:

Building Your Own Group Voice Calling Application Using the Agora Web SDK - Screenshot #4

If you would like to see the demo in action, check out the demo of the code in action on:

Building Your Own Group Voice Calling Application Using the Agora Web SDK - Screenshot #5

Thanks for taking the time to read my tutorial. If you have questions, please let me know with a comment. If you see room for improvement, feel free to fork the repo and make a pull request!

Other Resources:

To learn more about Agora’s Web NG SDK and other use cases you can refer to the developer guide given over here:

You can also have a look at the complete documentation for the functions discussed above and many more over here.

You can also join the Agora Developer Slack Community:

RTE Telehealth 2023
Join us for RTE Telehealth - a virtual webinar where we’ll explore how AI and AR/VR technologies are shaping the future of healthcare delivery.

Learn more about Agora's video and voice solutions

Ready to chat through your real-time video and voice needs? We're here to help! Current Twilio customers get up to 2 months FREE.

Complete the form, and one of our experts will be in touch.

Try Agora for Free

Sign up and start building! You don’t pay until you scale.
Try for Free