NodeJS Live Streaming App
How to build your live streaming web app with Uiza’s API using React and NodeJS
Last updated
How to build your live streaming web app with Uiza’s API using React and NodeJS
Last updated
Uiza provides intuitive APIs, which simplifies the integration of live streaming functionality into your platform. This guide is a step-by-step tutorial on how to build your live streaming app with Uiza’s APIs. The web app will have two components: the broadcaster web app, to start a stream, and the viewer app, to list all broadcasts and playback the broadcast.
Sample code is provided below on how to build a simple web app to call on Uiza’s API. The language used for web app is Javascript.
To understand the flow of the this tutorial, following terminologies are explained by the graph below.
During this documentation, broadcast, live streaming and streaming will be usede interchangeably.
To have a live streaming app, we have to distinguish between a broadcaster and a viewer. A broadcaster streams the live stream and a viewer watches the live stream - this is a one way interaction channel, hence we have to build 2 separate pages: a broadcasting page and a viewer page. The broadcaster needs to start a broadcast through a stream URL and key, while the viewer sees the active live streams and can watch them through the web app.
To build a broadcast web app, we start with creating a new react web application. Let us create a brand new application. Open terminal / command prompt and execute the below lines to create a starter app:
Create a new project
Get into the project directory
Start the development server.
To start a broadcast with Uiza we will need to do two things:
1. Create a live entity in Uiza servers.
2. Get the ingest.url and ingest.key for this entity.
To increase the readability of this tutorial, we use the Axios library to send requests to the Uiza server. Install Axios with the following command:
To play the video stream we will need a player control. Install react-player with the following command:
Open the App.js
file in the src
directory.
Import react, router, react video player and css file.
We need an API key to access Uiza's services. The URL to access the services will be the same, so we're saving it as a constant. The default headers will be common for every API call.
To get your API key, create an account at Uiza here: Sign Up Link. Once you are in the developer console, you will see your API key.
The code snippet shows the constants:
Then we import Axios to send GET
and POST
requests:
We divide the app into two parts:
Broadcast Page: Will contain the functionality to create a new broadcast.
View Page: This will display all broadcasts currently in the system, with online broadcasts as a green tile and offline broadcasts as an orange-red.
Let us start with the broadcast page design.
We use application-wide states that can be displayed in the application, and manipulated at run-time. As you can see, we can set default values with states. Our default region value is in-bangalore-1
We define this function as start_broadcast
. We clear the states and set the message state to fetching
. Then we start loading the information.
Now we set the parameters, so that we can make the create entity
call. The below structure contains all the information of the HTTP request that we pass to Axios. As you can see, we make use of the region_value
state to set the region to a supported value.
Now let's create the polling call structure so that we don't end up creating the same structure from the loop. As you can see it will be a GET
request. Authorization header will expect your API key.
We make a POST
request to create an entity.
The call returns the entity id
in the respone.
The GET
method takes the entity id
and returns the broadcast information (including the stream URL and key).
To get the stream URL and key, the entity has to be in a ready
state. We use setInterval
to poll the API every 3 seconds to check the status of the entity using response.data.status
.
The initial status of an entity is init
. When the server is ready with a stream URL and key, the status becomes ready
.
If the status is notready
yet, we continue polling and the current state of message
will be set to Polling
.
Once the status is ready
we can extract url
and key
from the response.
self.setState({ message: 'Polling' + '.'.repeat(1 + counter%3) });
The above code creates a nice text animation so that we know the program is not stuck and is working.
We build a very simple user interface. The front page will have a drop-down menu to select the region_value
. This drop-down contains the following regions (you can find the available regions here: Regions):
in-bangalore-1
in-mumbai-1
We create a Start broadcast
button to call the start_broadcast
function. The three lines below are important. They leverage the state value to display current states.
The first line displays the messages from the program's status: Fetching
, Polling
etc.
The second line contains the stream URL (i.e. stream_url
)
The third line contains the key for the stream key (i.e stream_key
)
The view page contains tiles that correspond to available streams. Green tiles are online entities and red tiles are offline entities.
The following load_alive_streams
function loads the streams. Available streams are loaded and saved to state
so that they update automatically.
We create a dynamic list of VideoTiles, and populate it on every render(). We use a 5-second interval between each render, to not overdo it. Then we access the details from the properties of the Video at the time of creation. We use the properties to pass values to the inner components of the tile and make it look functional.
For example: {this.props._url}
accesses the _url
parameter from <VideoTile>
The same approach is used for the key and the playback URL.
The tile has to be clickable and take the viewer to the live stream. For that, we make use of routing in our application and send the user to a page with video playback url. The playback page is dynamically generated and plays the video.
The above line sends the user to an href
link which is understood by the router later. The regex removes the protocol from the URL (i.e http / https)
Following code shows the VideoTile component:
As mentioned above, requests are only made every 5-seconds. We attach the parameters to the VideoTile element. After putting it all together:
Now we have the video tiles ready but what do we show when this tile is clicked? This clever little view code launches the player on screen. We launched the player on the screen when the tile is clicked with the following code:
We make use of the Router
component in react to create pagination in our app. We will have the link to broadcast and view page
To enable pagination in the app, we need to make use of react's routing. Following code does the routing:
The streams are loaded when we click on the viewer with the below line. Following line loads the streams on click: <Link to="/viewer" onClick={ViewerPage.load_alive_streams}>Viewer Page</Link>
The routing path below with *
wildcard enables video stream url to be parsed with /
and to be sent to the video page. Otherwise, the videoid is split at the first occurence of /
That's all wasn't that fun? If you have any questions please check out our Github repo where this entire project has been uploaded with source code here and if you have any other questions please contact us here: anhnh@uiza.io