HTML5 & javascript - 从支持多摄像头的设备拍照
HTML5 & javascript - taking pictures from a device supporting multiple cameras
我正在开发一个基于 Vuejs 的 PWA。我已经实现了一个组件来使用设备内置相机拍照。正在使用
-
navigator.mediaDevices.getUserMedia
API 带有 video
元素以显示来自相机的流。
- a
canva
及其 getContext("2d").drawImage
方法从流中获取图片并将其显示给用户
-
navigator.mediaDevices.enumerateDevices
API 获取可用摄像机列表和 getUserMedia
的约束参数在这些之间切换。
这一切都很好:)
但现在我偶然发现了一个新问题:一些最近的智能手机有多个后置摄像头,内置的摄像头软件可以组合起来只拍一张(一个摄像头擅长低曝光,另一个擅长高曝光)曝光和在其他一些条件下的另一个,等等)。在这种情况下,我的应用程序将显示所有摄像头并让用户独立使用它们。预期的行为是像内置软件一样将它们组合起来。这怎么可能?
在尝试了具有 1 个(正面)、2 个(背面和正面)和多个摄像头传感器(1 个正面,多个背面)的多个设备后,我的解决方案包括使用 [= 的标签 属性 11=] 由 mediaDevices.enumerateDevices()
:
返回的对象
- 如果包含'front'就是前置摄像头
- 如果包含 'back' 则为后置摄像头
- 如果它包含多个前置摄像头 and/or 后置摄像头,则标签包含“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];
}
}
}
我正在开发一个基于 Vuejs 的 PWA。我已经实现了一个组件来使用设备内置相机拍照。正在使用
-
navigator.mediaDevices.getUserMedia
API 带有video
元素以显示来自相机的流。 - a
canva
及其getContext("2d").drawImage
方法从流中获取图片并将其显示给用户 -
navigator.mediaDevices.enumerateDevices
API 获取可用摄像机列表和getUserMedia
的约束参数在这些之间切换。
这一切都很好:)
但现在我偶然发现了一个新问题:一些最近的智能手机有多个后置摄像头,内置的摄像头软件可以组合起来只拍一张(一个摄像头擅长低曝光,另一个擅长高曝光)曝光和在其他一些条件下的另一个,等等)。在这种情况下,我的应用程序将显示所有摄像头并让用户独立使用它们。预期的行为是像内置软件一样将它们组合起来。这怎么可能?
在尝试了具有 1 个(正面)、2 个(背面和正面)和多个摄像头传感器(1 个正面,多个背面)的多个设备后,我的解决方案包括使用 [= 的标签 属性 11=] 由 mediaDevices.enumerateDevices()
:
- 如果包含'front'就是前置摄像头
- 如果包含 'back' 则为后置摄像头
- 如果它包含多个前置摄像头 and/or 后置摄像头,则标签包含“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];
}
}
}