在 Android 设备上选择后置摄像头 - jsartoolkit5

Posted

技术标签:

【中文标题】在 Android 设备上选择后置摄像头 - jsartoolkit5【英文标题】:Select rear camera on Android device - jsartoolkit5 【发布时间】:2017-06-03 03:13:07 【问题描述】:

我正在构建一个类似于this example 和jsartoolkit5 的项目,我希望能够选择我设备的后置摄像头,而不是让android 上的Chrome 默认选择前置摄像头。

根据demo 中的示例,如果设备有后置摄像头,我添加了以下代码以自动切换摄像头。

var videoElement = document.querySelector('canvas');
function successCallback(stream) 
  window.stream = stream; // make stream available to console
  videoElement.src = window.URL.createObjectURL(stream);
  videoElement.play();


function errorCallback(error) 
  console.log('navigator.getUserMedia error: ', error);


navigator.mediaDevices.enumerateDevices().then(
  function(devices) 
    for (var i = 0; i < devices.length; i++) 
      if (devices[i].kind == 'videoinput' && devices[i].label.indexOf('back') !== -1) 
        if (window.stream) 
          videoElement.src = null;
          window.stream.stop();
        
        var constraints = 
          video: 
            optional: [
              sourceId: devices[i].deviceId
            ]
          
        ;
        navigator.getUserMedia(constraints, successCallback, errorCallback);
      
    
  
); 

问题在于它非常适合&lt;video&gt; 标签,但不幸的是jsartoolkit 将内容呈现在canvas 中,因此会引发错误。 我也尝试按照 Github 存储库中 this 已关闭问题中的说明进行操作,但这次我收到以下错误:DOMException: play() can only be initiated by a user gesture

您知道或对如何解决此问题有任何建议吗?

提前感谢您的回复!

【问题讨论】:

100% 工作解决方案。见***.com/a/53371645/9222769***.com/a/53371634/9222769 【参考方案1】:

主要问题:

您正在混合新旧 getUserMedia 语法。navigator.getUserMedia 已被弃用,navigator.mediaDevices.getUserMedia 应该是首选。 另外,我认为optional 不再是约束字典的一部分。

默认解决方案

这部分几乎是这个答案的副本:https://***.com/a/32364912/3702797

你应该可以直接调用

navigator.mediaDevices.getUserMedia(
  video: 
    facingMode: 
      exact: 'environment'
      
    
  )

但是 chrome 仍然有 this bug,即使 @jib 的回答指出它应该与 adpater.js polyfill 一起使用,我自己也无法让它在我的 Android 版 chrome 上运行。

因此,之前的语法目前仅适用于 Firefox for Android。

对于 chrome,您确实需要使用 enumerateDevices 以及 adapter.js 才能使其工作,但不要混淆语法,一切都应该没问题:

let handleStream = s => 
  document.body.append(
    Object.assign(document.createElement('video'), 
      autoplay: true,
      srcObject: s
    )
  );


navigator.mediaDevices.enumerateDevices().then(devices => 
  let sourceId = null;
  // enumerate all devices
  for (var device of devices) 
    // if there is still no video input, or if this is the rear camera
    if (device.kind == 'videoinput' &&
        (!sourceId || device.label.indexOf('back') !== -1)) 
      sourceId = device.deviceId;
    
  
  // we didn't find any video input
  if (!sourceId) 
    throw 'no video input';
  
  let constraints = 
    video: 
      sourceId: sourceId
    
  ;
  navigator.mediaDevices.getUserMedia(constraints)
    .then(handleStream);
);
&lt;script src="https://webrtc.github.io/adapter/adapter-latest.js"&gt;&lt;/script&gt;

Fiddle for chrome需要https。

让它与jsartoolkit一起工作

您必须 fork jsartoolkit 项目并编辑 artoolkit.api.js

主项目当前禁用了mediaDevices.getUserMedia(),因此您需要再次启用它,并且您还必须添加一个检查sourceId 选项,我们稍后会在ARController.getUserMediaThreeScene() 中添加该选项打电话。

您可以在this fork 中找到这些编辑的粗略和丑陋的实现。

所以一旦完成,你必须重新构建 js 文件,然后记得在你的代码中包含 adapter.js polyfill。

Here is a working fiddle 使用该项目的演示之一。

【讨论】:

感谢您的回复@Kaiido,小提琴适用于Android!我的代码仍有一些问题,你可以在这个小提琴中找到:jsfiddle.net/yw7ksv92(但它不能正常工作)。我试图在我的代码和本机库中插入你的小提琴,但在运行它时我仍然看到前置摄像头。你知道可能是什么问题吗? @d_z90,在快速阅读 jsARtoolkit 源代码后,,您需要 fork 库...特别是在 this line 附近,您需要在 @ 旁边添加一些内容987654339@。但似乎他们确实用 if(false) 阻止了 navigator.mediaDevices.getUserMedia 调用,只使用旧语法,这看起来很奇怪......我怀疑他们还没有更新他们的 Promises 代码......我可能有更深入的了解接下来几天。 @d_z90,我做了一个丑陋的项目分支。您可能可以从那里工作。

以上是关于在 Android 设备上选择后置摄像头 - jsartoolkit5的主要内容,如果未能解决你的问题,请参考以下文章

在 iPhone 5 上选择后置麦克风

无法在 IOS 和 Android 移动设备上选择文件

如果用户在其设备上选择了省电位置模式,是不是可以在 Android 上获得高精度的位置更新?

在移动设备上选择文本时覆盖本机行为

在三星 Galaxy 设备上选择图像会旋转

如何创建具有多个后置摄像头的 android 模拟器