Privacy-preserving screen sharing controls

François Beaufort
François Beaufort

Sharing tabs, windows, and screens is already possible on the web platform with the Screen Capture API. In short, getDisplayMedia() allows the user to select a screen or portion of a screen (such as a window) to capture as a media stream. This stream can then be recorded or shared with others over the network. There have been recent changes to the API to better preserve privacy, and prevent accidental sharing of personal information.

Here's a list of controls you can use for privacy-preserving screen sharing:

  • The displaySurface option can indicate that the web app prefers to offer a specific display surface type (tabs, windows, or screens).
  • The monitorTypeSurfaces option can be used to prevent the user from sharing an entire screen.
  • The surfaceSwitching option indicates whether Chrome should allow the user to dynamically switch between shared tabs.
  • The selfBrowserSurface option can be used to prevent the user from sharing the current tab. This avoids the "hall of mirrors" effect.
  • The systemAudio option ensures Chrome only offers relevant audio-capture to the user.

Changes to getDisplayMedia()

The following changes have been made to getDisplayMedia().

The displaySurface option

Web apps with specialized user journeys, which work best with sharing a window or a screen, can still ask Chrome to offer windows or screens more prominently in the media picker. The ordering of the offer remains unchanged, but the relevant pane is pre-selected.

The values for the displaySurface option are:

  • "browser" for tabs.
  • "window" for windows.
  • "monitor" for screens.
const stream = await navigator.mediaDevices.getDisplayMedia({
  // Pre-select the "Window" pane in the media picker.
  video: { displaySurface: "window" },
});
Screenshot of the media picker featuring the pre-selected
The "Window" pane is pre-selected in the media picker.

Note that we don’t offer the option to pre-select a specific window or screen. This is by design, as that would give the web app too much power over the user.

The monitorTypeSurfaces option

To protect companies from leakage of private information through employee-error, video conferencing web apps can now set monitorTypeSurfaces to "exclude". Chrome will then exclude screens in the media picker. To include it, set it to "include". Presently, the default value for monitorTypeSurfaces is "include", but web apps are encouraged to set it explicitly, as the default may change in the future.

const stream = await navigator.mediaDevices.getDisplayMedia({
  video: true,
  // Remove the "Entire Screen" pane in the media picker.
  monitorTypeSurfaces: "exclude",
});
Screenshot of the media picker with no
The "Entire Screen" pane is not visible in the media picker.

Note that an explicit monitorTypeSurfaces: "exclude" is mutually exclusive with displaySurface: "monitor".

The surfaceSwitching option

One of the top-cited reasons for sharing the entire screen, is the desire to seamlessly switch between sharing different surfaces during a session. To address this, Chrome now exposes a button that lets a user dynamically switch between sharing different tabs. This "Share this tab instead" button has previously been available to Chrome extensions, and can now be used by any web app which calls getDisplayMedia().

Screenshot of the button used to dynamically switch between sharing different tabs
The "Share this tab instead" button in Chrome.

If surfaceSwitching is set to "include", the browser will expose said button. If set to "exclude", it will refrain from showing the user that button. Web apps are encouraged to set an explicit value, since Chrome might change the default value over time.

const stream = await navigator.mediaDevices.getDisplayMedia({
  video: true,
  // Ask Chrome to expose browser-level UX elements that allow
  // the user to switch the underlying track at any time,
  // initiated by the user and without prior action by the web app.
  surfaceSwitching: "include"
});

The selfBrowserSurface option

In video conferencing scenarios, users often make the mistake of selecting the video conferencing tab itself, leading to a "hall of mirrors" effect, howling and general confusion.

To protect users from themselves, video conferencing web apps can now set selfBrowserSurface to "exclude". Chrome will then exclude the current tab from the list of tabs offered to the user. To include it, set it to "include". Presently, the default value for selfBrowserSurface is "exclude", but web apps are encouraged to set it explicitly, as the default may change in the future.

const stream = await navigator.mediaDevices.getDisplayMedia({
  video: true,
  selfBrowserSurface: "exclude"  // Avoid 🦶🔫.
});
Screenshot of the media picker excluding the current tab
The current tab is excluded, only the second tab is present.

Note that an explicit selfBrowserSurface: "exclude" is mutually exclusive with preferCurrentTab: true.

The systemAudio option

getDisplayMedia() allows capturing audio alongside video. But not all audio is created equal. Consider video conferencing web apps: - If the user shares another tab, it makes sense to capture audio as well. - System audio, on the other hand, includes remote participants' own audio, and should not be transmitted back to them.

In the future, it may be possible to exclude some audio sources from the capture. But for now, video conferencing web apps often find it best to just avoid capturing system audio. This could previously be done by checking what display surface the user chose, and stopping the audio track if they chose to share a screen. However, this raises a small issue, in that some users are confused when they explicitly check the checkbox to share system audio, and are then told by remote participants that no audio is incoming.

Screenshots of media pickers featuring tab audio sharing
Sharing tab audio is offered in "Chrome Tab" pane, but not in "Entire Screen" pane.

By setting systemAudio to "exclude", a web app can avoid baffling users through mixed signals. Chrome will offer to capture audio alongside tabs and windows, but not alongside screens.

const stream = await navigator.mediaDevices.getDisplayMedia({
  video: true,
  audio: true,           // Ask to capture audio; caveat follows.
  systemAudio: "exclude" // Do not offer to capture *system* audio.
});

Presently, the default value for systemAudio is "include", but web apps are encouraged to set it explicitly, as the default may change in the future.

Demo

You can play with these screen sharing controls by running the demo on Glitch. Be sure to check out the source code.

Browser support

  • displaySurface, surfaceSwitching, and selfBrowserSurface are available in Chrome 107 on desktop.

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: not supported.
  • Safari: not supported.
  • systemAudio is available in Chrome 105 on desktop.

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.
  • monitorTypeSurfaces is available in Chrome 119 on desktop.

Feedback

The Chrome team and the web standards community want to hear about your experiences with those screen sharing controls.

Tell us about the design

Is there something about those screen sharing controls that doesn't work as you expected? Or are there missing methods or properties that you need to implement your idea? Have a question or comment on the security model?

  • File a spec issue on the GitHub repo, or add your thoughts to an existing issue.

Problem with the implementation?

Did you find a bug with Chrome's implementation? Or is the implementation different from the spec?

  • File a bug at https://new.crbug.com. Be sure to include as much detail as you can, and simple instructions for reproducing. Glitch works well for sharing code.

Show support

Are you planning to use those screen sharing controls? Your public support helps the Chrome team prioritize features and shows other browser vendors how critical it is to support them.

Send a tweet to @ChromiumDev and let us know where and how you are using it.

Acknowledgements

Thanks to Rachel Andrew for reviewing