如何解决iOS 11 Safari getUserMedia“无效约束”问题

17

我试图在iOS 11的Safari中运行以下代码。它应提示用户允许访问其设备相机,然后在我的<video autoplay id="video"></video>元素中显示它。然而,在iOS 11上运行时,会抛出一个OverconstrainedError

{message: "Invalid constraint", constraint: ""}
  • 代码在安卓上运行良好并成功打开相机。
  • 我尝试了多个有效配置,但都没有成功。

我知道iOS 11刚刚发布,可能是一个bug,但你有什么想法吗?其他人也遇到过这个问题吗?

代码:

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

编辑 1

我运行了 navigator.mediaDevices.getSupportedConstraints(),并返回以下结果:

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

我尝试过去掉video属性的配置,但是没有成功。


我也是,同样在iOS 11上。虽然我找到了一个相机工作的线程,但对我来说没有运气:https://dev59.com/xFcO5IYBdhLWcg3whR3M - Ivan Pandžić
尝试使用 {video: true, audio: false}。我发现 getSupportedConstraints() 返回了很多错误的结果,可以尝试使用 track.getSettings() 代替(来源)。 - octavn
3个回答

21

Safari中的无效约束错误是因为浏览器期望您传递正确的宽度之一:

  • 320
  • 640
  • 1280

高度会根据4:3(320或640)或16:9(1280)的宽高比自动计算,如果您传递了320的宽度,则视频流设置为:

  • 320x240

如果您设置了640的宽度,则视频流将设置为:

  • 640x480

如果您设置了1280的宽度,则视频流将设置为:

  • 1280x720

在任何其他情况下,您都会收到“InvalidConstrain”错误,说明宽度值无效。

此外,您可以使用最小、最大、精确或理想约束来设置宽度,请参阅MDN文档

这里有一个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>";

提示:在Chrome中,您可以设置视频流的宽度和高度,而该流将设置为这些尺寸,Firefox会执行健身距离,而Safari则期望完全匹配。


1
在iOS12上,320px对我来说不起作用(只有640和1280),我需要添加frameRate:15。多么有bug的行为! - gabn88
这是一份非常棒的信息。我想知道是否有相关文档可供参考。我知道https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices,但也许Safari有自己的文档。我还想了解其他限制条件(帧速率等)。 - Millar248
@kintaro您好。我在Safari 13中打开了您的示例,但出现了错误:无效约束。 - Pantera
嗨@Pantera,你在320上遇到了错误吗?请检查Millar248的评论,他说320在iOS12中不起作用,只有640和1280有效。 - kintaro

7

3

看起来这可能是一个被纠正的bug,因为我刚刚再试了一次,错误信息不再出现了。

需要注意的是,虽然错误信息消失了,但我还必须再做一个更改才能让它工作,即在then回调函数中添加video.srcObject = stream;


2
我在 iOS 12 上仍然遇到这个问题。 - Belladonna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接