Multiparty Video with the Vonage Video API

The Vonage Video API allows you to create just about any video experience you want. A common use case that developers have is multiple users in a single room, like a meeting with a team. In many cases, these video sessions will need to be recorded. Doing both is easy with the Vonage Video API.

In this tutorial

The Vonage Video API lets you quickly put together a room and put participants inside. We will go over how to get a demo up and running with our existing demos so that you do not have to write any code, but we will also explain what the code is doing in the background.

  1. See the Demo - Check out the demo without writing any code
  2. How the Demo Works - The Client Side - What the Client Side code is doing
  3. How the Demo Works - The Server Side - What the Server Side code is doing

Prerequisites

To complete the tutorial, you need:

See the Demo

If you want to check out the demo before we write any code, we have a sample web server and JavaScript code to try out what a basic video call looks like. All of the code is open source and publicly available, so you can try out the demo and then use the code to make your own modifications.

Launch the Node.js Server

The video demo requires a backend server to handle things like creating client tokens for authorization and general session management. While you can build this in any language you want, we have a pre-built server you can use to get started over at the Vonage Video Learning Server (Node.js) on Code Hub. From the Developer Documentation, click on "Code Hub" in the top navigation bar, and then scroll down and find the card for "Vonage Video Learning Server (Node.js)." Click on it to open it up.

You will get a description of what this project does. For now, let's click on "Get code" so that we can load it into the Code Hub online editor. Click on "Create a new development environment." Name the workspace "Vonage Video Demo" as we can use this backend for multiple demos. This demo does require a number to be assigned to it, as the learning server supports telephone calls via SIP. While we will not use that in this demo, go ahead and click "Assign a number" to assign an existing number you have from Vonage, or purchase a new one to use with later demos.

Creating a new workspace

Code Hub will create an application automatically for you, including setting up the public and private keys that our application will use. Once the workspace is created, you will be dropped into the code editor, which is an online version of Visual Studio Code. Feel free to follow along with later parts of this demo to view the code, and you can edit this code as needed for your own projects.

Code editor

To run the application, click on "View" at the top of the editor, and then "Terminal." This will open a command line in which we can run commands. All we need to do is type vcr deploy and the code will be deployed. This will take a few moments as it packages up the code and executes it on the Vonage Code Hub servers. We will want to make note of the "instance host address" that it outputs near the end.

Deploying the project

If everything is working properly, you should be able to visit the "instance host address" and be greeted with the following page:

Learning Server homepage

Test the Front End

The backend server works directly with all of our pre-built demos, including this one-on-one demo. Head on over to https://github.com/Vonage-Community/video-api-web-samples/tree/main/Archiving, which is the source code for the front-end part of this demo. This sample allows multiple users with the URL to join a voice chat, and to create recordings of the session called Archives.

The easiest way to run this demo is to click on the "Open in Stackblitz" button in the README.

Basic Video Chat README

This will open the project in Stackblitz. As with the backend server, you can browse the code and modify it here if you would like. For this demo, all we will need to do is open the js/config.js file and plug in the Code Hub instance URL in the SAMPLE_SERVER_BASE_URL variable:

Stackblitz Demo Config

Once you save the file, you can refresh the demo view on the right-hand side of Stackblitz and your browser should ask you to allow your microphone and camera. Once you allow it, your image should appear in the bottom corner of the sidebar. If you copy that Stackblitz URL above the demo pane and visit it on your mobile device, another computer, or give it to a friend, anyone joining should be connected to your demo!

How the Demo Works

Configure a Vonage Application

For our video application to work, we need a way for our client and server to talk to the Vonage servers. Code Hub configures this for us, but if you are running the code locally or want to know what that entails a Video app is configured just like another other API. We need to set up a Vonage Application to house all of the configuration for our application, as well as help generate the necessary items for us to do authentication.

Head on over to your Vonage Customer Dashboard and log in. Once you are logged in:

  1. Click on "Applications" under "Build & Manage."
  2. Click on "Create a new application."
  3. Give the application a name, like "Basic Video Demo."
  4. Click on "Generate public and private key", which will have you download a file named private.key. Keep track of this file for later.
  5. Scroll down and toggle on "Video". We will leave these values empty for now.
  6. Click on "Generate new application" to create the application.

Once the application is created, note the Application ID. If you are running the code locally we will need this to configure the backend. If you are using Code Hub, the server code already has access to the Application ID and Private Key.

The Client Side

The client-side portion of the demo consists of two different parts - some HTML elements to put the video feeds in, and then some JavaScript to fetch login information and talk to the Vonage Video servers.

Since this is a browser demo, we use the JavaScript SDK located at https://unpkg.com/@vonage/client-sdk-video@latest/dist/js/opentok.js, and include that in a script tag in our HTML in index.html.

To add people to a room, we only need two elements - somewhere to put the current user, for example, You, which we call "publisher." We then need somewhere to put anyone else that joins, which you will "subscribe" to. We will put them in a "subscriber" element.

We will create two div elements, and give one an ID of publisher and the other an ID of subscriber. We will reference these elements in the JavaScript when the page is visited, and for when we detect another user has entered the video call.

