HTML5調用攝像頭demo和踩坑記錄

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章