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。