Click here to Skip to main content
15,885,435 members
Articles / Web Development / HTML5

How to broadcast a web-cam to YouTube using HTML5 and WebRTC

Rate me:
Please Sign up or sign in to vote.
4.78/5 (5 votes)
13 Feb 2017CPOL12 min read 47.9K   4   11   5
In this article we explain how YouTube Live broadcasts work, and show how anyone with just basic JavaScript knowledge can come up with a YouTube Live broadcast from an HTML page using the WebRTC technology.

image You will need the following knowledge and skills:

  1. Basic knowledge of JavaScript / HTML
  2. Some skills in using Linux command line.
  3. Diligence and competence.

YouTube Live Broadcasting

YouTube allows to run real-time broadcasts. That is, instead of uploading a video, you create a live broadcast of yourself, your cat, your show or any other performance. The YouTube broadcast studio is located at this page. In Google Chrome it looks as follows:

image

To enable broadcasting, click the Enable live streaming button and pass two-steps verification. Then, the button turns to Create live event, and you can start your broadcast.

image

Click Go live now to go directly to broadcasting. YouTube will open a Google Hangouts window, where all manipulations with the stream are held.

image

Therefore, we created a live broadcasting on YouTube Live, started the broadcast, then stopped it. As a result, we received the YouTube video containing the broadcast. Broadcasting was performed by means of Google Hangouts. Sounds great so far, but according to IT news, Google will close Hangouts API for video app developments starting from April 25, 2017.

For developers, this means we will not be able to create our own custom applications using Hangouts API that stream video (including YouTube).

Broadcasting using RTMP live encoder

Now, let's take a look at an alternative way to run broadcasting without using Google Hangouts that would allow broadcasting the video stream from a specialized device (RTMP Live Encoder).

image

If you click the Stream Now button, you will see the customary video broadcasting interface. And now the important part - encoder settings:

image

As you can see, there are only two fields here:

  1. Server URL
  2. Stream name / key

When you click the Reveal button, the name of your stream will be displayed, so you can copy it.

These data are usually enough to send a video stream from RTMP Live Encoder to YouTube Live from any place and any computer, without using Google Hangouts. RTMP Live Encoder (further referred as encoder) is a hardware device or software that captures the video stream from the web camera or professional camera, encodes it to the RTMP protocol and sends it to the specified address (Encoder setup).

In order to produce high-quality audio and video stream, use standard Live Encoders codecs, namely H.264 for video and AAC for audio. This combination is well-known and reliable, so it became a de facto standard for RTMP use with standalone encoders.

For example, the Adobe Flash Player browser plugin is also an encoder, and it can stream video directly from the web page in a browser, but it does not offer support for the AAC audio codec for streaming, so broadcasting with it is somewhat limited due to the lack of sound.

That is why we consider only those encoders that explicitly support H.264 and AAC codecs. Currently, we know two candidates for testing that can work with these codecs:

Adobe Flash Media Live Encoder on Mac OS - a free software encoder by Adobe that is capable of encoding RTMP streams to H.264 and AAC. Please note, the AAC audio codec is only supported in the FMLE version for Mac OS. If you use the same software for Windows, the AAC codec is not available; mp3 will be used instead.

Wirecast is a paid encoder with a trial version that puts a logo over the broadcast video and inserts sound every 30 seconds. Wirecast can be installed on Windows.

Let's start with Adobe FMLE. Install FMLE on Mac and connect a web camera to the computer (we used Mac Mini in our tests). It seems that FMLE does not work with virtual cameras, so you need a hardware USB web camera or a built-in one (if you have a Macbook).

As a video codec, select H.264 and the resolution of 640x480. Leave the default audio codec, AAC 22050 Hz mono. All other H.264 and AAC settings should also work flawlessly, though.

Insert the RTMP address of the broadcasting received from YouTube to the FMS URL box. Insert the name of the stream also received from YouTube to the Stream box.

* The box has such a strange name, FMS URL, because FMLE thinks there is only one server in the world capable of receiving an RTMP stream - Flash Media Server by Adobe (now Adobe Media Server). But as we can see, this is not so, and a number of software and services including YouTube can deal with this perfectly.
 

image