We also created two buttons to handle starting and stopping the archives, as well as a placeholder to fill in with the archive URL once it is finished being rendered.

Handling Video

On the JavaScript side, we will first get some information about the video call itself. To connect to the video call, we need an Application ID, a Session ID, and a token.

  • The Application ID is an identifier that the client SDK uses to reference different settings for our video app on the Vonage side.
  • The Session ID is a specific video session we want to connect to, as a single Application can have multiple concurrent video sessions at once.
  • The Token is a JWT authentication token that allows you to join a specific session with specific rights.

While you can generate the Session ID and Token ahead of time, in the real world you will generate these on demand. Our code represents how you would do that. We will show how the information is created in a bit, but we will grab that information from the backend server we deployed.

Once we have all the connection information, we can go ahead and call the Vonage Video JavaScript SDK, which handles all the work to connect to the Vonage Video API on the front end. First, we grab a session object with OT.initSession(). We then start to listen on the streamCreated event with session.on(). This allows us to set a callback to run when a stream from another publisher is created. In this case, we use session.subscribe() to connect to the incoming event, and push it into the subscriber div we set up in the HTML. We also listen for the sessionDisconnected event to know when the other user disconnects, but all we do for this demo is just log that we noticed they left.

Then we create the publisher object with OT.initPublisher(). We tell it what div to attach to (publisher), and some basic formatting options. This connects your camera and microphone to the Video API.

We then call session.connect() to connect to the session, using the connection JWT token we grabbed from the server. That's all it takes for two people to join a room!

Handling Archives

The actual archive management is handled on the server side of the application, but we need a way to tell the system to start and stop the archives. Let's grab the buttons that we added to the HTML, as well as the <span> to dump a URL into later. While we are at it, we will also hide the "Stop" button, as we do not need to show it until we start an archive.

We will fire off some HTTP requests to our backend server to actually start and stop the archiving. We will attach a function to the click events of our start and stop buttons. The server application will have code for talking to the Vonage Video API to manipulate the archives themselves.

The last thing we need to do is listen for the JavaScript events around archiving. These are an archiveStarted event and an archiveStopped event. This lets the SDK know that these operations are performing, and we can adjust our UI based on what is going on. It is better to handle this with the SDK as opposed to the event listener functions we created above as we know immediately when the Vonage Video API itself has performed the actions.

When the archiving starts, we hide the "Start" button and display the "Stop" button. When the archive stops, we hide the "Stop button" and fill in our <span> with the URL to view the archive. This URL is part of the backend server we deployed previously, and is not the URL where the archive itself is stored. For that, you will need to watch the server-side events.

The Server Side

The server-side portion of any Vonage Video application is used to handle session creation, authentication token generation, and administrative tasks like starting and stopping archives. For this demo, all we are worried about is creating sessions and tokens so users can join the room. While the API itself is a REST API and can be called however you like, we encourage you to use the Vonage Node SDK which handles all the authentication and HTTP calls for you. You can install it in your own application with:

npm install -s @vonage/server-sdk

The demo code already has it pre-installed. If you are running the code locally, you will need to run:

npm install

to download all the dependencies, and then copy .envcopy to a new file named .env. You will need to fill in the requested information in .env like the Application ID, the Private Key location on disk, and your Vonage API Key and Secret.

Session Creation and Joining the Session

The first thing we do is look up if we already have a session for the room we are generating. We keep an in-memory dictionary in roomToSessionIdDictionary, and if the room already has a session we just pull the session from the dictionary. We then use the Vonage Video Node SDK to create a client token by calling vonage.video.generateClientToken(), passing it the session ID and an object with some configuration. At the moment all we do is set the user to a moderator role for this simple demo. We then return the configured Application ID, Session ID, and Token back to the front end.

If the session does not exist, we create a new one with vonage.video.createSession(). This contacts the Vonage API and creates a session that users can connect to. We don't have any specific settings for this session, but here would be where we set up things like archiving rules and how the session should be handled, like routing or peer-to-peer. Then like before we create a token, and send all that information back to the browser.

Handling Archives

As with most management and administrative features of the Vonage Video API, managing Archives is handled through the REST API and our Server SDKs. We take the client-side requests for starting and stopping an archive, map them to a route in our backend server, and call vonage.video.startArchive() to start an archive, and vonage.video.stopArchive() to stop a running archive.

When we start an archive, we will return the archive information that is generated back to the client. This way it knows which archive to stop later. When we stop the archive, we send back its status as well in case the client side needs to update anything.

These calls will ultimately generate the archiveStarted and archiveStopped SDK events that we listen for.

To view the archive, we need to make sure that the archive itself is available. When the user clicks the link in the front end to view the archive, it filters through a route on the backend server that can check that the archive is indeed ready. If the status is available, we redirect to the actual storage URL for the video. We then let the browser natively display the archived video, as most major browsers support the MP4 format.

Conclusion

In this tutorial, you saw what goes into the backend server for a multiparty video session, how to create a web client for users to join a session and see and hear each other, how to record a video session and view it, as well as a peek at how easy it is to use the Vonage Code Hub and Stack Blitz to quickly test out samples.

Further Reading