之前小沃有给大家介绍过,通过html5技术打开摄像头,并且在video标签中使用的案例。目前小沃由于案子需要,需要一台电脑中使用双摄像头,原来的方法明显无法使用到这个上面。因此小沃经过潜心研究,终于发现了如何通过html5技术选择摄像头的方法。
这里,小沃就介绍一下小沃是如何发现这个方法的。
一、认真读一下之前的核心方法navigator.mediaDevices.getUserMedia
它的官方说明文档在这里,这个方法的第一个参数是一个MediaStreamConstraints对象,其中包括我们最熟悉的{ audio: true, video: true },但是根据看文章,这里其实还可以带有其他更多参数,那么这里的参数中是否有可以区分打开不同camera的参数呢?
首先,我们打开看一下MediaStreamConstraints对象具体是个什么东西。传送门
根据文档,这个对象的参数一共有三个video、audio、peerIdentity,其中peerIdentity是一个Security参数,目前不是我们分析的重点,重点看video参数,它的类型是一个Boolean类型或是一个MediaTrackConstraints对象类型。
Boolean类型就是我们一直在使用的true,那么如果它是一个MediaTrackConstraints对象类型,是否有可能送进去更多的参数呢?当我看到这里后,开始起了这样的怀疑。
因此我有看了下MediaTrackConstraints对象的官方说明。传送门
所有的对象都有的属性
deviceId、groupId
音频对象才有的属性
autoGainControl、channelCount、echoCancellation、latency、noiseSuppression、sampleRate、sampleSize、volume
视频对象才有的属性
aspectRatio、facingMode、frameRate、height、width
当我看到deviceId时,我兴奋了。
根据程序员的直觉,这个对象就是选择不同的设备的。
而deviceId是一个ConstrainDOMString对象,所以我又看了下这个对象的说明。传送门
它只有两个属性,exact和ideal。通过读文档,最后确认了,就是要将camera对应的deviceid送给exact这里,就能成功切换摄像头了。
那么,第二个问题,如何分别获得不同的camera的deviceId呢?
这就涉及到navigator.mediaDevices的另一个方法,navigator.mediaDevices.enumerateDevices了。传送门
然后,看一下官方提供的这个方法的案例
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
console.log("enumerateDevices() not supported.");
return;
}
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices().then(function(devices) {
devices.forEach(function(device) {
console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
});
}).catch(function(err) {
console.log(err.name + ": " + err.message);
});写到这里,小沃应该也就不需要再说什么了,上面的案例中很明显的出现了device.deviceId这个参数。
只要找准对应的camera,获取其对应的deviceId,然后送给MediaTrackConstraints即可。
下面是小沃写的一段代码,供大家学习使用。
var i = 0;
var video = document.getElementById("video");
var img = document.getElementById("img");
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var videoarr = new Array();
canvas.width = 360;
canvas.height = 240;
navigator.mediaDevices.enumerateDevices().then(function(devices) {
devices.forEach(function(device) {
if(device.kind == "videoinput") {
//console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
videoarr.push(device.deviceId);
}
});
console.log(videoarr);
navigator.mediaDevices.getUserMedia({"video":{ deviceId: {exact: videoarr[0]}}}).then(function(stream) {// videoarr[0]是一个摄像头,videoarr[1]是另一个摄像头
var URL = window.URL || window.webkitURL;
video.src = URL.createObjectURL(stream);
video.play();
}).catch(function(err) {
console.log("当前电脑没有摄像头");
alert("当前电脑没有摄像头");
});
}).catch(function(err) {
console.log(err.name + ": " + err.message);
});
function paizhao() {
context.drawImage(video, 0, 0, canvas.width, canvas.height);
img.src = canvas.toDataURL("image/jpeg");
}