After we set all the settings, we click the green Start button to start the broadcast and send the video to YouTube. The image is a bit muddy, because my testing Mac is overloaded, and the screenshots are taken with Teamviewer, so high quality images are out of the question. For quality streaming, make sure you have a high-res camera and a powerful CPU, for example Core i7, as well as an SSD disk for effortless and unhampered encoding of the RTMP video stream.

image

Now, as we have successfully configured FMLE, there is no need in explicitly testing Wirecast. If you have problems with FMLE, or simply do not have a nearby Mac OS, you can try doing the same using Wirecast.

Converting from WebRTC to RTMP

Above, we have conducted a test that shows how to run a broadcast using YouTube Live and how to send an RTMP video stream encoded to H.264 + AAC to YouTube.

Now, the next task is to do the same using WebRTC. WebRTC is a technology already built into browsers. It allows a browser to capture video from the camera and audio from the microphone and send the stream to the web. Therefore, a WebRTC-compatible browser can work exactly like Live Encoder - capture and send video and sound. WebRTC is supported by:

  • Chrome
  • Firefox
  • Opera
  • Chrome for Android
  • Firefox for Android

This means WebRTC video streams can be sent from desktop browsers Chrome, FF, and from Android versions of the same browsers.

As a result, our goal is to run a broadcasting from Google Chrome to YouRube on a simple HTML page without using Google Hangouts or RTMP Live Encoder. Here, we have three problems:

  • WebRTC does not support the RTMP protocol required by YouTube.
  • WebRTC does not support the AAC audio codec required by YouTube.
  • WebRTC in Chrome does not support the H.264 on mobile devices. They use VP8.

Due to these reasons, WebRTC cannot directly send audio + video stream to YouTube Live. Speaking of Adobe Flash Player, there is another problem here:

  • It doesn't encode audio to AAC

Therefore, regardless of whether you use a WebRTC-compatible browser (Chrome) or a browser with Flash Player (IE or Safari), you still cannot send an RTMP video stream encoded to H.264 + AAC directly from the browser.

The solution is to convert a video stream on the server side as shown below: image Here, broadcasting is run using a medium - the server that receives a WebRTC video stream and converts it to the format accepted by YouTube. For testing, we use Web Call Server 5.

This is a media server that supports WebRTC and RTMP, with a trial version.

We need to install Web Call Server 5 to a Linux-server and redirect a WebRTC video stream to it. Then the stream is redirected to YouTube. We will need a local 64-bit Linux server or a VPS server. Minimum requirements are 1-core CPU, 1GB RAM, Linux x86_64.

We've managed to find a decrepit 2-core Athlon 64, 1.8 GHz with CentOS 6 installed and 2 gigabytes of RAM. More than enough for testing. The installation process is well-documented on the vendor's website.

1) Download the archive

Bash
wget https://flashphoner.com/download-wcs5-server.tar.gz

Upon downloading, wget complains of certificates. So we have to set the flag:

Bash
wget --no-check-certificate https://flashphoner.com/download-wcs5-server.tar.gz

2) Unpack

Bash
tar -xzf download-wcs5-server.tar.gz

3) Run the installer

Bash
./install.sh

The installer reports an error and points out the lack of Java.

4) Install java with the package manager, then run the installer again.

Bash
yum install java
Bash
./install.sh

During installation, the installer asks, if the server is in a local network. We answer 'yes', and the installer writes the local IP address of the server 192.168.1.59 to the settings.

5) Now, it's time to run the server.

Bash
service webcallserver start

Server starts for about a minute.

6) Open the dashboard at https://192.168.1.59:8888 in Chrome

image Sure enough, the browser complains about the lack of the normal SSL certificates. Later, we can import them. For example, we can take the free ones at letsencrypt.

Now, we simply click Advanced / Proceed and confirm the security exclusion.

7) The developer docs suggest one more thing about certificates we should do. We need to repeat the previous step for this page: https://192.168.1.59:8443

This is required to make signal websocket connections operate properly. Without them, WebRTC will not work, because it requires SDP exchange via a separate connection.

image

After these two steps are complete, the Dashboard with demo examples should open. We need the demo called 'WebRTC as RTMP re-publishing', it look as follows:

image



