Suggestions

close search

Screen sharing — Web

You can publish a stream that uses a video view of your screen (instead of a camera) as the source. A client connected to the session can subscribe to the stream (and view it), just as they would subscribe to a stream that uses a camera as the source.

A client connected to the session can subscribe to a screen-sharing stream (and view it), just as they would subscribe to a stream that uses a camera as the source. (No browser extension is required to subscribe to a stream-sharing stream.)

In Chrome, to publish a screen-sharing video, the client needs to add an extension that enables publishing screen-sharing streams for your domain. (See Developing a Chrome screen-sharing extension.)

As of Firefox 52, an extension (or whitelist listing) is no longer needed for screen sharing. Firefox prompts the end user for access to a screen, window, or application, as it would for access to the camera. For more information, see this Mozilla blog post. To support screen sharing in older versions of Firefox, see the OpenTok screensharing-extensions repo on GitHub.

The OpenTok plugin for Internet Explorer has screen sharing support built in.

Electron does not require an extension for screensharing, you can simply call the OT.checkScreenSharingCapability() to start screensharing. Click here to see the full implementation details.

In all browsers, publishing a screen-sharing stream requires the page to be loaded over HTTPS.

This topic includes the following sections:

Quick Start

In Chrome the user can install an extension to enable publishing a screen-sharing video stream for your domain. Firefox (version 52+) and the OpenTok plugin for Internet Explorer have screen sharing support built in. Publishing a screen-sharing stream is only supported when the web page and the OpenTok.js file are loaded via HTTPS.

No extension is required to subscribe to a screen-sharing video stream.

Developing a Chrome screen-sharing extension

To support screen-sharing in Chrome, you must create a Chrome screen-sharing extension. See the following GitHub repository for sample code for a Chrome screen-sharing extension:

https://github.com/opentok/screensharing-extensions

This site includes instructions on developing the extension. It also includes a sample HTML file for testing your screen-sharing extension.

To test your screen-sharing extension:

For your production website, register your screen-sharing extension in the Chrome Web Store. Then, in your app, you will register the ID of the extension using OpenTok.js.

In Chrome, call the OT.registerScreenSharingExtension() method to register the screen-sharing extension. This method takes three parameters:

Sample code

Once you have created a screen-sharing extension for Chrome and installed it in your browser (see the previous section), you can use the following code to test it. (Firefox 52+ and the OpenTok plugin for Internet Explorer have screen-sharing support built in.)

Be sure to edit the code to enter values for apiKey, sessionId, and token (and for the Chrome extension ID, if you are testing on Chrome). Also, you must load the page over HTTPS. Load the page in one browser tab to publish the screen-sharing stream (along with a stream that uses the camera as the video source). Load it in a second tab to view the streams published by the first tab.

<html>
<body>
  <div id="camera"></div>
  <div id="screen-preview"></div>
  <script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
  <script type="text/javascript">

    // Go to https://tokbox.com/account to find your OpenTok
    // API key and generate a test session ID and token:
    var apiKey    = "<YOUR_API_KEY>";
    var sessionId = "<YOUR_SESSION_ID>";
    var token     = "<YOUR_TOKEN>";

    var session = OT.initSession(apiKey, sessionId);

    session.connect(token, function(error) {
      var publisher = OT.initPublisher('camera');
      session.publish(publisher, function() {
        screenshare();
      });
    });

    session.on('streamCreated', function(event) {
      session.subscribe(event.stream);
    });

    // For Google Chrome only, register your extension by ID. You can
    // find it at chrome://extensions once the extension is installed.
    //
    // The last parameter assumes you are using the latest version (version 2)
    // of the OpenTok Chrome extension source code.
    OT.registerScreenSharingExtension('chrome', '<YOUR_CHROME_EXTENSION_ID>', 2);

    function screenshare() {
      OT.checkScreenSharingCapability(function(response) {
        if (!response.supported || response.extensionRegistered === false) {
          alert('This browser does not support screen sharing.');
        } else if (response.extensionInstalled === false) {
          alert('Please install the screen sharing extension and load your app over https.');
        } else {
          // Screen sharing is available. Publish the screen.
          var screenSharingPublisher = OT.initPublisher('screen-preview', {videoSource: 'screen'});
          session.publish(screenSharingPublisher, function(error) {
            if (error) {
              alert('Could not share the screen: ' + error.message);
            }
          });
        }
      });
    }
  </script>
