17

I'm attempting to run the following code in Safari in iOS 11. It should prompt the user to give access to their devices camera and then display it in my <video autoplay id="video"></video> element. However, when running in iOS 11, it results in an OverconstrainedError to be thrown:

{message: "Invalid constraint", constraint: ""}
  • The code runs fine in Android and successfully opens the camera.
  • I've attempted multiple valid configurations with no luck.

I know iOS 11 just came out so it may be a bug, but any thoughts? Has anyone else run into this?

Code:

var video = document.getElementById('video');
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
     navigator.mediaDevices.getUserMedia({video: true})
         .then(function(stream) {
             video.src = window.URL.createObjectURL(stream);
             video.play();
         })
         .catch(function(err) {
             console.log(err);
         });
}

Edit 1

I've run navigator.mediaDevices.getSupportedConstraints() and it returns the following:

{
    aspectRatio: true,
    deviceid: true,
    echoCancellation: false,
    facingMode: true,
    frameRate: true,
    groupId: true,
    height: true,
    sampleRate: false,
    sampleSize: false,
    volume: true,
    width: true
}

I've tried configurations omitting the video property, but had no luck.

Community
  • 1
  • 1
mb-ca
  • 469
  • 1
  • 4
  • 15
  • Same here, also on iOS 11. Although I've found thread where camera was working, no luck for me: https://stackoverflow.com/questions/45692526/ios-11-getusermedia-not-working – Ivan Pandžić Nov 14 '17 at 17:45
  • Try `{video: true,audio:false}` . I've found `getSupportedConstraints()` to return a lot of false positives, try `track.getSettings()` instead ( [source](https://addpipe.com/blog/getusermedia-video-constraints/) ). – octavn Nov 29 '17 at 12:08

3 Answers3

21

The invalid constraint error in safari is because the browser expects that you pass a correct width, one of:

  • 320
  • 640
  • 1280

the height is auto calculate in an aspect ratio of 4:3 for 320 or 640, and 16:9 for 1280, then if you pass a width of 320, you video stream is set in:

  • 320x240

if you set a width of 640, you video stream is set in:

  • 640x480

And if you set a width of 1280, then you video stream is set in:

  • 1280x720

In any other case you got a error "InvalidConstrain" for width value.

Also you can use a min, max, exact or ideal constrains for width, please check the MDN documentation

Here an example in this codepen

var config = { video: { width: 320/*320-640-1280*/ } };
var start = () => navigator.mediaDevices.getUserMedia(config)
  .then(stream => v.srcObject = stream)
  .then(() => new Promise(resolve => v.onloadedmetadata = resolve))
  .then(() => log("Success: " + v.videoWidth + "x" + v.videoHeight))
  .catch(log);

var log = msg => div.innerHTML += "<p>" + msg + "</p>";

PD: In chrome you can set a width of height and the video stream is set in these sizes, Firefox do a fitness distance, and Safari expect a exact match.

kintaro
  • 2,393
  • 2
  • 16
  • 16
  • 1
    320px is not working for me on iOS12 (only 640 and 1280) and I needed to add frameRate:15. What a buggy behaviour! – gabn88 Oct 16 '18 at 16:25
  • This is a fantastic piece of information. I wonder if there is documentation on this somewhere. I know about https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices, but maybe there's one for Safari. I also wonder about the other constraints (frameRate, etc.). – Millar248 Jan 25 '19 at 15:13
  • @kintaro. Hello. I opened your example in safari 13 and I have Error: Invalid constraint – Pantera Aug 27 '19 at 07:28
  • Hi @Pantera, you got error with 320? Please check the comment of Millar248, he says that 320 is not working and only works with 640 and 1280 in iOS12 – kintaro Aug 29 '19 at 00:24
7

Remember that the iOS Simulator that comes with Xcode does not support webcam or microphone, which is why you may get the OverconstrainedError (as per https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia docs, that means no device fits the passed options, even if you're not putting specifics)

Tom Roggero
  • 5,777
  • 1
  • 32
  • 39
3

It appears to have been a bug that was corrected, because I just tried it again and the error message no longer appears.

Note that while the error message went away, I did have to make one more change for it to work, which was adding video.srcObject = stream; in the then callback.

mb-ca
  • 469
  • 1
  • 4
  • 15