Stream a Video Chat With Vonage Video API

Published April 28, 2020 by Hui Jing Chen

This series of tutorials will explore the Vonage Video API (formerly TokBox OpenTok) and what you can build with it. The Video API is very robust and highly customizable, and in each post we’ll show how to implement a specific feature using the API. This time we will look at how to stream your video chat to an audience who is not in the chat.

As this application will require some server-side code, we will use Glitch for ease of setup. You can also download the code from this Glitch project and deploy it on your server or hosting platform of choice (may probably require some configuration tweaking based on the requirements of your platform).

We will not be using any front-end frameworks for this series, just vanilla Javascript to keep the focus on the Video API itself. At the end of this tutorial, your video chat application should also provide an option to simply watch the video chat stream.

Screenshot of viewer page

The final code for this application can be found in this GitHub repository or remixed on Glitch.


Before we get started, you will need a Vonage Video API account, which you can create for free here. You will also need Node.js installed (if you are not using Glitch).

This tutorial builds on the first introductory post in the series: Building a Basic Video Chat. If this is your first time using the Video API, we highly suggest you go through that because it covers the following basic setup:

  • Create a Vonage Video API project
  • Setting up on Glitch
  • Basic project structure
  • Initializing a session
  • Connecting to the session, subscribing and publishing
  • Basic layout styles for a video chat

Token Creation and Roles

Every user that connects to a session needs to be authenticated with a token. Each token is assigned a role, which determines what the client can do when they are connected. There are three available roles, Subscriber, Publisher and Moderator. We will only be using the first two for this tutorial.

A publisher can connect to sessions, publish audio-video streams to the session and subscribe to other clients’ sessions. A subscriber can connect to sessions and subscribe to other clients’ sessions but cannot publish to the session.

Crude illustration of subscribers and publishers

For this tutorial, we will provide participants with publisher tokens, while viewers get subscriber tokens.

More information about tokens can be found in the documentation.

Initial Setup

As we are building onto a basic video chat, start off by remixing the project for the basic video chat built in the previous tutorial. Click the big Remix button below to do that. 👇

remix this

Your folder structure should resemble something like this:

Folder structure of the project

As mentioned at the start, TokBox OpenTok is now Vonage Video API. We haven’t made any changes to our package names, so you will still reference OpenTok in your code.

If you had remixed the Glitch project, your server.js file should already look like this:

To get the video chat up and running, go to the .env file and fill in your API key and secret for your project, which you can find from the dashboard. Once that’s done, we will make some additions to the project to provide an interface for viewers.

Add the Required Markup

Our application will be made up of three pages: a landing page for users to create or join a session as well as to select if they want to be a viewer or a participant, and the two video chat pages for each role respectively.

We will need to create an additional page for the viewer. Let’s add a viewer.html file to the views folder by clicking the New File button in the left sidebar. Name the file views/viewer.html and paste the following markup into the page. This page is almost exactly the same as the index.html file, except it does not have a div for publisher.

Add a viewer.html to the views folder

The viewer.html and the index.html file will be using different script files as their implementation is slightly different due to their respective token roles as explained in the section above.

Next, we will make some modifications to the form on the landing.html page to include an option for users to select their roles via radio buttons. If they select Viewer, they will be sent to the page which shows them a stream of the video chat. If they select Participant, another text input will show up for the user name, which will be used to identify their stream.

Style the Landing Page Form

Let’s add to the existing styles to cater for the new fieldset and radio buttons.

Basic styles for fieldset and radio buttons

Refactor the Client-Side Javascript

Let’s work on the landing.html page first. For the conditional show/hide of the user name field, we can add an event listener that checks for the value of the radio button being selected and toggle the styles accordingly.

We also need to modify the logic for sending our users to the correct pages based on whether they chose viewer or participant. Viewers will be sent to /session/viewer/ROOM_NAME while participants will be sent to /session/participant/ROOM_NAME?username=USER_NAME. We are making use of the query string in the URL to pass the user name to the server.

Next, we’ll create the viewer.js file for the viewer.html page. Similar to what we did for the viewer.html, click on New File again, but this time, add the Javascript files to the public folder instead.

Your project folder should now look like this:

Project structure after all files are added

The viewer.js file is slightly shorter than the client.js file because it does not include the creation of a publisher. We are making a POST request to /session/viewer/ROOM_NAME and receiving the necessary response data to connect to a session.

We need to make some minor tweaks to the client.js file as well because we want to label the stream for each participant with the user name they entered on the landing page.

The initializeSession() function will now take one more parameter for streamName and used in the initPublisher() method and the subscribe() method. Both methods accept an optional properties argument, which allows us to pass in customisation options for the streams.

Your final client.js files will look like this:

Handle Routes on the Server-Side

The last portion before everything comes together is the server.js file, where the routes are defined. We will need to handle the routes to serve the Viewer page (viewer.html) as well as the Participant page (index.html) respectively.

Instead of the remixed generateToken() function, we will use two different functions for the two roles.

For viewers, once the Viewer page loads, the room name will be sent to the server via a POST request. This will be handled by the following route:

Similarly, for participants, once the Participant page loads, the room name and user name will be sent to the server via a POST request, and its corresponding route is handled as follows:

And with that viewers will be able to see the participant’s streams on a single page, while participants will be having a video chat with each other.

Screenshot of viewer page

Screenshot of participant page

Do check out the final code on Glitch or GitHub and feel free to remix or clone the code and play around with it yourself.

What’s Next?

There are additional functionalities we can build with the Vonage Video API which will be covered in future tutorials, but in the meantime, you can find out more at our comprehensive documentation site. If you run into any issues or have questions, reach out to us on our Community Slack. Thanks for reading!

Leave a Reply

Your email address will not be published.

Get the latest posts from Nexmo’s next-generation communications blog delivered to your inbox.

By signing up to our communications blog, you accept our privacy policy , which sets out how we use your data and the rights you have in respect of your data. You can opt out of receiving our updates by clicking the unsubscribe link in the email or by emailing us at