Screen Capture in Firefox
Tags: javascript, firefox, webrtc
Published: 2017-10-30 22:28:43

---
title: Screen Capture in Firefox    
published: true
description: Build screen capture for WebRTC in Firefox
tags: javascript, firefox, webrtc
canonical_url: https://www.twilio.com/blog/2017/10/screen-capture-in-firefox.html
cover_image: https://thepracticaldev.s3.amazonaws.com/i/anrxbn2wx7t9kfzhmmk8.png
---

Screen sharing is a hugely useful feature you can build into a video chat. We recently saw how to <a href="https://dev.to/philnash/screen-capture-in-google-chrome-bjo">capture the screen using Chrome</a>. Support in only one browser is not much fun so you'll be pleased to hear we can access screen capture in Firefox too. Let's see how.

<img alt="An animation showing the final product of this tutorial. Clicking on a start screen button initiates the screen capture permissions in Firefox, when the screen is chosen to be shared it is then visible in a video on the web page." src="https://twilioinc.wpengine.com/wp-content/uploads/2017/10/35W6m2ZumESuVdSSLjXF98mQa9KlVsOvsyE3ngL-u1B6sVtl-3PH75BOseLm0kkVbpT84xbsvYYuNDQNxXr122iHi4cXYuHX-QhVQQecmksKTvlE94YIrWgn6ZgRSCq3KcmNwwM.png" class="aligncenter">

## What you need

