Broadcast Video Chat with Javascript and Vonage

Published May 14, 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 broadcast your video chat to many viewers online.

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, you should be able to broadcast your video chat live to a large audience using HTTP live streaming (HLS) or an RTMP stream.

Screenshot of broadcast 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

Broadcasts with the Vonage Video API

The platform supports two types of broadcasts, Live interactive video broadcasts and live streaming broadcasts. Both types of broadcast require you to use a routed session (a session that uses the Vonage Video API Media Router). More in-depth coverage of this subject gets covered in the next section.

Live interactive video broadcasts enable many clients to publish and subscribe to each others’ audio-video streams in real-time. Routed sessions can support live interactive video broadcasts for up to 3,000 streams between clients.

Live streaming broadcasts let you share an HTTP live streaming (HLS) stream or an RTMP stream with large numbers of viewers. The HLS or RTMP stream is a single video composed of the individual streams published to the session. For this tutorial, this is the type of broadcast we will be using.

HTTP Live Streaming (HLS) is a media streaming protocol which aims to deliver continuous and long-form video over the Internet reliably. It was developed by Apple and released in 2009.

HLS uses CDN for delivery and is a traditional broadcast with high latency (15–20 seconds) and no interaction. An HLS viewer will receive the content at a latency of 15–20 seconds, so it does not lend itself directly to interactive use-cases.

Real-Time Messaging Protocol (RTMP) is a TCP-based protocol designed for the transmission of audio, video and data. Originally developed as a proprietary protocol by Macromedia, it is now an open specification released by Adobe.

Although RTMP has lower latency (around 5 seconds) than HLS, it also does not lend itself to use-cases that require interactivity. You would use RTMP to push content created with the Vonage Video API to social media video platforms, such as Facebook or YouTube Live.

Initial Setup

As we are building onto a basic video chat, start 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 be working on the client-side code to get the text chat working before revisiting the server.js file again.

Add the Required Markup

Our application will be made up of three pages. a landing page for users to create or join a session, a video chat page for participants of the video chat, and a page that displays the broadcast stream.

We will need to create an additional page for the broadcast. Let’s add a broadcast.html file to the views folder by clicking the New File button in the left sidebar. Name the file views/broadcast.html and paste the following markup into the page.

Add a broadcast.html to the views folder

There isn’t a lot going on here, the key portion is the video element which will house the HLS stream when the broadcast starts.

We will also add some broadcast-related markup to the index.html page, like the buttons to start and stop the broadcast, as well as to generate a shareable HLS link.

Style the broadcast controls

Next, let’s put in some styles for the newly added markup. Nothing too fancy here, just some positioning and also button states, which we will talk about when we start working on starting/stopping the broadcast.

Now, when you start the session, your interface should look something like this:

Styling the broadcast controls to the bottom-right corner of the screen

This is not the final styling, but it will do for now as we build out the broadcast functionality of the application.

Starting/Stopping a Broadcast

The key to broadcasting with the Vonage Video API is the startBroadcast() method and the stopBroadcast() method. These methods will be called from the server.js file. The startBroadcast() method takes in three parameters: the session ID for the session, options for the broadcast, and a callback function. We will get the session ID from the client-side via a POST request. Let’s set up the route for that.

There are more optional properties you could include as broadcast options like resolution, layout and so on, but for now, we will be using the defaults. Refer to the API reference for specifics.

Let’s also set up the route to stop a broadcast. The stopBroadcast() method requires the broadcast ID, which we will also obtain from the client-side.

There are some tweaks to be made to the client.js file to cater for this new functionality. In the client.js file, make session a global variable.

We must also change the media mode of the session to a routed one, instead of the default relayed mode.


We also need to declare a broadcast variable to hold information about the broadcast that will be used to stop the broadcast as well. For now, let’s also log the responses to the console so we can verify things are working as expected.

If you open your console when starting and stopping the broadcast, you should see the following:

Console log messages when broadcast starts and stops

In theory, we could stop here, because we now have access to an HLS link to stream the video chat to a player that supports the format. And if you already have something that handles HLS streams, feel free to do things your way. The rest of this tutorial covers a basic implementation so you can have a look at what the broadcast stream looks like.

Handle button states

But first, some additional styling for button states. If you noticed, there is some time lag between you pressing the Start Broadcast button and the response which gets logged to console. To improve the user experience, we want to provide some indication to the user that their request did get sent to the server.

The flow would work something like this:

Button state flow

Instead of displaying both start and stop buttons, we only show one relevant button at a time. Also, once a button is clicked, we don’t want users to click it multiple times while processing is on-going. Let’s add some CSS classes to deal with the hidden and disabled states.

Given that start and stop have the same flow, the required CSS classes for state changes would be the same for both buttons, just applied in an alternating fashion. We can abstract those changes into a function that takes in the string “start” or “stop” and targets the appropriate button.

Let’s incorporate these functions into our fetch requests for starting and stopping the broadcast.

Create Shareable HLS Link

The Broadcast object returned from the SDK contains a HLS broadcast URL that can be consumed by any video players which support HLS. Let’s make use of this to create a link to a Broadcast page. We already created a broadcast.html file at the start, so let’s pipe our broadcast into that page. Let’s set up a route in the server.js file for it.

We’re going to add another route that checks for the existence of the session to be broadcast. If it does, the success response will pass over the URL for the broadcast and its status.

On our index.html page, add in the following to the broadcast controls div:

And some additional CSS to styles.css:

The result of these changes will be a link that opens the Broadcast page in a separate tab or window. A button is displayed which, when clicked, copies the link to the Broadcast page for people to share it around. We’ll need to grab the HLS URL from the broadcast response, as well as the room name (from the URL) to compose the link for the broadcast page.

Let’s add these new functions to the fetch requests for starting/stopping the broadcast as well:

There are numerous video players that can handle HLS streams and offer different levels of customization over the player interface, but to keep things basic, this tutorial loads up hls.js to play the stream. Create a broadcast.js file in the public folder.

The final bit of this tutorial is a native implementation of copy to clipboard. Feel free to use a library like clipboard.js for a simpler API.

After all that, you should finally get something like this for the video chat page and the broadcast page respectively:

Video chat page

Broadcast page

What’s Next?

The final code on Glitch and GitHub contains everything we covered in this lengthy post but re-organized, so the code is cleaner and more maintainable. Feel free to remix or clone the code and play around with it yourself.

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