(Android) / Chrome getUserMedia() 约束应该如何格式化?

Fis*_*sio 4 html android google-chrome html5-video getusermedia

我一直在尝试访问运行 Chrome 的 LG G4 Android 手机上的后置摄像头。我可以从 中过滤掉视频源MediaStreamTrack.getSources(),但是当我尝试设置约束以偏爱后置摄像头时,出现错误TypeError: Failed to execute 'webkitGetUserMedia' on 'Navigator': Malformed constraints object.下面我有我用来过滤视频源的代码:

if (navigator.getUserMedia) {
  if (MediaStreamTrack.getSources) {
    MediaStreamTrack.getSources(function(sourceInfos) {
      var sources = [];
      _.forEach(sourceInfos, function(info) {
        if (info.kind === 'video') {
          sources.push(info);
        }              
      })
      handleSources(sources);
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我试图在handleSources上面提到的函数中选择一个源:

function handleSources(sources) {
  var constraints = {
    video: {
      facingMode: 'environment' // Yeah, this definitely doesn't work.
    }
  }
  getMedia(constraints); // This calls getUserMedia with the selected contraints
}
Run Code Online (Sandbox Code Playgroud)

我已经为约束对象尝试了大量不同的格式,但它们似乎都不起作用。我知道我可以遍历所有来源并从那里选择环境相机,但我很想知道它的实际语法是如何工作的。谷歌搜索答案只会出现https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Parameters,其语法不起作用。

Joe*_*han 6

看起来好像早期/不同版本的 Android 浏览器为相机发现实现了不同的 API。我发现我可以访问的每部手机(模拟器和物理)似乎都尊重一组不同的选项。更糟糕的是,这似乎是各种文档存储库坚持忽略或删除以前实现的 API 的领域(即使我们仍然需要知道如何使用它们,如果我们能够在除最新手机之外的任何东西上实现) )。

我发现的 API 的两种主要风格是当前记录的一种(您指的是上面的 API)和一种记录在2013 年 10 月的 WebRTC 规范版本中。这种风格具有明显不同的约束规范,包括强制性和可选属性。在旧规范下,您上面对 getMedia 的调用将如下所示:

var constraints = {
  video: {
    mandatory: {
      facingMode: 'environment'
    }
  }
}
getMedia(constraints);
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用可选设置,这些设置以数组形式提供,因此您可以有多种选择(按顺序评估这些设置):

var constraints = {
  video: {
    optional: [{
      facingMode: 'environment'
    }]
  }
}
getMedia(constraints);
Run Code Online (Sandbox Code Playgroud)

话虽如此,在寻找有效的过滤器时,您的里程可能会有所不同。例如,facingMode上面的过滤器在我的 Android 5.0 模拟器中不起作用(它不会抛出错误,但也不会显示面向环境的相机);但是,使用设备 ID 确实有效(映射到您的示例时看起来像这样):

var constraints = {
  video: {
    mandatory: {
      sourceId: '<your source ID here>'
    }
  }
}
getMedia(constraints);
Run Code Online (Sandbox Code Playgroud)

在 Android 5.0 模拟设备的情况下,我已经做了一些测试,我可以MediaStreamTrack.getSources()用来找到我想要的设备(它返回facing每个相机的属性)。请注意,navigator.mediaDevices.enumerateDevices()此仿真设备中不存在“推荐的”替换方法。

在使用不同的模拟设备和物理设备时,您还会看到许多其他问题,在现实世界中实现这些 API 时,每个问题对我来说都是相当大的问题。我强烈建议使用多个物理设备的组合(如果您处于可以访问它们的工作环境中)、BrowserStack(为您提供大量真实和模拟设备以进行测试)、console.log() 和Vorlon.js(从所有这些模拟设备实时查看 console.log() 输出,以便您可以看到真正发生了什么)。

我目前正在解决这个确切的问题 - 如果我发现有关需要支持的不同 API 风格的任何其他内容,我将在此处发布更新。