Click here to Skip to main content
13,143,637 members (29,393 online)
Click here to Skip to main content
Add your own
alternative version

Stats

3.2K views
39 downloads
3 bookmarked
Posted 26 Mar 2017

WebRTC Screencasting in Chrome

, 26 Mar 2017
Rate this:
Please Sign up or sign in to vote.
Screencasting (demo screen, screensharing) already works in Google Chrome. The technology allows capturing a window of the browser itself as well as windows of other applicaitons. For example, you can capture Firefox running in a separate window.

image

Screencasting in Chrome

Screencasting (demo screen, screensharing) already works in Google Chrome. The technology allows capturing a window of the browser itself as well as windows of other applicaitons. For example, you can capture Firefox running in a separate window. It's fine, but there is a security issue. In the Chrome browser screencasting is turned off. To enable screencasting, you need Chrome Desktop Capture API, and this article shows how to do this.

Screencasting extension

To make screencasting work, the user should install your Chrome extension designed specifically for your website (domain). The very first run of screencasting requires the follows actions from a user:

  1. The user opens the website and clicks Start screensharing.

    image
  2. The user is asked to add the extension for this action.

    image

The Chrome browsers asks to add the extension in a standard box, where a user can add the extension in just one click. The box notifies the user that the extension can capture the screen.

Your own extension

The next step is creating an extension for your domain. Let's say your test domain is mysupercat.com. In this case, when creating the extension, you should put the domain name into the code. Besides, your domain (the website on this domain) must work via HTTPS. Correspondingly, your screencasting page should open something like this: https://mysupercat.com/screen-sharing.php

The domain and HTTPS are, basically, all you need to create your own extension for screencasting. And you don't need to purchase SSL certificates. Self-signed certificates will do fine as long as your page does open via HTTPS, even if it's read and strikethrough:

image

Oh, and you need spare five bucks. This is what you need to pay to become a Chrome developer community. Let's conclude. To start creating and testing your own extension you need:

  • domain name
  • HTTPS hosting
  • 5 dollars on your credit card

Publishing the extension

  1. Go to Chrome Developer Dashboard and pay 5 bucks for membership.

    image
     
  2. Prepare a ZIP containing files of the extension. To do this, download 2 files here. Edit the manifest.json file and put your own:
  • name
  • author
  • description
  • homepage_url

For example:

"Name" : "My cool screen sharing extension",
"Author" : "I am",
"Description" : "The extensions shares screens from my website",
"Homepage_url" : "https://mysupercat.com",
{
  "name" : "Flashphoner Screen Sharing",
  "author": "Flashphoner",
  "version" : "1.4",
  "manifest_version" : 2,
  "minimum_chrome_version": "34",
  "description" : "This Chrome extension is developed for http://flashphoner.com WCS Api to enable screen capture.",
  "homepage_url": "http://flashphoner.com",
  "background": {
    "scripts": ["background-script.js"],
    "persistent": false
  },
  "externally_connectable": {
    "matches": [
      "https://flashphoner.com/*",
      "https://*.flashphoner.com/*",
      "*://localhost/*",
      "*://127.0.0.1/*"
    ]
  },
  "icons": {
    "16": "logo16.png",
    "48": "logo48.png",
    "128": "logo128.png"
  },
  "permissions": [
    "desktopCapture"
  ],
  "web_accessible_resources": [
    "logo48.png"
  ]
}

Pack these files to a ZIP archive with all the icons and other pictures. You can read more about icons here. Additional images are discussed here. Then click Add new item.

image

Then, after reading the agreement, upload your ZIP archive

image

After the archive is uploaded, verify everything and save

image

Now, you only need to publish the extension from the Dashboard by clicking the Publish button.

image

The published extension looks like this in the Dashboard:

image

Done. The extension is packed, published and is available for installing to a browser.

In-line install

Without in-line install, your users would have to open Chrome Store and install your extension from there. Not a big deal, but:

  • This is not very convenient to a user.
  • The user can get lost on the extension installation page and never get back to your page.

In-line installing of an extension is that nifty standard box that allows a user to skip visiting Chrome Store:

image