</body>
</html>

Distributing a screen-sharing extension

In order to use screen-sharing at your website, Chrome users need to install your screen-sharing extension.

You must package your Chrome screen-sharing extension and register it in the Chrome Web Store. See the Chrome documentation for details on publishing your extension in the Chrome Web Store. You can use the Chrome inline installation to initiate installation of your extension "inline" from your site. In your app, you will need to register the ID of the extension using OpenTok.js.

Checking for screen-sharing support

To check if publishing a screen-sharing stream is supported in the client browser, call the OT.checkScreenSharingCapability() method. This method takes one parameter: a callback function. The callback function is passed a response object. This object has the following properties that indicate support for publishing screen-sharing streams in the client:

The options parameter also includes the following properties, which apply to screen-sharing support in Chrome (in other browsers, they are undefined):

Note: Screen sharing is only supported when the web page and the OpenTok.js file are loaded via HTTPS.

The following example shows how to check for screen-sharing support:

OT.checkScreenSharingCapability(function(response) {
  if(!response.supported || response.extensionRegistered === false) {
    // This browser does not support screen sharing
  }
});

Publishing a stream with a screen-sharing source

The videoSource property of the options parameter of the OT.initPublisher() method defines the video source for the stream to be published. For screen-sharing, set this property to one of the following: "screen", "application", or "window". In Firefox, all three settings are supported. In Chrome, pass in "screen"; the user selects what they want to share. In Internet Explorer (using the OpenTok plugin), "screen" and "window" are supported.

The following code shows how to publish a stream that uses screen sharing as the source:

<div id="publisher"></div>
<div id="screen-preview"></div>

OT.checkScreenSharingCapability(function(response) {
  if(!response.supported || response.extensionRegistered === false) {
    // This browser does not support screen sharing.
  } else if (response.extensionInstalled === false) {
    // Prompt to install the extension.
  } else {
    // Screen sharing is available. Publish the screen.
    var publisher = OT.initPublisher('screen-preview',
      {videoSource: 'screen'},
      function(error) {
        if (error) {
          // Look at error.message to see what went wrong.
        } else {
          session.publish(publisher, function(error) {
            if (error) {
              // Look error.message to see what went wrong.
            }
          });
        }
      }
    );
  }
});

Upon error, the completion handler for the OT.initPublisher() method can be passed an error object with one of the following error codes:

When you publish screen-sharing stream, the following default values are set for the options parameter of the OT.initPublisher() method:

Additionally, subscribers to the resulting stream also default to using the "contain" fitMode setting.

For information on maxResolution and fitMode, see the next two sections.

Setting the maximum resolution of the stream

You can set a maxResolution property when you call the OT.initPublisher() method. This property sets the maximum resolution to stream. When sharing a window, the resolution of the stream will match the window's dimensions unless the window is larger than the maxResolution setting (when the user resizes the window).

The maxResolution property is an object with two properties: width and height. The maximum value for each is 1920, and the minimum value is 10.

var publishOptions = {};
publishOptions.maxResolution = { width: 1920, height: 1080 };
publishOptions.videoSource = 'screen';
OT.initPublisher('some-element-id', publishOptions);

For screen-sharing, do not set the resolution option for the OT.initPublisher() method.

You may not want to display the screen-sharing video in the HTML DOM on the page that you publish it from. For example, if you are sharing the entire screen and you include the video in the HTML DOM, you will see a recursive "hall of mirrors" effect. To prevent this, create an HTML DOM element for the publisher element and do not display the element in the HTML DOM:

var publishOptions = {videoSource: 'screen'};
var screenPublisherElement = document.createElement('div');
OT.initPublisher(screenPublisherElement, publishOptions);

Cropping or letter-boxing screen-sharing videos

You can set a fitMode property of the options parameter you pass into the OT.initPublisher() and Session.subscribe() methods. The fitMode property determines how the video is displayed if the its dimensions do not match those of the DOM element. You can set this property to one of the following values:

Determining the video type ("screen" or "camera") for a stream

The Stream object contains a new videoType property. This can be set to one of the following values

The following code subscribes to streams and adds them to different HTML DIV container elements, based on the video type:

<div id="people"></div>
<div id="screens"></div>

session.on('streamCreated', function(event) {
  var subOptions = {insertMode: 'append'};
  if(event.stream.videoType === 'screen') {
    session.subscribe(event.stream, 'screens', subOptions);
  } else {
    session.subscribe(event.stream, 'people', subOptions);
  }
});

Detecting when video dimensions change

The Publisher object that is publishing a screen-sharing stream and a Subscriber object that is subscribing to a screen-sharing stream can each dispatch a videoDimensionsChanged event. The event is dispatched when the publishing client resizes a window being shared.

The videoDimensionsChanged event has the following properties:

You may use the newValue.width and newValue.height properties to adjust the size of the publisher in the HTML DOM:

var publisher = OT.initPublisher('some-element',
  {videoSource: 'screen'});

publisher.on('videoDimensionsChanged', function(event) {
  publisher.element.style.width = event.newValue.width + 'px';
  publisher.element.style.height = event.newValue.height + 'px';
});

Determining when the user stops sharing the screen

When the user stops sharing the screen, the Publisher object dispatches a mediaStopped event.

If the Publisher was also publishing the stream to a session, it also dispatches a streamDestroyed event with the reason property set to "mediaStopped". Also, the Session object on all clients connected to the session dispatches a streamDestroyed event with the reason property set to "mediaStopped".

The default behavior for both the mediaStopped event and the streamDestroyed event is to delete the publisher (or the subscriber in the case of a subscribed stream). Call the preventDefault() method of the event object to prevent the publisher or subscriber from being deleted.

publisher.on('mediaStopped', function(event) {
  // The user clicked stop.
});

publisher.on('streamDestroyed', function(event) {
  if (event.reason === 'mediaStopped') {
    // User clicked stop sharing
  } else if (event.reason === 'forceUnpublished') {
    // A moderator forced the user to stop sharing.
  }
});

Subscribing to screen-sharing streams

You can subscribe to a stream that uses a screen-sharing video source in the same way that you subscribe to a stream that uses a camera as the source. See Subscribing to streams.

You can detect that a stream is a screen-sharing stream, by checking the videoType property of the Stream object. For a screen-sharing stream, this property is set to "screen".

The following code subscribes to streams, appending them to different HTML DOM container elements, based on the video type ("screen" or "camera"):

session.on('streamCreated', function(event) {
  var subOptions = {
    appendMode: 'append'
  };

  var parentElementId = event.stream.videoType === 'screen' ?
    'sub-screen-sharing-container' :
    'sub-camera-container';
  subscriber = session.subscribe(event.stream, parentElement, subOptions);
});

The dimensions of a screen-sharing stream can change if user publishing the stream resizes the window that is the source for the stream. When the video dimensions change, the Subscriber object dispatches a videoDimensionsChanged event.

The following code resizes a subscriber when the stream's video dimensions change:

subscriber.on('videoDimensionsChanged', function(event) {
  subscriber.element.style.width = event.newValue.width + 'px';
  subscriber.element.style.height = event.newValue.height + 'px';
  // You may want to adjust other UI.
});