【问题标题】:HTML5 & javascript - taking pictures from a device supporting multiple camerasHTML5 & javascript - 从支持多个摄像头的设备拍照
【发布时间】:2021-11-11 10:15:38
【问题描述】:
我正在开发一个基于 Vuejs 的 PWA。我已经实现了一个使用设备内置相机拍照的组件。它正在使用
- 带有
video 元素的navigator.mediaDevices.getUserMedia API 用于显示来自摄像头的流。
-
canva 及其 getContext("2d").drawImage 方法从流中获取图片并将其显示给用户
-
navigator.mediaDevices.enumerateDevices API 获取可用摄像机列表和getUserMedia 的约束参数以在这些之间切换。
这一切都很好:)
但现在我偶然发现了一个新问题:最近的一些智能手机有多个后置摄像头,内置的摄像头软件将它们组合起来只能拍摄一张照片(一个摄像头擅长低曝光,另一个摄像头擅长高曝光和在其他一些条件下还有另一个,等等)。在这种情况下,我的应用程序将显示所有相机,并让用户独立使用它们。预期的行为是像内置软件一样组合它们。这怎么可能?
【问题讨论】:
标签:
javascript
html5-video
【解决方案1】:
在尝试了具有 1 个(正面)、2 个(背面和正面)和多个摄像头传感器(1 个正面、多个背面)的多个设备后,我的解决方案包括使用由 @987654322 返回的 MediaDeviceInfo 对象的标签属性@:
- 如果包含“front”,则为前置摄像头
- 如果包含“后退”,则为后置摄像头
- 如果它包含多个前置摄像头和/或后置摄像头,则标签包含“0”的那个是其他摄像头的组合。此外,列表中的第一个似乎总是前置摄像头,最后一个是组合后置摄像头。
然后我的代码获取前置摄像头和组合后置摄像头的 id 如下(假设始终只有一个前置摄像头):
return navigator.mediaDevices.enumerateDevices()
.then(mediaDevices => {
let cameras = mediaDevices.filter(mediaDevice => mediaDevice.kind === 'videoinput');
console.log("#potential camera=" + cameras.length);
if(cameras.length<=2)
return cameras.map(x => x.deviceId);
else {
let front = cameras.find(x => x.label.match(/\bfront\b/));
let back = cameras.filter(x => x.label.match(/\bback\b/) && x.label.match(/\b0\b/))
if(!front || back.length!=1) {
console.log("no clear front and back, taking first and last one - cameras=", cameras);
return [cameras[0].deviceId, cameras[cameras.length-1].deviceId];
}
else {
console.log("clear front and back");
return [front.deviceId, back[0].deviceId];
}
}
}