Build a Livestreaming Application with Twilio Live and Express
Time to read: 12 minutes
Twilio Live is finally here! If you have ever wanted to build your own livestreaming application, now is your chance.
In this tutorial, you will learn how to build a livestreaming application and share your live video feed with your friends, followers, and maybe even the world. For this project, you'll be using Node.js and Express to build the server side of the application, and vanilla JavaScript on the client side.
Let's get started!
Prerequisites
- A free Twilio account. (If you register here, you'll receive $10 in Twilio credit when you upgrade to a paid account!)
- Node.js v14+ and npm installed on your machine.
- ngrok
What you will build
In this tutorial, you will be creating an application that allows a person to livestream video and audio from their device to people who have the link to the stream. The Express server you'll build will handle both the streamer and audience experiences. The client side will have one experience for the streamer and one experience for the audience members.
For the streamer experience, you will:
- Create a Twilio Video Room, where the streamer will share their video and audio.
- There are three different types of Video Rooms, but for this project, you'll be using a WebRTC Go room, which is limited to two participants. Since this application will just be for one user to stream their own video, a WebRTC Go room is the perfect size. When you finish this tutorial, if you decide you want to include more streaming participants in one room, you can upgrade to a Group room very easily!
- Create the livestream itself — the captured audio and video, formatted into a livestream by a Video Composer running on a MediaProcessor.
- Create a PlayerStreamer, which sends the livestreamed content to a web or mobile application running a version of the Player SDK.
- Build a UI where the streamer can start and end the livestream.
For the audience experience, you will:
- Build a UI where the audience can watch a livestream.
- Use the Player SDK to receive and display the livestreamed media in the browser.
Create the project directory and install dependencies
From your terminal or command prompt, navigate to where you would like to set up your project. Create a new directory called express-live-stream and change into that directory by running the following commands in your terminal:
Next, set up a new Node.js project with a default package.json file by running the following command:
Once you have your package.json file, you're ready to install the needed dependencies:
- Express, a Node.js framework
- Twilio Node Helper Library, to use the Twilio APIs
- dotenv, to load the environment variables from a .env file into your application
- nodemon, to automatically reload the server when you make code changes
- @twilio/live-player-sdk, the Twilio Live Player SDK for JavaScript
Run the following command in your terminal to install the packages listed above:
Open the package.json file in your code editor. You will see that the packages listed above have been installed as dependencies
.
Now that you have a package.json file set up, it's time to add your environment variables to the project.
Save your Twilio credentials safely as environment variables
Create a new file named .env at the root of your project and open it in your code editor. The .env file is where you will keep your Twilio account credentials. Add the following variables to your new file:
You’ll need to replace the placeholder text above with your actual Twilio credentials, which can be found in the Twilio Console. Log in to the Twilio Console and find your Account SID:
Copy and paste the value for Account SID to replace the placeholder text for TWILIO_ACCOUNT_SID
.
Then, navigate to the API Keys section of the console and generate a new API Key. Copy the API Key's values for SID and Secret to replace the placeholder text for TWILIO_API_KEY_SID
and TWILIO_API_KEY_SECRET
.
It’s important to keep these private credentials secure and out of version control. If you’re using GitHub, create a .gitignore file at the root of your project. In this file, you can list the files and directories that you want Git to not track or commit. Open .gitignore in your code editor and add the .env file and the node_modules directory:
Now that you have your Twilio credentials set up, it's time to create your Express server.
Create a new Express server
Create a new file called server.js at the root of your project. This is the place where you will write your server-side code.
Open server.js in your code editor and add the following lines of code to import the necessary packages and create your Express application, which will run on port 5000:
Now, open package.json in your code editor. Here, you will see that the main
file is set to index.js
. Remove this line and the scripts
section below it. Then add the following lines in their place:
The code above changes the main
file to server.js
to match the server file you just created. Then, just below that, "type": "module"
allows you to use ES6 modules in your project. The start
script on the lines after that is the command to use nodemon to run your Node.js server. Your updated package.json file should look like the one below:
To run the start
script, return to your terminal window and run the following command:
Once you have done this, you should see the following log statement in your terminal window, letting you know that the Express server is running:
You can leave this server running while you work through the tutorial. Nodemon will watch for changes in the server.js file and reload the server to keep it up to date with your latest additions.
Now that your server is running, it's time to lay out the client side of your application.
Build the application layout and serve static files
Create a new directory called public at the root of your project. This directory will hold your static files:
Inside the public directory, create 5 new files:
- index.html, a simple entry point for your application
- streamer.html, containing the UI for the streamer
- streamer.js, containing the logic for starting and ending a livestream
- audience.html, containing the UI for the audience member
- audience.js, containing the logic for watching a livestream
Now that you have the public files, you need to set up your server to serve these files when a user navigates to http://localhost:5000/ in their browser.
Return to server.js in your code editor. Add the following code to the file, just below your variable for port
:
This code will allow you to display the HTML files in your browser when users navigate to the endpoints you have set up above.
Let's work on the HTML files first to get the layout of the application set up. Open public/index.html in your code editor and add the following code to the file:
The HTML code above creates a simple layout with two links — one for the streamer and one for the audience members. This layout also includes a CDN link to TailwindCSS, which will allow you to quickly add CSS styles.
If you navigate to http://localhost:5000/ in your browser, you will see the links as shown below:
Next, open public/streamer.html in your editor and add the following code to the file:
In this HTML file for the streamer, you will see that there is a div reserved for the video stream, as well as a controls section with inputs for the streamer's name and the livestream's name, as well as a button that lets the user start the stream. Navigating to http://localhost:5000/stream in your browser window will show you what the layout looks like so far:
Now open public/audience.html and add the following code to the file:
In this HTML file for the audience members, you will see that there is a div for the livestream to appear, as well as a button that allows viewers to start watching the stream. If you navigate to http://localhost:5000/watch in your browser, you will see the following layout:
Now that the layout is set up, the next step is to build out the streamer experience.
Build the streamer experience
Allow the streamer to preview their video feed
Open public/streamer.js. This is where you will add the logic that allows the person livestreaming to preview their own video feed and control the livestream.
To start, add the following code to the file:
The first section of this code sets up the variables you will need for this part of the project. There is a list of HTML elements that you will refer to later in the code, as well as variables for whether a user is streaming, for the room being streamed, and for the details of that stream. After that, you create a liveNotification
, which is a div that will appear for the user to let them know their video is being shared live.
Below that, the function addLocalVideo()
creates a video track and attaches it to the DOM. This allows the streamer to preview their video feed before they start the stream. If you navigate to http://localhost:5000/stream in your browser, you will be able to preview your video feed.
Add logic to control the livestream
It's time to add the functions that will allow the streamer to control the livestream. In this section, you will be adding three functions — one to start the livestream, one to end the livestream, and one to toggle which of these actions is selected.
Add the following startStream()
function to public/streamer.js, just below the addLocalVideo()
function:
This function takes the stream name that the user enters and calls a /start
endpoint on the server side to create a new Video Room and a livestream. Once the stream is created, the function then calls the /streamerToken
endpoint to retrieve an Access Token, then uses that token to join the Video Room and begin streaming. Once the stream has started, a red LIVE message is added to the top left corner of the video feed, and the start stream button changes to say end stream instead. If the streamer clicks this button, they can end the livestream.
Next, add the following endStream()
function just below startStream()
:
If there is an ongoing livestream, this function will call the server-side /end
endpoint to stop the stream and close the video room. The LIVE message disappears, and the button returns to saying start stream again.
Now, add the following startOrEndStream()
function and event listeners to the file, just below endStream()
:
The startOrEndStream()
function will be called when the startEndButton
is clicked. If there is no livestream ongoing, this function will call startStream()
. Otherwise, if a stream is in progress, the function will call endStream()
to stop it. There is also an event listener for when a user closes the browser tab or window — this way, the video room and livestream can be cleaned up even if the user does not click the stop stream button before navigating away.
Now that you have the client-side logic to handle controlling the livestream, it's time to add the server-side endpoints being called in the JavaScript code above.
Create endpoints for controlling the livestream and getting access tokens
In server.js, you will need to add the /start
, /end
, and /streamerToken
endpoints referred to in the previous step.
First, just below const port = 5000;
, add variables for your Twilio credentials and the access tokens you'll need for this project:
Then, add the following /start
endpoint to the file, just below the /watch
endpoint:
This endpoint uses the Twilio Node Helper Library to create a WebRTC Go Video Room using the stream name chosen by the user. Then it creates the PlayerStreamer and MediaProcessor. The PlayerStreamer is what will allow the livestreamed content to be sent to the audience. The MediaProcessor uses the Video Composer extension to compose the video feeds into a grid layout and send the content to the PlayerStreamer. (In this project, since there is only one streamer, the audience will only see one video feed.) Once the MediaProcessor is created, the Video Composer extension will join the video room as a second participant and begin to stream out the video and audio tracks.
Now that you can start the livestream, add the following /end
endpoint under the /start
endpoint to stop it:
This endpoint takes the streamDetails
from the request and sets the PlayerStreamer and MediaProcessor's statuses to ended
. After this is complete, the endpoint also updates the video room's status to completed
.
Next, add the following /streamerToken
endpoint to the file, just below /end
:
This endpoint creates a new access token for the streamer and adds a VideoGrant, which will allow this person to join the video room and begin streaming. Now that you have all the endpoints you need for the streamer, it's time to build out the experience for the audience members.
Build the audience experience
Add the Twilio Player SDK
To play a livestream, your application will need the following three static files from the Twilio JavaScript Player SDK:
- twilio-live-player.min.js
- twilio-live-player-wasmworker-1-5-0.min.js
- twilio-live-player-wasmworker-1-5-0.min.wasm
You can find these files in node_modules/@twilio/live-player-sdk/dist/build from when you ran npm install
earlier in the tutorial.
Inside the public directory, create a new directory called livePlayer. This is where you will store the Player SDK files:
From your terminal window, run the following command at the root of the project to copy the three Player SDK files into the livePlayer directory:
Now you are ready to add the logic to show the player in the UI.
Allow the audience member to start watching the stream
For the audience member's experience, you will be adding logic to public/audience.js. Open this file in your code editor and start by adding the following variables to the top of the file:
Now you are able to refer to the player element, the button that will control it, and whether the audience member is currently watching a livestream.
Next, add the following watchStream()
function to the file, just below the variables:
Similar to the person streaming their content, an audience member who wants to view a livestream also needs an access token. The watchStream()
function calls the /audienceToken
endpoint you will create in a later step to get the token for the user. After that, the function uses the token to connect to the Player SDK and begin playing the livestreamed content in the browser window. Once the user is watching the livestream, the watch stream button changes to say leave stream.
Now, add the following leaveStream()
function, just below where you added watchStream()
:
This function disconnects the player and changes the button's text and color back to its original state.
Finally, similar to on the streamer side of the application, add the following watchOrLeaveStream()
function and event listener:
On a button click, if the audience member is already watching the livestream, this function will call leaveStream()
. If they are not watching, then watchStream()
will be called.
You may be wondering why we don't just let the livestream start playing when the audience member navigates to the audience experience page at the /watch
endpoint. Well, there is a browser policy that makes autoplay videos start muted — to start playing the audio, an explicit user interaction is required. In this application, clicking the watch stream button is the explicit user interaction that will start playing the livestream's audio along with its video.
Now that you have the logic to let the audience member watch or leave the stream, you just need to fill in the /audienceToken
endpoint on the server side to allow these users to get the access tokens they need.
Create endpoints for controlling the livestream and getting access tokens
Return to server.js and add the following /audienceToken
endpoint just below the /streamerToken
endpoint:
This endpoint generates a random string for the audience member's identity. Then, it queries for a list of PlayerStreamers with a status of started
. In this application, you can assume that there is only one PlayerStreamer, so the endpoint takes the first one from the list. If the list comes back empty, the endpoint returns a message to the client side to let them know that no one is streaming right now.
Once you have the PlayerStreamer, you can create a PlaybackGrant which will allow the audience member to start viewing the livestream. This grant is attached to the access token, and the token is returned to the client side.
You have all the code you need to begin streaming! There is just one more step before you can test it all out.
Run your application on ngrok
In this project, you'll be using ngrok to connect the Express application running locally on your machine to a temporary public URL. To start a new ngrok tunnel, open up a new terminal window and run the following command:
Once ngrok is running, you will see text similar to the below in your terminal window:
Copy the https:// URL next to Forwarding
. Any requests that are made to this ngrok URL will be forwarded to your local server. You now have a temporary link to your application that you can share with a friend or colleague!
Try livestreaming!
Now that everything is set up, it's time to try out a livestream. You will be trying out both the streamer and audience member experiences.
Open the ngrok forwarding URL in your browser window. Click the link to start a livestream. Enter your name and your livestream's name in the input boxes, then click the start stream button.
For my livestream, I've decided to share a cute stream of my dog, Nova! 🐶
Once you've started the stream, the LIVE marker will appear and the button will change to say end stream. Congratulations, you're livestreaming!
Now it's time to check out the audience experience. In a second browser tab, navigate to the ngrok forwarding URL again. This time, click watch a livestream. You will see a layout like the following appear:
Click the watch stream button to connect to the stream and begin watching. The live video feed will replace the gray box in the UI:
If you want, you can send the /watch
link to a friend so they can see your livestream too!
What's next for building a livestreaming application?
Now that you have had a taste of livestreaming by learning to stream your video feed, perhaps you'd like to try another Live tutorial and learn how to livestream your screen. Or, if you're curious about livestreaming in general, check out this blog post about livestreaming's use cases and benefits. Maybe you already have your own project idea in mind, in which case you can check out the Twilio Live documentation to learn even more.
I can't wait to see what you build!
Mia Adjei is a Software Developer on the Developer Voices team. They love to help developers build out new project ideas and discover aha moments. Mia can be reached at madjei [at] twilio.com.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.