* <a href="https://www.mozilla.org/firefox/">Firefox</a>
* A text editor
* A local web server - I like to use <a href="https://www.npmjs.com/package/servedir">servedir</a> for things like this
* Either <a href="https://ngrok.com/">ngrok</a> or an equivalent tunnelling service or TLS certificates set up for localhost (we'll see why later)

## Screen capture

It was not straightforward to implement screen capture for our own application with Chrome as we needed to build an extension. Firefox, on the other hand, has supported screen capture since version 33 using the `mediaSource` constraint in the <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices">`mediaDevices` API</a>.

However, before Firefox version 52 your site needed to be on a whitelist to access screen capture in Firefox. You can see who is on the whitelist by opening about:config in Firefox and searching for "screensharing".

Since Firefox version 52, this capability was made available to all sites that are served over HTTPS. You could build an extension that added your site to the whitelist, however as Firefox is up to version 56 as I write this, we won't explore that within this post.

### The code

To get access to a media stream of the screen in Firefox, the code looks a bit like this:

```javascript
navigator.mediaDevices.getUserMedia({
  video: {
    mediaSource: 'screen'
  }
}).then(returnedStream => {
  // use the stream
});
```

This works slightly different to the <a href="https://dev.to/philnash/screen-capture-in-google-chrome-bjo">Chrome example</a> in which you could pass an array of potential sources, including "window", "screen" or "tab". In Firefox you can only request one `mediaSource` at a time from the choices "screen", "window" or "application".

To explore how this all works in Firefox let's build the same example application <a href="https://dev.to/philnash/screen-capture-in-google-chrome-bjo">that we built for Chrome</a>, capturing the screen then showing it in a `<video>` element.

## Building screen capture

Create a new directory for this project as well as a file called `index.html`. All the work will be in the HTML for this example, so that is the only file you will need.

We'll use the same HTML structure as the <a href="https://github.com/philnash/screen-capture/blob/master/chrome/index.html">Chrome example</a>, except we'll add a set of radio buttons to select the source we want. Add the following to `index.html`:

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Screen</title>
</head>

<body>
  <h1>Show my screen</h1>

  <video autoplay id="screen-view" width="50%"></video>
  <ul>
    <li>
      <label for="screen">Screen</label>
      <input type="radio" name="capture" id="screen" value="screen" checked>
    </li>
    <li>
      <label for="window">Window</label>
      <input type="radio" name="capture" id="window" value="window">
    </li>
    <li>
      <label for="application">Application</label>
      <input type="radio" name="capture" id="application" value="application">
    </li>
  </ul>
  <button id="get-screen">Get the screen</button>
  <button id="stop-screen" style="display:none">Stop the screen</button>

  <script>

  </script>
</body>
</html>
```

Within the `<script>` tags we'll start with some of the code we already had from the previous project. This code selects the video and button elements that we need to use, initialises a `stream` variable and sets up a listener to stop the stream when the "Stop screen" button is pressed.

```javascript
(() => {
  const video = document.getElementById('screen-view');
  const getScreen = document.getElementById('get-screen');
  const stopScreen = document.getElementById('stop-screen');
  let stream;

  // Fill in the rest here

  stopScreen.addEventListener('click', event => {
    stream.getTracks().forEach(track => track.stop());
    video.src = '';
    stopScreen.style.display = 'none';
    getScreen.style.display = 'inline';
  });
})();
```

Now, when a user clicks on the "Get screen" button we'll work out whether they want to share the screen, window, or application and then pass that to `getUserMedia`.

```javascript
  let stream;

  getScreen.addEventListener('click', event => {
    const mediaSource = document.querySelector('[name=capture]:checked').value;
    navigator.mediaDevices
      .getUserMedia({
        video: {
          mediaSource: mediaSource
        }
      });

  stopScreen.addEventListener('click', event => {
```

Once we have access to the stream, we set it to the `src` of the video object, hide the get screen button, and show the stop screen button. If there's an error we can log that in the `catch` function.

```javascript
    navigator.mediaDevices
      .getUserMedia({
        video: {
          mediaSource: mediaSource
        }
      })
      .then(returnedStream => {
        stream = returnedStream;
        video.src = URL.createObjectURL(stream);
        getScreen.style.display = 'none';
        stopScreen.style.display = 'inline';
      })
      .catch(err => {
        console.error('Could not get stream: ', err);
      });
  });
```

And that is all the code we need! Let's see it in action.

## Capture the screen

To run this example we need to serve the HTML from a local web server. I like to do this with the npm module <a href="https://www.npmjs.com/package/servedir">servedir</a>. If you have Node.js and npm installed, you can install it with:

```bash
npm install servedir -g
```

You can then navigate using the command line to the directory you saved your `index.html` file in and serve it on localhost:8000 by entering:

```bash
serve .
```

If you have another method you use to serve static files on localhost you can use that too.

Set up your web server and open it up in Firefox. Click the "Get screen" button and…

<img alt="The browser shows an error in dev tools. 'Could not get stream'" src="https://twilioinc.wpengine.com/wp-content/uploads/2017/10/JVq-nCG0-p7v_U8jTUq64-5jHrklW6s7ROEOmOyz5l2ocSabEK9A_ptMxl8FNHlbKfdu5Ww5UOEE8Zpl32g3pIMf0Rct4r59vJTL-zYE8cidfqPPZqp2xFxK_WICYS57gHWpWNE.png" class="aligncenter">

<strong><em>Error!</em></strong>

### What went wrong?

Firefox's implementation of the `mediaDevices` API requires the site accessing screen capture to be served over HTTPS, even when served on localhost. Since we're just loading the site over a regular HTTP connection we get an error.

To workaround this locally you can generate a self signed TLS certificate and configure your local web server to use it to serve the site up over HTTPS. There's an easier solution though. I normally <a href="https://www.twilio.com/blog/2015/09/6-awesome-reasons-to-use-ngrok-when-testing-webhooks.html">like to use ngrok for testing webhooks locally</a>, but it can also give you an HTTPS URL with which to test your application.

Spin up ngrok for the port you are serving the HTML

```bash
ngrok http 8000
```

Grab the HTTPS URL and enter that in Firefox instead.

<img alt="A terminal window shows the ngrok dashboard. There are two URLs that can be used to tunnel, but we want the one which starts 'https'." src="https://twilioinc.wpengine.com/wp-content/uploads/2017/10/tyeZ426JDanyRT4_ZDm4mu251JlPldQc7DEzSOlCHjERV49zje46e8M3gHDiyW7YS-Xz__y6RUmISklFCXOJBUIbnnK7n3b1RjuEmT0syEtOKQv3J805Q1rsdt9Py0iqvn_hHzw.png" class="aligncenter">

Now press the "Get screen" button and you'll be able to give access to screen and see it in the `<video>` element on the page. You can also explore the results that "screen", "window" and "application" give you when selecting the media you want to capture.

<img alt="An animation showing the final product of this tutorial. Clicking on a start screen button initiates the screen capture permissions in Firefox, when the screen is chosen to be shared it is then visible in a video on the web page." src="https://twilioinc.wpengine.com/wp-content/uploads/2017/10/35W6m2ZumESuVdSSLjXF98mQa9KlVsOvsyE3ngL-u1B6sVtl-3PH75BOseLm0kkVbpT84xbsvYYuNDQNxXr122iHi4cXYuHX-QhVQQecmksKTvlE94YIrWgn6ZgRSCq3KcmNwwM.png" class="aligncenter">

## Next steps

Now we've seen screen capture in both Chrome and Firefox. <a href="https://github.com/philnash/screen-capture">If you want the code for both, check out the GitHub repo</a>.

Next up, we'll look at using what we've seen in these two blog posts to provide a single method of accessing screen capture across both browsers and finally wrap up with a screen sharing application using <a href="https://www.twilio.com/docs/api/video">Twilio Video</a>.

Do you have an interesting use case for screen capture in browsers? Drop your ideas or any questions in the comments below. Or feel free to reach out on Twitter at <a href="https://www.twitter.com/philnash">@philnash</a> or by email at <a class="c3" href="mailto:philnash@twilio.com">philnash@twilio.com</a>.

___

_[Screen Capture in Firefox](https://www.twilio.com/blog/2017/10/screen-capture-in-firefox.html) was originally published on the [Twilio blog](https://www.twilio.com/blog) on October 25, 2017._