Let's test it in Google Chrome. The goal is to redirect a WebRTC audio + video stream to Web Call Server 5, convert it to RTMP and send to the recipient.

image

To start testing, click the Start button and allow the browser to access the camera and the microphone. On the above screenshot:

  1. Browser Google Chrome connects to Web Call Server 5 via the websocket protocol and secure connection: wss://192.168.1.59:8443
  2. A WebRTC audio + video stream is sent to the server, and the status PUBLISHING is displayed indicating the video stream is being successfully sent to the server.
  3. Web Call Server sends the received WebRTC audio + video stream to the specified RTMP address:
  • rtmp://localhost:1935/live
  • stream1

So, here we forward the RTMP video stream to localhost, that is to the same 192.168.1.59 server in our case. So, we could say Web Call Server has received the WebRTC stream and turned it back to itself as RTMP.

Please notice how this correlates to YouTube Live. There, we specified Server URL and Stream name / key

image

4) Then, we only need to play the video stream in the built-in player. The address and the stream name are formed automatically.
image

The RTMP player built into the page is very simple, and is merely here to make sure the stream is here and it plays OK. The full address of the stream is: rtmp://192.168.1.59:1935/live/rtmp_stream1

Pay attention to this: Web Call Server 5 substitutes the 'rtmp_' prefix to the name of the stream. That is, it takes the stream1 stream and redirects it as rtmp_stream1.

When testing on localhost it is important that the names of the streams were different. The local testing was successful, so it is time to send the stream to YouTube Live. Remember, when we tested YouTube Live with the RTMP live video encoder we used

  • Server URL: rtmp://a.rtmp.youtube.com/live2
  • Stream name / key: myfm-c9td-etew-eqdf

That is, YouTube wants this name of the stream and nothing else: myfm-c9td-etew-eqdf. So, if Web Call Server adds its rtmp_ prefix, the resulting name will be rtmp_myfm-c9td-etew-eqdf, and YouTube will not accpet it. We need a workaround, so let's edit the config on the server side: /usr/local/FlashphonerWebCallServer/conf/flashphoner.properties. Comment out or remove this line in the config:

Bash
#rtmp_transponder_stream_name_prefix =rtmp_

This way, we basically tell the server to not add the prefix, and forward the received stream as is.

image

Changing this setting requires restart. So, we restart the server and wait for about one minute.

Bash
service webcallserver restart

After restart, we are ready to finish. Open the dashboard and the 'WebRTC as RTMP re-publishing' demo example again. But this time, we enter the RTMP address exactly as for Live Encoder.

image

Finally, we open YouTube Live and watch the result:

image
This time we were able to throw the WebRTC video stream to Youtube as RTMP and get the picture. In the Google Chrome browser, on the chrome://webrtc-internals tab, you can see graphs illustrating delivery of WebRTC video stream to the server:

image

From the side of YouTube, the incoming traffic looks as follows:

image

Looks very similar to HTTP Live streaming (HLS) with video segments loaded via HTTP (HTTPS). Great! We managed to test everything and make sure the method is working.

We have image, we have sound, the video stream goes right from the browser to YouTube. Now, let's do some coding. In particular, we want the same on a simple HTML page - a sample of our own website or application.

Coding an HTML-page to send WebRTC to YouTube

The simplest way to grasp the example would be to download three source files: HTML, JavaScript, CSS. However, we'll skip the shortcuts and will create a bare-minimum dummy page from scratch. Let's first make a template test-webrtc-youtube.html

HTML
<!DOCTYPE html>
<html>
 <head lang="en">
  <meta charset="UTF-8">
  <title></title>
 </head>
 <body></body>
</html>

Now, download the flashphoner.js script that does all the work regarding WebRTC and sending of the video stream to the server. This script is a part of Web SDK that is available to download from here.

Download and unpack Web SDK to a separate server with Apache (or Nginx) installed.

Bash
wget https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/flashphoner-api-0.5.14.1977-48448b99eddb0da1248519290dba2d4d00d4a505.tar.gz

Create a folder /var/www/html/test-webrtc-youtube where the html page should be, and copy the html and the js files there. So, we end up with the following structure:

Bash
test-webrtc-youtube
-- flashphoner.js
-- test-webrtc-youtube.html

