Javascript 使用navigate.getUserMedia()时选择相机
我正在使用navigate.getUserMedia()方法在手机上捕获视频并对其进行进一步处理。但到目前为止,它正在使用前置摄像头拍摄视频。如何进入后向摄像头 下面是我在应用程序中使用的一些示例代码:Javascript 使用navigate.getUserMedia()时选择相机,javascript,html,html5-video,video-processing,navigator,Javascript,Html,Html5 Video,Video Processing,Navigator,我正在使用navigate.getUserMedia()方法在手机上捕获视频并对其进行进一步处理。但到目前为止,它正在使用前置摄像头拍摄视频。如何进入后向摄像头 下面是我在应用程序中使用的一些示例代码: navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; if (navigator.getUserMedia){ navigator.getUserMedia({video:
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
if (navigator.getUserMedia){
navigator.getUserMedia({video: true}, successCallback, errorCallback);
提前感谢有关更多信息,请参阅
使用哪个摄像头由设备决定:“用户代理是
鼓励默认使用用户的主默认值或系统默认值
摄像机和/或麦克风(视情况而定)生成媒体
小溪。”
您可能想问的问题是如何更改默认相机。但正如我在评论部分所提到的,根据所使用的设备操作系统、供应商甚至型号,这是不同的,这可能是一个大问题
编辑(根据后面的答案改进已接受的答案):
有关如何更改相机源,请参阅本博客:
siml.info上的这个示例演示了如何使用
MediaStreamTrack.getSources
从多个视频源中进行选择
我可以确认这在Chrome 32上可以正常工作。您可以使用
facingMode
分别为前后摄像头选择“用户”或“环境”。不确定是否支持浏览器,但它可以在Android Chrome 58上运行
//----------------------------------------------------------------------
// 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));
使用
或者,允许回退到其他摄像机
navigator.getUserMedia({video: { facingMode: "environment" } },
successCallback, errorCallback);
而不是
navigator.getUserMedia({video: true}, successCallback, errorCallback);
从长话短说:
如果要在不支持facingMode约束的旧设备上选择后置摄像头,则需要在视频:{}配置中使用sourceId:{exact:device.id}
constraint
长:
export interface SourceInfo {
facing: string; // "environment"
id: string; // "bcb8d32aebb99fdf1d5f2fdb4ec4ec28a381b83f5e3c96cbcb30c4ab757380da"
kind: string; // "video"
label: string; // ""
}
代码(打字脚本):
(导航器,如有)。getUserMedia=
(导航器,如有)。getUserMedia||
(导航器,如有)。webkitGetUserMedia||
(导航器,如有)。mozGetUserMedia||
(导航器,如有)。msGetUserMedia;
if(navigator.getUserMedia&&(任何窗口).MediaStreamTrack){
(MediaStreamTrack,如有)。getSources((源代码:SourceInfo[])=>{
this.videoSources=sources.filter((source:SourceInfo)=>{
返回source.kind==='video';
//或source.facing==“环境”
});
//log('got video sources',this.videoSources);
试一试{
const rearCameraDevice=this.videoSources.find((设备:SourceInfo)=>device.faceting==='environment');
const anyCameraDevice=this.videoSources[0];
常量约束={
视频:{
强制性:{
sourceId:rearCameraDevice.id | | anyCameraDevice.id
}
//这两个都不适用于旧的约束…这是新的语法
//deviceId:此.videoSources[0].id
//deviceId:{exact:this.videoSources[0].id}
}
};
navigator.getUserMedia(
制约因素,
this.successOldStream.bind(this),
this.errorOldStream.bind(this)
);
}捕获(错误){
控制台错误(error);
}
});
}否则{
控制台。错误('您的浏览器不支持摄像头/媒体捕获')
}
我认为这个问题太笼统了,它可能取决于设备的供应商、软件和型号。但是这个代码可以在各种平台上运行,。。问题是它可以访问前摄像头,所以我们可以通过某种方式指定它访问后摄像头,。。或者得到一个可用相机的弹出窗口,让用户从中选择。这应该是正确的答案。虽然不是在所有设备上都实现,但我可以确认它在android上的chrome浏览器中工作,而不是在常规浏览器中,尽管在我的gs2上(我知道它的旧版本)。在ios7中不起作用,但我周一一到办公室就会在ios8 beta 3上测试。它没有解决我的问题,因为它在iOS safari上不起作用。两个摄像头都激活了我的前摄像头如果你描述一下你的代码,这将是一个更好的答案!我将在这里解释一些台词。videoDevices:是一个简单的数组,其中包含前后摄像头的id。devices.forEach:将列出所有媒体设备(视频和音频)。如果device.kind==“videoinput”,则表示它是视频媒体设备,我们将所有视频设备的ID保存在以前的阵列videoDevices中。var CONTAINTS包含视频分辨率和我们要启动的摄像头。videoDevices[1]=后摄像头和videoDevices[0]=前摄像头。然后我们将约束传递给getUSerMedia函数。这个答案太棒了!但是,它是否可以跨平台工作
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')
}