To configure in-line install, you should have a control over the domain and hosting specified in the manifest (manifest.json file). For example, if your domain is mysupercat.com, you will need to pass the standard verification procedure and confirm your ownership of this domain. To enable in-line install, enable the This item uses in-line install flag on the configuration page of the extension.

image

Then, you add your own website.

Search Console will open in a new window where you can pass verification.

The next step is to upload the identifier file to your hosting to confirm ownership of your domain / website

image

Verification is successful.

The verified site is displayed in the list of websites available for this extension, and now you can use in-line installing for the extension

image

Integrating screencasting to the web page

The extension is read and configured for in-line installing. We only need to embed the code to invoke the extension to the HTML page and test it. Screencasting in Google Chrome uses WebRTC API. So, to finish this test we need a WebRTC platform. As a server-side WebRTc platform we will use Web Call Server and Web SDK - a set of API scripts for this server.

1. Create an HTML page for screencasting screen-sharing.html The page is 20 lines of code looking as follows:

<p><title></p>
<h1>Screen Sharing</h1>
<p>Install Now</p>
<h2>Capture</h2>
<div id="localVideo" style="width: 320px; height: 240px"> </div>
<h2>Preview</h2>
<div id="remoteVideo" style="width: 320px; height: 240px"> </div>
<p>Connect and share screen</p>
<p id="status"> </p>

2) Upload the screen-sharing.js script. We will examine it in detail later.

<script type="text/javascript" src="screen-sharing.js"></script>

3) Specify where to look for the screencasting extension.

<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nlbaajplpmleofphigmgaifhoikjmbkg">

4) Add a button to execute installing of the extension.

<button id="installExtensionButton" onclick="installExtension()" type="button">Install Now</button>

5) Add a div - the localVideo element that will display the captured screen locally

<div id="localVideo" style="width: 320px; height: 240px"> </div>

6) Add a div - the remoteVideo element that will act as a player displaying what was received from the server, that is it displays the video stream captured to localVideo and sent to the server.

<div id="remoteVideo" style="width: 320px; height: 240px"> </div>

7) The button that initiates screencasting and displays the status of the stream

<button id="publishBtn" onclick="connectAndShareScreen()" type="button">Connect and share screen</button>
<p id="status"> </p>

Or page looks like this. image

 

2. Create JavaScript code for screencasting screen-sharing.js The code is available for download here. The code is a couple of screens with 5 main functions.

 

var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;
var remoteVideo;
var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg";

function init_page() {
   //init api
   try {
       Flashphoner.init({screenSharingExtensionId: extensionId});
   } catch (e) {
       //can't init
       return;
   }

   var interval = setInterval(function () {
       chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {
           if (response) {
               document.getElementById("installExtensionButton").disabled = true;
               clearInterval(interval);
               localVideo = document.getElementById("localVideo");
               remoteVideo = document.getElementById("remoteVideo");
           } else {
               document.getElementById("installExtensionButton").disabled = false;
           }
       });
   }, 500);

}

function connectAndShareScreen() {
   var url = "wss://wcs5-eu.flashphoner.com:8443";
   console.log("Create new session with url " + url);
   Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
       //session connected, start streaming
       startStreaming(session);
   }).on(SESSION_STATUS.DISCONNECTED, function () {
       setStatus(SESSION_STATUS.DISCONNECTED);
   }).on(SESSION_STATUS.FAILED, function () {
       setStatus(SESSION_STATUS.FAILED);
   });

}

function startStreaming(session) {
   var streamName = "test123";
   var constraints = {
       video: {
           width: 320,
           height: 240,
           frameRate: 10,
           type: "screen"
       }
   };
   session.createStream({
       name: streamName,
       display: localVideo,
       constraints: constraints
   }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
       setStatus(STREAM_STATUS.PUBLISHING);
       //play preview
       session.createStream({
           name: streamName,
           display: remoteVideo
       }).on(STREAM_STATUS.PLAYING, function (previewStream) {
           //enable stop button
       }).on(STREAM_STATUS.STOPPED, function () {
           publishStream.stop();
       }).on(STREAM_STATUS.FAILED, function () {
           //preview failed, stop publishStream
           if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
               setStatus(STREAM_STATUS.FAILED);
               publishStream.stop();
           }
       }).play();
   }).on(STREAM_STATUS.UNPUBLISHED, function () {
       setStatus(STREAM_STATUS.UNPUBLISHED);
       //enable start button
   }).on(STREAM_STATUS.FAILED, function () {
       setStatus(STREAM_STATUS.FAILED);
   }).publish();
}