1. Add the following elements to the page:

HTML
<body onload="init_page()">
   <div id="localVideo" style="width:320px;height:320px;border: 1px solid"></div>
   Server URL <input type="text" id="urlServer" value="wss://192.168.1.59:8443"/><br/>
   Stream URL: <input type="text" id="rtmpUrl" value="rtmp://a.rtmp.youtube.com/live2"/><br/>
   Stream name / key: <input type="text" id="streamName" value="myfm-c9td-etew-xxxx"/><br/>
   <input type="button" onclick="publishToYoutube()" value="Start"/>
   <p id="status"></p>
</body

1) localVideo - this is merely a div where the video from the web camera is put to
2) urlServer, rtmpUrl, streamName - already familiar values from previous testing
3) status - this field displays connection status or stream

2. Add three variables:

JavaScript
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;

The first two are shortcuts. The localVideo variable will hold the link to the div element.

3. Initialize the API

JavaScript
function init_page() {
   Flashphoner.init();
   localVideo = document.getElementById("localVideo");
}

4. Connect to the WCS server and start streaming.

JavaScript
function publishToYoutube(){
   var urlServer = document.getElementById("urlServer").value;
   Flashphoner.createSession({urlServer: urlServer}).on(SESSION_STATUS.ESTABLISHED, function(session){
       //session connected, start streaming
       startStreaming(session);
   }).on(SESSION_STATUS.DISCONNECTED, function(){
       setStatus("Connection DISCONNECTED");
   }).on(SESSION_STATUS.FAILED, function(){
       setStatus("Connection FAILED");
   });
}

On successful connection indicated by the ESTABLISHED event, we start streaming by calling to the startStreaming function

5. Send the video stream.

JavaScript
function startStreaming(session) {
   var streamName =  document.getElementById("streamName").value;
   var rtmpUrl =  document.getElementById("rtmpUrl").value;
   session.createStream({
       name: streamName,
       display: localVideo,
       cacheLocalResources: true,
       receiveVideo: false,
       receiveAudio: false,
       rtmpUrl: rtmpUrl
   }).on(STREAM_STATUS.PUBLISHING, function(publishStream){
       setStatus(STREAM_STATUS.PUBLISHING);
   }).on(STREAM_STATUS.UNPUBLISHED, function(){
       setStatus(STREAM_STATUS.UNPUBLISHED);
   }).on(STREAM_STATUS.FAILED, function(){
       setStatus(STREAM_STATUS.FAILED);
   }).publish();
}

Here, we create the stream and call the publish function for it.

6. Display all statuses using the separate function.

JavaScript
function setStatus(status){
   document.getElementById("status").innerHTML = status;
}

Finally we ended up with nearly the same result as we did with the demo:

Note that we again use the https protocol. The web server must be configured to work via https. Usually, this simply requires setting mod_ssl:

Bash
yum install mod_ssl

HTML code of the page is exactly 65 lines. It looks as follows:

image

The source is attached. As a result, we have an HTML page 65 lines long including all scripts, that uses the API file flashphoner.js to send a WebRTC video to Web Call Server, which in turn forwards this video stream to the YouTube Live service.

That's all. Materials and links used in this article are listed below for those who wants to reproduce all steps.

Links:

1) Youtube Live
2) Adobe Flash Media Live Encoder
3) Wirecast
4) Web Call Server (used version 2047)
5) WebRTC
6) Google closes Hangouts API

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionLive Streaming using other devices without webcam Pin
Member 1458322511-Sep-19 20:43
Member 1458322511-Sep-19 20:43 
QuestionHTML code in other computer Pin
Member 1378880519-Apr-18 14:26
Member 1378880519-Apr-18 14:26 
Is the HTML code must also be on the Linux Server or it can be on the other computer? Thank you.
QuestionLicense for trial? Pin
Adi Gunawan Hidayat24-Jan-18 19:55
Adi Gunawan Hidayat24-Jan-18 19:55 
GeneralMy vote of 5 Pin
elgerm7-Sep-17 23:22
elgerm7-Sep-17 23:22 
Questionabout article Pin
Member 1300086814-Feb-17 5:37
Member 1300086814-Feb-17 5:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.