Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Resolution test does not use selected camera #262

Open
jlongman opened this issue Mar 28, 2018 · 3 comments · May be fixed by #278
Open

Resolution test does not use selected camera #262

jlongman opened this issue Mar 28, 2018 · 3 comments · May be fixed by #278

Comments

@jlongman
Copy link

jlongman commented Mar 28, 2018

In a system with multiple cameras (I have 5 listed) select different cameras and re-run the resolution tests. The camera used will not always be the camera selected. This does however work with the microphone.

Browsers and versions affected

Should be all - see Analysis below.
For completeness: MacOS 10.13.3, Chrome Version 65.0.3325.181 (Official Build) (64-bit).

Steps to reproduce

In a system with multiple cameras (I have 5 listed) select different cameras using the hamburger and re-run the resolution test. In my case CamTwist is the first camera listed but ManyCam Virtual Camera (or sometimes the Facetime HD Camera) was the one used. I had selected the fourth option, a Logitech Brio in this case.

This is visible by expanding a resolution test and comparing the output to the expectations, e.g.:

Check resolution 640x480
[ INFO ] cameraName: FaceTime HD Camera

Expected results

The resolution tests should be run with the camera selected in the configuration options.

Actual results

The camera used is chosen by the system and not the user.

Analysis

In testrtc-main.html there is a method which is intended to inject the settings into the GUM call:

      doGetUserMedia: function(constraints, onSuccess, onFail) {
        var self = this;
        var traceGumEvent = report.traceEventAsync('getusermedia');

        try {
          // Append the constraints with the getSource constraints.
          this.appendSourceId(this.$.audioSource.value, 'audio', constraints);
          this.appendSourceId(this.$.videoSource.value, 'video', constraints);

          traceGumEvent({'status': 'pending', 'constraints': constraints});
          // Call into getUserMedia via the polyfill (adapter.js).
          navigator.mediaDevices.getUserMedia(constraints)

In mictest.js we can see where this is called:

MicTest.prototype = {
  run: function() {
    if (typeof audioContext === 'undefined') {
      this.test.reportError('WebAudio is not supported, test cannot run.');
      this.test.done();
    } else {
      doGetUserMedia(this.constraints, this.gotStream.bind(this));
    }
  },

however in camresolutionstest.js we see this is not called:

  startGetUserMedia: function(resolution) {
    var constraints = {
      audio: false,
      video: {
        width: {exact: resolution[0]},
        height: {exact: resolution[1]}
      }
    };
    navigator.mediaDevices.getUserMedia(constraints)

the code bypasses the doGetUserMedia and call navigator.mediaDevices.getUserMedia directly, bypassing the source injection.

@jlongman
Copy link
Author

A naïve replacement of the navigator.mediaDevices.getUserMedia(constraints) with doGetUserMedia results in:

Failed to execute 'getUserMedia' on 'MediaDevices': Malformed constraint: Cannot use both optional/mandatory and specific or advanced constraints.

@streamencode
Copy link

I am also having this same issue on multiple Windows boxes, only the Default camera is used regardless of video selection.

@felixzapata
Copy link

felixzapata commented Feb 26, 2019

Maybe if you replace the current startGetUserMedia with this one:

startGetUserMedia: function(resolution) {
    var constraints = {
      audio: false,
      video: {
       deviceId: this.$.videoSource.value,
        width: { exact: resolution[0] },
        height: { exact: resolution[1] }
      }
    };
    var traceGumEvent = window.report.traceEventAsync('getusermedia');
    try {
      traceGumEvent({ status: 'pending', constraints: constraints });
      navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
        // Do not check actual video frames when more than one resolution is
        // provided.
        var cam = this.test.getDeviceName_(stream.getVideoTracks());
        traceGumEvent({ status: 'success', camera: cam });
        if(this.resolutions.length > 1) {
          this.test.reportSuccess('Supported: ' + resolution[0] + 'x' + resolution[1]);
          stream.getTracks().forEach(function(track) {
            track.stop();
          });
          this.maybeContinueGetUserMedia();
        } else {
          this.collectAndAnalyzeStats_(stream, resolution);
        }
      }.bind(this).catch(function(error) {
        traceGumEvent({ status: 'fail', error: error });
        if(this.resolutions.length > 1) {
          this.test.reportInfo(resolution[0] + 'x' + resolution[1] + ' not supported');
        } else {
          this.test.reportError('getUserMedia failed with error: ' + error.name);
        }
        this.maybeContinueGetUserMedia();
      }.bind(this));
    } catch (e) {
      console.log(e);
      traceGumEvent({ status: 'exception', error: e.message });
      return this.test.reportFatal('getUserMedia failed with exception: ' + e.message);
    }
  },

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants