Chris Bongers is a full-stack developer from the Netherlands. He is passionate about working on a cool web projects and writing tutorial blogs for the community. Follow him on Twitter (@DailyDevTips1) and his website (https://chrisbongers.com/)
Many traditional human interactions have moved online. And as the technology to enable this move becomes ubiquitous, the transition seems inevitable for many industries. Over the course of the past year, we have seen many companies and developers launch digital solutions that can replace traditional human interaction. And building live video streaming and chat web apps might now be easier than you realize.
In this tutorial, I’ll show you how to create your own one-on-one video meeting tool. By the end of it, you will see how easy it is.
Some potential use-cases for such a tool:
Patient-doctor video call
Mentor-mentee video call
Client- contractor video call
One-on-one consultant video call
We will be using Agora to connect two people so they can have a video conference. We will be using vanilla JavaScript to create this project. The cool part is that you can type along and create your own version!
The end result will look like this demo:
Prerequisites
For this project, you will need an Agora account, which can be created following this guide. You will need a basic knowledge of JavaScript and HTML. But don’t worry — I will guide you through this process.
For this project, we will need to create a folder on our computer. Let’s call this folder agora-demo.
After you create this project structure, open the folder in Visual Studio Code. The project structure in VSCode will look like this:
This will be a plain JavaScript-powered tutorial that doesn’t include any frameworks. We will be using a SASS compiler to convert an SCSS file into a CSS file.
We also will be using Live Server to start our project.
Let’s head back to Visual Studio so we can start building our tool.
Note: The demo will provide only one channel. While Agora supports generating as many channels as you need, in this guide we won’t provide a UI so users won’t be able to create their own channels.
HTML Structure
We will start by setting up our HTML in index.html. In our case, we are creating a very basic look, where the user will see a screen with the remote’s user stream in the center. Their own stream will be in the right-hand corner, with some controls at the bottom.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We also used a CDN to load Fontawesome and Agora into our project. And we linked to our CSS stylesheet and our JavaScript file. That concludes the HTML part. We should now have something that looks like this:
That doesn’t look very appealing, does it?
In the next step, we will be adding some styling to make this look better.
Styling the Application
The first thing we’ll do is reset all the paddings and margins.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then we can give the container some basic flex styling and give the header some padding so it’s not so dense.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We also will need a hidden class to hide the start and stop buttons.
Then we can style the two holders (one for video and one for the buttons).
The video styling looks like this:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This styling makes sure that the video has some space and that the video elements placed inside it are positioned accordingly.
You might have spotted the :before pseudo-element. We use those to give feedback to the user about what’s happening.
Then the button bar needs the following styling:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This gives the buttons a nice appeal by using the box-shadow and giving them some space. We also add an active class to showcase which button is active.
Our application should look like this:
OK, it’s beginning to look like a meeting tool. But it won’t really do anything yet.
Connecting to Agora
Let’s connect to Agora. For this, we need to perform a couple of steps in our script.js file.
First, we will create some variables. We will need some options to hold our appID and token. We will also add our channel here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Another variable will hold the users’ own local streams.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then let’s add all of the front-end elements we want to access at one point.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The next step is to create a join function that will connect us to Agora.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Now that we have Agora set up, let’s make this app work and connect our buttons so that we can start having that video chat!
The first button we want to connect to is the join button.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When we click this button it should run the startBasicCall function.
This function will make sure we call the join function, start our video and audio, and subscribe to the stream.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As you can see, we call the join function, and on the callback, we call the start video and audio functions. Then we connect to the stream to wait for the other user to connect. If they connect, we update the specific stream to start receiving.
The remoteVideoTrack.play() takes the argument of remote, which references the ID of the div it should render on.
The last part is that we hide the join button and show the leave button.
Now, let’s create the startVideo function.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The first step here is that we add the connecting class, This will show the user we are doing something. Then we set the rtc variable to update the localVideoTrack with an Agora connected video track. Then we publish this track and remove the connecting class.
With the rtc.localVideoTrack.play(“me”); we tell the div with ID “me” to play this user’s local stream. And we finish by adding the active class to our camera button.
For the startAudio function, we do the same thing, but we use the AgoraRTC.createMicrophoneAudioTrack method.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We also want to be able to stop the stream, so let’s connect to our stop button.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This will call the stop video and audio function, and leave the channel. We also switch out the leave button with the join button.
Let’s create these stop functions.
We close the local audio connection and unpublish it for the other receiver. We then remove the active class from our button.
The same goes for the video.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In this case, we stopped the whole stream. But what if we only want to disconnect our video or audio temporarily?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Based on the active class for either the audio or the video, we will call the respective start or stop functions.
Making Sure It’s a One-on-One Call
Since we want to make sure that the call is one-on-one and that no other people can join our channel, let’s add some checks using Agora RTC.
Once a person joins this channel, we will check the number of users the client has. If this number is greater than 1, it should be invalid and the user trying should be removed.
Let’s modify the user-published callback:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The roomFull function will handle all the logic for us:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This will call the leave function we made before and add a full class to the remote user div.
Now we just need to add some styling to this div:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
To test the application, you can download the files from GitHub. Make sure you open the script.js file and add your client details. Then you can open the index.html file in one browser tab and duplicate it in another tab.
You should be able to see yourself twice now. It’s best to mute the microphone since it can echo.
Conclusion
And that’s it — we now have an interactive meeting tool using Agora and vanilla JavaScript!
Thanks to Agora, building such an interactive meeting tool is easier than ever. I’m challenging you to think of other ways to use Agora and come up with your own video solution.
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.