Screen sharing using the Web SDK
Important: As of Chrome 72+, Firefox 52+, and Opera 59+, an extension is no longer needed for screen sharing. The browser prompts the end user for access to the screen as it would for access to the camera.
In older versions of Opera and 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 screen-sharing extension.)
Note: On macOS 10.15+ (Catalina), to publish a screen-sharing stream the user must grant the browser access to the screen in macOS System Preferences > Security & Privacy > Privacy > Screen Recording. Otherwise, the Publisher will dispatch an accessDenied event.
The Vonage Video plugin for Internet Explorer has screen-sharing support built in. (Note that support for the Vonage Video plugin for Internet Explorer is removed in Vonage Video 2.17.)
In Electron, screen sharing is supported if the webPreferences.contextIsolation option of the Electron BrowserWindow is set to false or if the app uses a preload script to access the desktop capturer. For details, see Enabling screen-sharing in Electron.
Publishing screen-sharing streams is currently not supported in Safari on iOS or in Safari 12 and older on macOS.
In all supported browsers, publishing a screen-sharing stream requires the page to be loaded over HTTPS.
Publishing screen-sharing videos is supported in Chrome, Firefox, Opera, Chromium-based versions of Edge (versions 79+), and Safari 13+. It is currently not supported in mobile browsers, Safari 12 and older on macOS. Publishing a screen-sharing stream is only supported when the web page is loaded via HTTPS.
Note: To support screen-sharing in older versions of Chrome and Opera, you must create a screen-sharing extension.
No extension is required to subscribe to a screen-sharing video stream, which is possible in all browsers that support the Vonage Video API.
Developing a Screen-Sharing Extension (Deprecated)
Important: Screen sharing extensions are not required in the latest versions of Chrome, Firefox, and Opera.
To support screen-sharing in older versions of Chrome and Opera, you must create a screen-sharing extension.
https://github.com/opentok/screensharing-extensions
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:
supported— (Boolean) Whether sharing is supported.supportedSources— Deprecated. In older browser versions, you could select a type of screen-sharing source (such as"application","screen", or"window"by setting thevideoSourceproperty of the options passed into theOT.initPublisher()method. However, in current browsers that support screen sharing, passing in any of these values results in the same behavior — the browser displays a dialog box in which the end user selects the screen-sharing source (which can be the entire screen or a specific window). In Electron, screen sharing captures the entire screen, without prompting the user for permission.
The options parameter also includes the following properties, which apply to screen-sharing support in older versions of Chrome and Opera, which require screen-sharing extensions — in other browsers, they are undefined:
extensionRequired(String) — Set to "chrome" in older versions of Chrome (prior to Chrome 72) and Opera (prior to Opera 59), which require a screen sharing extension to be installed.extensionRegistered(Boolean) — In older versions of Chrome (prior to Chrome 72) and Opera (prior to Opera 59), this property is set totrueif a screen-sharing extension is registered; otherwise it is set tofalse. Use theOT.registerScreenSharingExtension()method to register an extension in Chrome or Opera.extensionInstalled(Boolean) — If an extension is required, this is set totrueif the extension is installed (and registered, if needed); otherwise it is set tofalse.
Note: Screen sharing is only supported when the web page is 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
}
});
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:
"cover"— The video is cropped if its dimensions don't match those of the DOM element. This is the default setting for videos publishing a camera feed."contain"— The video is letter-boxed if its dimensions don't match those of the DOM element. This is the default setting for screen-sharing videos.
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:
newValue— An object with width and height properties defining the new width and height of the video.oldValue— An object with width and height properties defining the previous width and height of the video.target— The Publisher or Subscriber object.
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.
}
});
Enabling Screen Sharing in Electron
In Electron, screen sharing is supported if the webPreferences.contextIsolation option of the Electron BrowserWindow is set to false or if the app uses a preload script to access the desktop capturer. The default value of webPreferences.contextIsolation option is true in Electron 12+ and false in previous versions. In Electron 17+, a breaking change was introduced, causing screen sharing to only be available after using a preload script.
Enabling Screen Sharing via Preload Script in Electron Versions 12-16
To enable screen sharing in Electron versions 12-16 using a preload script, add the following to the preload.js file:
const {
contextBridge,
desktopCapturer
} = require('electron');
// Expose the desktopCapturer so that OpenTok.js can access it
// via window.electron.desktopCapturer
contextBridge.exposeInMainWorld(
'electron', {
desktopCapturer,
}
);
Then reference preload.js when instantiating a BrowserWindow in Electron:
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'preload.js'), // use the preload script
}
});
Enabling Screen Sharing via Preload Script in Electron Versions 17+
To enable screen sharing in Electron versions 17+, add the following to the preload.js file:
const {
contextBridge,
ipcRenderer
} = require('electron');
// Event emitter to send asynchronous messages to the main process. The
// corresponding ipcMain handler listens for the 'DESKTOP_CAPTURER_GET_SOURCES'
// channel and returns an array of the available DesktopCapturerSource objects.
const desktopCapturer = {
getSources: (opts) => ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', opts)
};
// Expose desktopCapturer so that the SDK can access it.
contextBridge.exposeInMainWorld(
'electron', {
desktopCapturer
}
);
Then reference preload.js when instantiating a BrowserWindow in Electron:
// Event emitter to handle messages sent from the renderer process. This handler
// will be called whenever a renderer calls
// ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', ...args)
electron.ipcMain.handle(
'DESKTOP_CAPTURER_GET_SOURCES',
(event, opts) => electron.desktopCapturer.getSources(opts)
);
mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js') // use a preload script
}
});
Optimizing Video performance of Certain Screen-Sharing Streams
You can set a video content hint to improve the quality and performance of a screen-sharing video that will primarily contain either text or video content. For details, see Setting video content hints to improve video performance in certain situations.