Kay van Bree
Kay van Bree

Reputation: 2082

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
}

Upvotes: 10

Views: 4206

Answers (2)

Babyburger
Babyburger

Reputation: 1828

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();
});

Upvotes: 1

Manthan Makani
Manthan Makani

Reputation: 117

@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.

Upvotes: 8

Related Questions