5

Since Apple's iOS 11 webRTC and getUserMedia introduction, I'm able to get the camera's input to the <video> element, but can't use conventional methods to set its dimensions (height and width).

This works:

var constraints = {
    audio: false,
    video: { facingMode: 'user' }
};

navigator.mediaDevices.getUserMedia(constraints).then(
    function success(stream) {
         video.srcObject = stream;
    }
);

This doesn't work (only on iOS), and no image is shown:

var constraints = {
    audio: false,
    video: { facingMode: 'user', width: 306, height: 180 }
};

navigator.mediaDevices.getUserMedia(constraints).then(
    function success(stream) {
         video.srcObject = stream;
    }
);

The error message from catch:

Invalid constraint


Failed attempts: setting mandatory, ideal, minHeight etc.


Is this a bug? Are there any known alternatives?

Koby Douek
  • 16,156
  • 19
  • 74
  • 103

1 Answers1

3

This looks like a bug in Safari. Bare values like width: 306 are supposed to mean ideal, but Safari appears to treat them like exact, and fails with an error unless it exactly matches a driver resolution offered by the user's camera.

Except for that, Safari appears to work like other browsers like Firefox and Edge, where the goal is to find best-match native resolutions offered by the camera.

So stick to ranges until Safari fixes this.

navigator.mediaDevices.getUserMedia({video: {width: {min: 320, max: 640}}})

...or use common values with a fallback strategy:

try {
  await navigator.mediaDevices.getUserMedia({video: {width: 320}})
} catch(e) {
  await navigator.mediaDevices.getUserMedia({video: {width: 640}})
}
jib
  • 40,579
  • 17
  • 100
  • 158