create custom video conferencing app using WebRTC, node.js and vidyo.io

Most of us are familiar with video conferencing. Indeed, it has changed the way many teams and businesses operate. It’s no exaggeration to say that video conferencing is one of the killer apps of the internet age.

Video conferencing as we know it is limited, though. Many companies use third party video conferencing applications. While these applications are the right tool for some jobs, they’re not always ideal. In many cases, it would be preferable to use a custom application that precisely meets the company’s needs. Let’s envision a few scenarios where easy to use, easy to embed video conferencing would help:

  • An e-commerce site could add live, face-to-face help for customers on its site. Alongside the video chat, employees would be able to see the customer’s purchase history, along with the items they’ve looked at today, and what they’ve added to their shopping cart.
  • A financial advisor could enable live video chat with clients. The video chat could be embedded in an application that displays all of the client’s investments and financial history, enabling the advisor to answer client questions quickly.
  • A therapist could use a custom video app to host live therapy sessions. The app could show the patient’s history and the therapist’s notes, enabling the therapist to provide the best advice possible.

The list of possibilities is nearly endless. Easy, on-demand embeddable video conferencing can enhance existing workflows, and enable the creation of entirely new applications that wouldn’t have been possible before. Unfortunately, the specialized expertise required to write a custom, cross platform video conferencing application makes it prohibitively expensive for most companies.

Fortunately, vidyo.io has you covered! Using the Vidyo SDK, developers can quickly create custom video conferencing applications using their existing skills and knowledge.

The Tech Stack

We’ll be using Node.js, JavaScript, and WebRTC to quickly put together a simple video conferencing application.

After its introduction in 2009, Node.js quickly became the world’s most popular server side JavaScript runtime. It is now used to power some of the largest sites on the internet.

WebRTC – which stands for Web Real-time Communication – is, as its name implies, a cross browser standard that makes it possible to add real time communications capabilities to web applications. Although it is very powerful, WebRTC can be difficult to use because it only provides one piece of the overall solution needed for a robust video conferencing app. When it comes to things like firewall traversal, ground calling, and call recording, you are on your own.

Fortunately, as we will see, the vidyo.io SDK makes it possible to do all of this and more by providing a powerful yet simple use API that will makes it easy to get a custom video conferencing app up and running in minutes! Sound interesting? Great! Let’s move on to creating our app.

Creating the Application

To begin, you’ll need to make sure you have Node.js installed. To complete this application, you should be running Node.js 10.14 LTS or newer. If you don’t already have it installed, you can download it from https://nodejs.org.

Next, you’ll need to set up a vidyo.io developer account. You can do this by loading https://vidyo.io/ and clicking the green ‘Sign Up’ button at the top right of the page.

After your account is created, sign in to vidyo. You’ll end up on a dashboard screen with three large buttons: Demo, Learn, and Keys. Click Keys, and you’ll see three options appear below it.

vidyo.io dashboard

Click on ‘API Key’, and you’ll see a screen like the one below:

vidyo.io API key

Click on ‘Add Application’ to create a new application. Give it any name you’d like. Note that you can click on the blue eyeball button to show the entire developer key. Remember this, as you’ll need to use this key soon.

Now, it’s time to write some code.

Open up a terminal or command prompt, and create a new directory for your test application. Name it ‘vidyo-test’. Next, initialize your Node project by running the following commands:

cd vidyo-test
npm init

When npm asks you for a package name, enter vidyo-test. Next, we’re going to install a few packages we’ll need to complete this project. To install the packages, run the following command:

npm install jssha btoa express body-parser

Express.js and body-parser will enable us to setup an API that our vidyo app can request tokens from, and jssha and btoa are libraries that will help us generate Vidyo tokens. It’s important that we generate these tokens server-side, and not in the browser because we must use our application ID and developer key to create these tokens. You should always treat your application ID and developer key as secrets, because if you were to accidentally give them out, you’d effectively be giving out unlimited access to your Vidyo API account!

Next, open the vidyo-test directory in a text editor of your choice. If you’re not sure what to use, Visual Studio Code is a good cross-platform text editor with great JavaScript support.

Create a new file named app.js. This file will contain all of our test app’s server-side code. Start by adding the following code to app.js:

let jsSHA = require('jssha');
let btoa = require('btoa');

let applicationId = "your-app-id";
let developerKey = "you-dev-key";

function getRandomInt() {
return Math.floor(Math.random() * Math.floor(9999));

function generateToken(expiresInSeconds) {
var EPOCH_SECONDS = 62167219200;
var expires = Math.floor(Date.now() / 1000) + expiresInSeconds + EPOCH_SECONDS;
var shaObj = new jsSHA("SHA-384", "TEXT");
shaObj.setHMACKey(developerKey, "TEXT");
jid = "demoUser" + getRandomInt() + '@' + applicationId;
var body = 'provision' + '\x00' + jid + '\x00' + expires + '\x00';
var mac = shaObj.getHMAC("HEX");
var serialized = body + '\0' + mac;
return btoa(serialized);

In the code above, replace the applicationId and developerKey variables with with your actual application ID and developer key. Note that in a production application, you’ll want to keep these values in environment variables, or in a secure key store such as AWS Key Management Service or Kubernetes secrets.

We won’t dive into the details of what the generateToken function is doing. You can find more information on token generation in the vidyo.io developer documentation, along with token generation examples in several languages.

Next, we’re going to add an API endpoint that we’ll be able to call to request tokens that will allow new users to join video calls in our app. Add the following code to app.js:

const express = require('express')
const app = express()
const port = 3000


app.get('/token', (req, res) => {
let thirtyMinutes = 30 * 60;
let response = JSON.stringify({
token: generateToken(thirtyMinutes)

app.listen(port, () => console.log(`Listening on port ${port}!`))

This code imports Express, tells it which directory to serve static files from, and sets up an API endpoint that will let us request tokens for users who are using our application. We’ve hardcoded a token life time of 30 minutes, which should be plenty for our test application. But if you’d like to make it shorter (or longer) for testing purposes, feel free to do so.

Keep in mind that in a real application, you’ll want to ensure that users are signed in to your app before you let them request a token and connect to a Vidyo call. If you made this API public, you’d be letting anyone in the world make calls – at your expense!

Next, we’ll be creating a page that will let our users enter a user name and connect to a video call. Start by creating a new subdirectory named public inside the vidyo-test directory. This is where we will put the HTML page that will host our video conference.

Now that you have created the public directory, create a new file in it named index.html. Populate index.html with the following code:

<!doctype html>
           body {
               width: 100%;
               height: 100%;
           #video {
               width: 800px;
               height: 600px;
           .login-box {
               width: 100%;
               display: flex;
               justify-content: center;
               margin-bottom: 10px;
           .container {
               display: flex;
               flex-direction: column;
               align-items: center;
<div class="container">
<div class="login-box"><label for="name">Name:</label>
<input name="name" type="text" />
<button id="join-call">Join</button></div>
<div id="video"></div>
<script type="text/javascript">
      function onVidyoClientLoaded(status) {
               console.log("function called");
               switch (status.state) {
               case "READY":    // The library is operating normally              
                   console.log("Ready to connect")
                   console.log("Vidyo client load failed.");

           document.querySelector("#join-call").addEventListener("click", function(e) {
               const displayName = document.querySelector("input[name=name]").value;
                   .then(res => res.json())
                   .then(function(data) {
                   const token = data.token;
                   connect(token, displayName);

           function connect(token, displayName) {
                   viewId: "video", // Div ID where the composited video will be rendered
                   viewStyle: "VIDYO_CONNECTORVIEWSTYLE_Default", // Visual style of the composited renderer
                   remoteParticipants: 15, // Maximum number of participants
                   logFileFilter: "warning all@VidyoConnector info@VidyoClient",
                   }).then(function(vidyoConnector) {
                       host: "prod.vidyo.io",
                       token: token,
                       displayName: displayName,
                       resourceId: "DefaultRoom",
                       // Define handlers for connection events.
                       onSuccess: function()            {/* Connected */},
                       onFailure: function(reason)      {/* Failed */},
                       onDisconnected: function(reason) {/* Disconnected */}
                       }).then(function(status) {
                           if (status) {
                               console.log("ConnectCall Success");
                           } else {
                               console.error("ConnectCall Failed");
                       }).catch(function() {
                           console.error("ConnectCall Failed");
                   }).catch(function() {
                   console.error("CreateVidyoConnector Failed");
<script src="https://static.vidyo.io/latest/javascript/VidyoClient/VidyoClient.js?onload=onVidyoClientLoaded"></script>

Note that to keep things concise, we’ve placed our CSS and JavaScript inline inside the HTML file. In a production application, you’d want to have these in separate files.

Our page is nice and simple – it contains a box for the user to enter their name, and then a button to connect to join the video conference.

Looking at the JavaScript, you’ll see that we define a function named onVidyoClientLoaded. This function is called by the Vidyo client SDK when it finishes loading. You can ask the SDK to call any function you’d like; near the end of the file, you’ll see the following script tag:

<script src="https://static.vidyo.io/latest/javascript/VidyoClient/VidyoClient.js?onload=onVidyoClientLoaded"></script>

Note the onload=videoClientLoaded at the end. You can provide the name of any function you’d like the SDK to call here. All we’re doing with this callback is looking for success or failure. For a complete list of the statuses the SDK may pass to the function, see the developer documentation.

Next, you’ll see that we have added a click handler to the Join button. When the button is clicked, we read the display name the user entered, and then use the browser’s Fetch API to call our token endpoint to get a Vidyo token for the user.

Once we have the token, we call another function – called connect – that calls the Vidyo SDK, creates a connector using the user’s token and display name, and then asks it to connect. This will connect the user to the video conference, and display the conference on the screen. For more details about all of the options that can be passed to the Vidyo SDK, please refer to the developer documentation page.

To try out our application, open a terminal and navigate to the vidyo-test directory, and then run the command node app.js.

This will run our application server. Next, open a web browser and navigate to http://localhost:3000. You’ll see a box where you can enter your name. Do this, and then click ‘Join’. You’ll then join the video conference. It will be a quiet conference, because you’ll be the only member. For testing purposes, try loading the site in a different web browser on your computer. Enter a different display name, and join the conference again. You’ll now see two people in the video conference! Be sure to turn down your speakers or microphone before doing this to avoid audio feedback.

And we’re done! You’ve successfully created your first video conference app with Node.js, WebRTC, and Vidyo.


As we’ve discovered, creating your own video conference applications can be quick and easy.

Whether you’re creating your own app to sell to others, or creating internal video conference applications to use inside your organization, Vidyo lets you do it quickly and easily.

Although we’ve only explored using Vidyo’s web SDK, there are also SDK clients available for Windows, MacOS, iOS, Android, Xamarin, and Electron. With all of these options available, you’ll be able to quickly develop video conferencing apps for everyone in your organization – no matter what platform they’re using.

For a detailed overview of everything that’s possible, visit the Vidyo Developer Center. Happy video conferencing!

About the Author

Ryan Peden is a full-stack developer from Toronto, Canada. He has been writing web apps since ES3 was state of the art.