Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript prevents me from passing the correct constraints to getUserMedia

I'm trying to get a screen to stream to my Angular 5 Electron app. I'm using the desktopCapturer provided by Electron. This is my code:

loadCurrentScreensource() {
    desktopCapturer.getSources({
        types: [
          'window',
          'screen'
        ]
     }, (error, sources) => {
        if (error) {
          throw error;
        }
        console.log('Finding screen: ' + this.selectedScreenSource);
        console.log(sources);

        for (let i = 0; i < sources.length; ++i) {
          if (sources[i].id === this.selectedScreenSource.id) {
            console.log('Found screen');

            const constraints = {
              audio: false,
              video: {
                mandatory: {
                  chromeMediaSource: 'desktop',
                  chromeMediaSourceId: sources[i].id,
                  minWidth: 1280,
                  maxWidth: 1280,
                  minHeight: 720,
                  maxHeight: 720
                }
              }
            };

            navigator.mediaDevices.getUserMedia(constraints)
              .then((stream) => this.handleStream(stream))
              .catch((e) => this.handleError(e));
            return;
          }
        }
      }
    );
}

According to the documentation here, I need to use the mandatory part of the constraints to get the correct stream. However, TypeScript gives me the error that the types of property 'video' are incompatible. If I enter the following constraints I sometimes get a stream of my webcam:

{ width: 1280, height: 720 }

The docs at mozzilla.org never mention the mandatory part, so I guess I overlooked some import or something to get getUserMedia to accept my constraints. Either that, or maybe getUserMedia has been changed, but the docs didn't?

What am I doing wrong here?

[edit]

Also, the documentation for MediaTrackConstraints does not have the mandatory, nor the chromeMediaSourceId properties. This is however, the same documentation that Electron links to.

[edit2]

I found the deviceId constraint, which I previously overlooked. When I use the following constraints, I still get the webcam stream though.

video: {
  width: 1280,
  height: 720,
  deviceId: this.selectedScreenSource.id
}
like image 772
Scuba Kay Avatar asked Dec 29 '17 17:12

Scuba Kay


People also ask

Is getUserMedia deprecated?

getUserMedia() Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes.

What is getUserMedia?

getUserMedia() method prompts the user for permission to use a media input which produces a MediaStream with tracks containing the requested types of media.

What is getDisplayMedia?

getDisplayMedia() The MediaDevices interface's getDisplayMedia() method prompts the user to select and grant permission to capture the contents of a display or portion thereof (such as a window) as a MediaStream .

What are the audio constraints in getUserMedia?

In a previous blog post we’ve focused on the audio constraints. The getUserMedia () function receives only one parameter, a MediaStreamConstraints object used to specify what kind of tracks (audio, video or both) to request, and, optionally, any requirements for each track.

What is getUserMedia TypeError in chrome?

Chrome will throw a “TypeError: Failed to execute ‘getUserMedia’ on ‘MediaDevices’: At least one of audio and video must be requested”. It’s thrown by Chrome when the user closes the privacy dialog asking for mic and webcam access.

What does “constraints could not be satisfied” mean?

The error object will also mention the constraint that could not be satisfied through the constraintName property and the message “Constraints could be not satisfied.”. Is thrown when the user denies (or has previously denied) access to the webcam or microphone.

Is the getUserMedia method available in secure contexts?

The getUserMedia() method is only available in secure contexts. A secure context is one the browser is reasonably confident contains a document which was loaded securely, using HTTPS/TLS, and has limited exposure to insecure contexts.


2 Answers

@Scuba Kay I can suggest you the workaround. You can just replace

navigator.mediaDevices.getUserMedia(constraints)

with

(<any> navigator.mediaDevices).getUserMedia(constraints)

It will work.

like image 180
Manthan Makani Avatar answered Sep 28 '22 11:09

Manthan Makani


To add a little more context about @Manthan Makani his solution, check out: https://github.com/microsoft/TypeScript/issues/22897

TS follows the latest WebRTC specification. Each browser can have differences in API as WebRTC specification is not an official standard yet.

Chrome seems to follow a deviating standard still. So it can be solved by defining mediaDevices as 'any' and define your own methods that coincide with Chrome's implementation. This will satisfy the Typescript compiler. Note: we follow Chrome's implementation specifically because Electron runs on the Chromium browser.

const mediaDevices = navigator.mediaDevices as any;
mediaDevices.getUserMedia({
    audio: false,
    video: {
        mandatory: {
            chromeMediaSource: 'desktop',
            chromeMediaSourceId: source.id,
            minWidth: 1280,
            maxWidth: 1280,
            minHeight: 720,
            maxHeight: 720
        }
    }
}).then((stream: MediaStream) => {
    // do stuff
    stream.getTracks()[0].stop();
});
like image 20
Babyburger Avatar answered Sep 28 '22 10:09

Babyburger