Build

WebRTC Live Video Stream Broadcasting from One-to-Many

7 min read Michael Carroll on Aug 27, 2015

Good News

We recommend checking out our updated WebRTC video chat tutorial.

Read tutorial here →


In this tutorial, we’re going to build a WebRTC live stream broadcasting application for one-to-many video communication. In other words, we’ll build Periscope or Meerkat using WebRTC, enabling one-way video streaming from a single broadcaster to any number of viewers, all in the browser!

We’ll cover how to use the PubNub WebRTC SDK with a wrapper class to easily create live embeddable streaming content, and implement PubNub Presence to get a real-time count of stream viewers.

Check out the live broadcast video streaming demo here, open up a couple windows, and watch it in action!

And if you want to check out the project code for the tutorial series, it’s available here.

If you haven’t yet checked out the previous posts, we built a WebRTC video chat app with a number of different features:

That’s right! Let’s get to it.

A Note on Testing and Debugging

If you try to open file://<your-webrtc-project> in your browser, you will likely run into Cross-Origin Resource Sharing (CORS) errors since the browser will block your requests to use video and microphone features. To test your code you have a few options. You can upload your files to a web server, like Github Pages if you prefer. However, to keep development local, I recommend you setup a simple server using Python.

To do this, open your terminal and change directories into your current project and depending on your version of Python, run one of the following modules.

For example, I run Python2.7 and the command I use is python -m SimpleHTTPServer 8001. Now I can go to http://localhost:8001/index.html to debug my app! Try making an index.html with anything in it and serve it on localhost before you continue.

Step 1: The HTML5 Backbone

I am going to try to keep the HTML simple for the sake of the demo. Create a file called stream.html, and in it put the following code.

This will give you some inputs and options, as well as a video holder where you can place your local stream, to see what you are streaming to the world.

I added a icon of a person to indicate the number of people watching your stream.

stream_html

You will notice there are a few functions that we will need to create in the JavaScript:

stream(form): Begin streaming video on channel in form.
watch(form): Join the steam channel provided by the form.
end(): Stop streaming.
genEmbed(width,height): Generate an embeddable code for the stream.

Step 2: The JavaScript Imports

There are three libraries that you will need to include to make WebRTC operations much easier:

  1. Include jQuery to make modifying DOM elements a breeze.
  2. Include the PubNub JavaScript SDK to facilitate the WebRTC signaling.
  3. Include the PubNub WebRTC SDK, and SDK Wrapper libraries which makes placing phone calls as simple as calling the dial(number) function.

Now we are ready to write our broadcasting functions for stream and watch!

Step 3: Broadcasting Your Stream

In order to start broadcasting your streams, you will need a publish and subscribe key. To get your pub/sub keys, you’ll first need to sign up for a PubNub account. Once you sign up, you can find your unique PubNub keys in the PubNub Developer Dashboard. The free Sandbox tier should give you all the bandwidth you need to build and test your WebRTC Application.

3.1 Prepare to Broadcast

First, let’s locate our video holder for our local stream, embed code holder, and here-now holder for presence updates. Also, let’s create a global variable that will hold our current stream name.

3.2 Broadcast & Configurations

Now, time to implement our stream function that will setup the WebRTC connection for broadcasting.

You are now streaming your video on channel streamName. If you remember instantiating the phone object in the past, you will notice that we added some new configurations, oneway and broadcast. The oneway configuration simply sets the WebRTC SDK up for the possibility one-way streaming.

Then, broadcast is set to true to indicate that your phone will be the one broadcasting, not receiving the stream. Indicating oneway will allow a user to watch your stream without ever having to grant mic and video permissions.

The ctrl.ready function takes a callback to execute when it is ready to stream. First, we simply change the input to green to indicate success, and hide the submit button. Then, we use ctrl.addLocalStream(video_out) to place our local stream in the video_out div. Finally, a call to ctrl.stream subscribes us to a stream channel to begin broadcasting.

