javascriptioswebrtcgetusermedia

How to change dimensions with getUserMedia on iOS?


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?


Solution

  • 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}})
    }