demo目标:摄像头全屏,canvas能够完全截取摄像头内画面内容
<!DOCTYPE html>
<html>
<head>
<title>AR</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body{position:fixed;}
body{margin:0;padding:0;overflow:hidden;}
</style>
</head>
<body>
<video id="video"></video>
<canvas id="canvas"></canvas>
<script>
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var content = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
video.videoWidth = height;
video.videoHeight = width;
canvas.width = width;
canvas.height = height;
var deviceIds = [];
function draw(){
content.drawImage(video,0,0);
}
setInterval("draw()",5000);
function camera(constraints, success, error){
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
}
function success(stream){
video.srcObject = stream;
video.onloadedmetadata = function(e){
video.play();
}
}
function error(msg){
alert(msg.toString());
}
navigator.mediaDevices.enumerateDevices().then(gotDevices);
function gotDevices(deviceInfos){
deviceInfos.forEach(function(ele,index){
if(ele['kind'] == 'videoinput'){
deviceIds.push(ele['deviceId']);
}
})
camera({video:{facingMode:"environment",deviceId:deviceIds[1],width:height,height:width}}, success, error);
}
</script>
</body>
</html>
踩坑记录
1.video宽高设置,通常情况下,会把宽赋给宽,高赋给高,如果你这么做了,那么摄像头的成像永远是一个奇怪的比例。所以当尝试着把宽赋值给高,高赋值给宽,居然全屏了。
2.canvas千万不要尝试宽高反向赋值,宽就是宽,高就是高,这样赋值,图像才跟摄像头看到一致。
3.虽然video是全屏成像,但是还是会有画面溢出,所以使用overflow:hidden来控制溢出的画面不显示,这样摄像头看到的和canvas绘制的图像才一致。当然移动端body设置的时候会失效,所以还要加position:fixed来使之生效。
4.前置和后置选择问题,如果浏览器内核够高(安卓的Chrome for Android 59以上即可),可以直接使用facingMode来控制,user为前置,environment为后置,如果不行,只能通过
navigator.mediaDevices.enumerateDevices().then(gotDevices);
来获取设备信息,但是你却不能保证,哪个是前置,哪个是后置,最好来个切换按钮,让用户自己选择。
5.navigator.mediaDevices需在https下才会有,否则返回undefined。