在使用 navigate.getUserMedia() 时选择相机
Posted
技术标签:
【中文标题】在使用 navigate.getUserMedia() 时选择相机【英文标题】:Select the camera while using navigate.getUserMedia() 【发布时间】:2013-05-24 07:33:06 【问题描述】:我正在使用 navigate.getUserMedia() 方法在我的手机上捕获视频并对其进行进一步处理。但截至目前,它正在使用前置摄像头捕捉视频。如何让它访问后置摄像头??
以下是我在应用程序中使用的一些示例代码:
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
if (navigator.getUserMedia)
navigator.getUserMedia(video: true, successCallback, errorCallback);
提前致谢
【问题讨论】:
我觉得这个问题太笼统了,可能取决于设备的供应商、软件和型号。 但是这段代码在各种平台上运行,..问题是它访问前置摄像头,所以我们可能有一些方法可以指定它访问后置摄像头,..或者弹出一个可用的相机并让用户从中选择.. 【参考方案1】:simpl.info 上的这个示例演示了如何使用 MediaStreamTrack.getSources
从多个视频源中进行选择。
https://simpl.info/getusermedia/sources/
我可以确认这在 Chrome 32 中有效。
【讨论】:
这应该是正确的答案。虽然没有在所有设备上实现,但我可以确认它可以在 android 上的 chrome 中运行,而不是在我的 gs2 上的常规浏览器中(我知道它是旧的)。在 ios7 中不起作用,但我将在周一到达办公室后立即在 ios8 beta 3 上进行测试。 好吧,它并没有解决我的问题,因为它不适用于 iOS Safari。两个摄像头都激活了我的前置摄像头【参考方案2】:您可以使用facingMode
分别为前置或后置摄像头选择“用户”或“环境”。不确定浏览器是否支持,但它适用于 Android Chrome 58。
使用
navigator.getUserMedia(video: facingMode: exact: "environment" ,
successCallback, errorCallback);
或者,允许回退到其他相机
navigator.getUserMedia(video: facingMode: "environment" ,
successCallback, errorCallback);
而不是
navigator.getUserMedia(video: true, successCallback, errorCallback);
来自https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
【讨论】:
感谢这个答案!但是它会在跨平台上工作吗【参考方案3】://----------------------------------------------------------------------
// Here we list all media devices, in order to choose between
// the front and the back camera.
// videoDevices[0] : Front Camera
// videoDevices[1] : Back Camera
// I used an array to save the devices ID
// which i get using devices.forEach()
// Then set the video resolution.
//----------------------------------------------------------------------
navigator.mediaDevices.enumerateDevices()
.then(devices =>
var videoDevices = [0,0];
var videoDeviceIndex = 0;
devices.forEach(function(device)
console.log(device.kind + ": " + device.label +
" id = " + device.deviceId);
if (device.kind == "videoinput")
videoDevices[videoDeviceIndex++] = device.deviceId;
);
var constraints = width: min: 1024, ideal: 1280, max: 1920 ,
height: min: 776, ideal: 720, max: 1080 ,
deviceId: exact: videoDevices[1]
;
return navigator.mediaDevices.getUserMedia( video: constraints );
)
.then(stream =>
if (window.webkitURL)
video.src = window.webkitURL.createObjectURL(stream);
localMediaStream = stream;
else if (video.mozSrcObject !== undefined)
video.mozSrcObject = stream;
else if (video.srcObject !== undefined)
video.srcObject = stream;
else
video.src = stream;
)
.catch(e => console.error(e));
【讨论】:
如果您在那里描述您的代码,这将是一个更好的答案! 我将在这里解释一些行。 videoDevices : 是一个简单的数组,其中将包含 frond 和后置摄像头的 id。 devices.forEach :将列出所有媒体设备(视频和音频)。如果一个device.kind == "videoinput",表示它是一个视频媒体设备,我们将所有视频设备的ID保存在前面的数组videoDevices中。 var constraints 包含视频分辨率和我们想要启动的相机。 videoDevices[1] = 后置摄像头 和 videoDevices[0] = 前置摄像头。然后我们将约束传递给 getUSerMedia 函数。【参考方案4】:有关更多信息,请参阅this。
使用哪个摄像头留给设备:“用户代理是 鼓励默认使用用户的主要或系统默认值 摄像头和/或麦克风(视情况而定)以生成媒体 流。”
您可能想问的问题是如何更改默认摄像头。但正如我在评论部分提到的,这会根据所使用的设备操作系统、供应商甚至型号而有所不同,这可能是一个大问题。
编辑(根据后面的改进接受的答案):
请参阅此博客了解如何更改摄像头来源:
https://www.html5rocks.com/en/tutorials/getusermedia/intro/
【讨论】:
【参考方案5】:长话短说:
如果您想在 OLD 设备上选择不支持 facesMode 约束的后置摄像头 - 您需要在视频中使用 sourceId: exact: device.id
约束: config.
长:
export interface SourceInfo
facing: string; // "environment"
id: string; // "bcb8d32aebb99fdf1d5f2fdb4ec4ec28a381b83f5e3c96cbcb30c4ab757380da"
kind: string; // "video"
label: string; // ""
代码(打字稿):
(navigator as any).getUserMedia =
(navigator as any).getUserMedia ||
(navigator as any).webkitGetUserMedia ||
(navigator as any).mozGetUserMedia ||
(navigator as any).msGetUserMedia;
if (navigator.getUserMedia && (window as any).MediaStreamTrack)
(MediaStreamTrack as any).getSources((sources: SourceInfo[]) =>
this.videoSources = sources.filter((source: SourceInfo) =>
return source.kind === 'video';
// or source.facing === 'environment'
);
// console.log('got video sources', this.videoSources);
try
const rearCameraDevice = this.videoSources.find((device: SourceInfo) => device.facing === 'environment');
const anyCameraDevice = this.videoSources[0];
const constraints =
video:
mandatory:
sourceId: rearCameraDevice.id || anyCameraDevice.id
// these both not work with old constraints...it's new syntax
// deviceId: this.videoSources[0].id
// deviceId: exact: this.videoSources[0].id
;
navigator.getUserMedia(
<any>constraints,
this.successOldStream.bind(this),
this.errorOldStream.bind(this)
);
catch (error)
console.error(error);
);
else
console.error('your browser not supported camera/media capturing')
【讨论】:
以上是关于在使用 navigate.getUserMedia() 时选择相机的主要内容,如果未能解决你的问题,请参考以下文章
在哪里使用 CORBA 以及在哪里使用 SNMP 进行监控?
为啥在使用 unicode 时我不能在 :before :after 内容之后使用空格
在哪里使用 callable 以及在哪里使用 Runnable Interface?
在 Observable RxSwift 中使用 'asPromise()' 可以在 PromiseKit Promise 中使用吗?
可以在 SELECT 查询中使用 IF() 但不能在 UPDATE 中使用
使用 React,在使用 react-transition-group 时,在 StrictMode 中不推荐使用 findDOMNode 作为警告