The last thing we do in our stream function is make a ctrl.streamPresence(function(m){...}) handler. This subscribes you to presence events on your stream, then hands all presence events to the callback function. I simply pull off the current occupancy and display it in our here_now div.

To spark your creativity, see the documentation on Presence.

stream_broadcast

Step 4: Join a Stream

Now that we have a user streaming (our broadcaster), we need to enable other users to join and view that stream. The watch function takes the value from the HTML input and joins that stream.

The initial setup looks very similar, but you will notice we only specify oneway this time. This user is only receiving the stream, not broadcasting as well.

When the controller is ready to connect, it uses ctrl.isStreaming(number, function(isStrm){}) to make sure that the user they want to watch is currently streaming. This function takes a number and a callback. It checks if the number is streaming and passes a boolean value isStrm to the callback function. If the user is streaming, we use ctrl.joinStream to join the stream. No need to grant access to mic and video because we are only watching the stream.

Then, we use ctrl.streamPresence again to update the amount of users currently watching the stream via Presence.

And just like that, we’ve built a real-time live broadcast video app with WebRTC. The coolest part is yet to come though. Next we will set up an embeddable live streaming video.

Step 5: Embeddable Live Streams

Lastly, we want to make the live stream embeddable in any browser. Creating an embeddable live stream is as simple as making an iframe whose contents automatically joins your live stream.

5.1 Generate the Embed Code

Before we get to coding the HTML file that will load your video in the iframe, let’s write the function that will create the embeddable code.

You can see that our code will open an iframe that displays the contents of a file on your website called embed.html, and passes the parameter stream=streamName. For debugging, you can use http://localhost:[your-port]/embed.html.

5.2 Create the Embed HTML & CSS

In the same directory as your stream.html, create a file called embed.html. The HTML portion of your embed file is extremely basic:

Just a box to place the stream in and a presence counter. I will leave most of the styling to your personal preference, but in order to make sure the video takes up as much of the iframe as it can, I recommend some of the following stylings:

This will ensure that vid-box and the video element that will be placed inside of it take up as much of the screen as possible.

5.3 The Embeddable Content’s JavaScript

This embeddable HTML will need to include some of the JavaScript imports as well, that way you can embed it on any page. Below your HTML, put the following JavaScript imports:

All that is left to do now is create a final script tag that gets the stream name from the URL parameters, and then does the exact same thing as our watch function from part three.

First, set some global variables and make sure that there is a parameter stream in the URL query string.

Notice that we wrap the entire function in an anonymous function call (function(){ ... }()). This is to preserve the scope of these variables, so they won’t interfere with the JavaScript on their embedded page. (It is called anonymous because it has no name and it calls itself!)

The function urlparams can be copied exactly. It simply chops everything off the URL after ? and then creates a map of type string->string for the query string key-value pairs. We create this map in urlargs and then check if it contains a key stream. If it doesn’t, handleNoStream is called.

This function is also called if there was no user streaming to the channel you tried joining, or when the streaming user ends broadcast. It is essentially an error handler, and this implementation hides the presence counter and displays some text.

Now, in the same anonymous function, right below handleNoStream, we will place the following code, which looks almost identical to watch.

The only real differences between this block of code and watch from Part 3, is that we now catch ctrl.unable which is called if the browser is not WebRTC compatible, and session.ended which is called when the broadcaster stops streaming. Both callbacks invoke handleNoStream and display the “No Stream” message.

stream_embed

5.4 Try It Out

Start broadcasting a stream and then visit the page /embed.html?stream=myStreamName. If all goes well, you will see your stream load automatically! When you are ready to take your site live, remember to change the url from 4.1 genEmbed to your website’s name.

What Now?

This guide has only provided simple suggestions for your video streaming app. Get creative! These are very open callbacks. You can customize the way your embed page looks by styling the HTML, if you want the video smaller or larger, it is just a plain video HTML element and it can be modified with CSS. Make something cool!

0