//show connection or local stream status
function setStatus(status) {
   var statusField = document.getElementById("status");
   statusField.innerHTML = status;
}

//install extension
function installExtension() {
   chrome.webstore.install();
}

Let's examine this code in detail. 1) First, we declare several variables: statuses, localVideo and remoteVideo elements, and extensionId that contains the unique id of the screencasting extension.

var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
var localVideo;
var remoteVideo;
var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg"

2) The we send extensionId to the Flashphoner API, as a result the API knows which extension is used for screencasting.

Flashphoner.init({screenSharingExtensionId: extensionId});

3) Periodically we check Chrome and see if the extension is installed. If the extension is installed, we don't need the Install extension button any more and we can hide it.

chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {...}

4) The connectAndShareScreen function establishes connection to the server, and as soon it does (ESTABLISHED) it begins capturing and sending the video stream by delegating control to the startStreaming function.

function connectAndShareScreen() {
   var url = "wss://wcs5-eu.flashphoner.com:8443";
   console.log("Create new session with url " + url);
   Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
       //session connected, start streaming
       startStreaming(session);
   }).on(SESSION_STATUS.DISCONNECTED, function () {
       setStatus(SESSION_STATUS.DISCONNECTED);
   }).on(SESSION_STATUS.FAILED, function () {
       setStatus(SESSION_STATUS.FAILED);
   });
}

5) Before screencasting starts, we set such stream parameters as video resoultion and FPS.

var constraints = {
       video: {
           width: 320,
           height: 240,
           frameRate: 10,
           type: "screen"
       }
   };

6) Then we create the stream itself and invoke the publish() method. Please note, the stream is named test123

session.createStream({
       name: streamName,
       display: localVideo,
       constraints: constraints
   }).publish();

7) After the test123 stream is successfull sent to the server, the execution is transferred to the handler of the PUBLISHING event.

on(STREAM_STATUS.PUBLISHING, function (publishStream) {...}

8) Now we only need to play the stream in the adjacent div remoteVideo. To do this, we invoke the play() function.

session.createStream({
           name: streamName,
           display: remoteVideo
       }).play();

The page and the script are ready for testing.

Preparing to testing

As a result we have the following files:

  • screen-sharing.html
  • screen-sharing.js
  • flashphoner.js

flashphoner.js is included to Web SDK build. The latest build is available for download here. In addition to html and js files, we need the rebroadcasting server that accepts a video stream and broadcasts it to all others (in our case - back to the same page).

Testing of screencasting follows the below diagram:

image

The same way we can broadcast the screencasting stream to multiple connected users

image

Testing screencasting in Chrome

  1. Open the screen-sharing.html page via HTTPS in Google Chrome

    image
  2. Click the Install Now button to add the extension using in-line installing

    image
  3. Click Add extension and start screencasting by clicking Connect and share screen. Chrome asks to choose what to capture. This can be a tab or a window of Chrome itself, or another appliciaton.

    image
  4. Click Share and end up enjoying the final result. The screen is captured, sent to the server via WebRTC and returns back when the Preview block displays it.

    image

Conclusion

Therefore we successfully tested screencasting using a simple test page screen-sharing.html in the Google Chrome browser. The test page contains the extension for screencasting that we published in Chrome Store and installed in one click without opening the Store.

During testing the page operated via the HTTPS protocol and have sent and received video via Web Call Server - a WebRTC media server to broadcast streaming video.

To integrate screencasting to the HTML page we used the flashphoner.js script that is a part of the Web SDK build for the WCS server.

References

Chrome API to capture video from the desktop
Developer Dashboard for Chrome
Minimum code for a screencasting extension
Packing icons to the extension
Packing additional icons to the extension
Downlfoad the sample code of screencasting
Installing Web Call Server to your own host
Running WCS on Amazon EC2
Web SDK

Example source

License

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

Share

About the Author

Harry Truman
Netherlands Netherlands
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.170915.1 | Last Updated 27 Mar 2017
Article Copyright 2017 by Harry Truman
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid