html5+JS调用手机摄像头扫码

2 篇文章 0 订阅

在app项目中实现HTML5的扫描二维码,网上的搜了一大推,但是实际使用的时候发现能直接上手的并不多,所以自己百度,然后提炼了一些,下面直接上代码。

注意:
1.安卓(5.1)有些手机中测试正常,iOS暂时不行,后续再研究。
2.需要自己打包成APP,比如用Hbuilder打包,因为摄像头涉及权限问题。(demo下载

js插件链接: https://download.csdn.net/download/wys997/12876201

代码:

<!DOCTYPE html>
<head>
    <title>HTML5 GetUserMedia Demo</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    <style>
    	body {
    		text-align: center;
    		margin: 0;
    	}
    	.hide {
    		display: none;
    	}
    	.toast {
    		position: fixed;
    		bottom: 150px;
    		left: 50%;
    		background: rgba(35,35,35,0.8);
    		color: #fff;
    		padding: 5px 15px;
    		transform: translate(-50%, 50%);
    		border-radius: 5px;
    	}
    	video {
    		width: 100vw;
    	}
    </style>
</head>
<body>
<video autoplay="autoplay"></video>
<canvas id="canvas1" height="320px" class="hide"></canvas>
<img class="hide" src="" alt="" id="img" />
<div></div>
<span class="toast hide" id="toast">
	
</span>
<button id="scan">扫一扫</button>
<script src="http://www.jq22.com/demo/jQueryQrcode201709202327/analyticCode.js" type="text/javascript" charset="utf-8"></script>
<script src="http://www.jq22.com/demo/jQueryQrcode201709202327/llqrcode.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
    var video = document.querySelector('video');
    var audio, audioType;

    var canvas1 = document.getElementById('canvas1');
    var context1 = canvas1.getContext('2d');
    var stream;
    
    // 兼容不同浏览器内核
    // 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
	if (navigator.mediaDevices === undefined) {
	  navigator.mediaDevices = {};
	}
	
	// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia 
	// 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
	if (navigator.mediaDevices.getUserMedia === undefined) {
	  navigator.mediaDevices.getUserMedia = function(constraints) {
	
	    // 首先,如果有getUserMedia的话,就获得它
	    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
	
	    // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
	    if (!getUserMedia) {
	      	return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
	    }
	
	    // 否则,为老的navigator.getUserMedia方法包裹一个Promise
	    return new Promise(function(resolve, reject) {
	      	getUserMedia.call(navigator, constraints, resolve, reject);
	    });
	  }
	}

    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;

	var exArray = [];
    navigator.mediaDevices.enumerateDevices()
    .then(function(sourceInfos) {
        for (var i = 0; i != sourceInfos.length; ++i) {
            var sourceInfo = sourceInfos[i];
            //这里会遍历audio,video,所以要加以区分
            if (sourceInfo.kind === 'video') {
                exArray.push(sourceInfo.deviceId);
            }
        }
    })
	.catch(function(err) {
	  	alert(err.name + ": " + err.message);
	});

    function getMedia() {
        if (navigator.mediaDevices.getUserMedia) {
            navigator.mediaDevices.getUserMedia({
            	audio: false,
            	video: {
        			facingMode: { exact: "environment" }
        		}
            }).then(function(stream) {
			  	successFunc(stream)
			})
			.catch(function(err) {
			  	errorFunc(err)
			});
        }
        else {
            alert('Native device media streaming (getUserMedia) not supported in this browser.');
        }
    }
    // 初始就加载摄像头,不加定时会出现显示的前置摄像头(大概因为打开摄像头也要时间)
    /*setTimeout(function() {
		getMedia();
    }, 500);*/
	
    function successFunc(stream) {
        //alert('Succeed to get media!');
        if (video.mozSrcObject !== undefined) {
            //Firefox中,video.mozSrcObject最初为null,而不是未定义的,我们可以靠这个来检测Firefox的支持
            video.mozSrcObject = stream;
        }
        else {
            video.src = window.URL && window.URL.createObjectURL(stream) || stream;
        }
    }
    function errorFunc(e) {
        alert('Error!'+e);
    }

	var getImgTiming = null;
    // 将视频帧绘制到Canvas对象上,Canvas每60ms切换帧,形成肉眼视频效果
    function drawVideoAtCanvas(video,context) {
        window.setInterval(function () {
            context.drawImage(video, 0, 0,240,320);
        }, 3000);
        // 定时进行图片转换成二维码
        getImgTiming = window.setInterval(function () {
            getImg();
        }, 1000);
    }

    // vedio播放时触发,绘制vedio帧图像到canvas
	video.addEventListener('play', function () {
	    drawVideoAtCanvas(video, context1);
	}, false);
    
    // 转化图片
    function getImg() {
    	var dataURL = canvas1.toDataURL("image/png");
    	// 加载文件
    	document.getElementById('img').src = dataURL;
    	getUrl(document.getElementById('img'), 'img-url');
    }

    // 获取二维码地址
    function getUrl(e,param){
        analyticCode.getUrl(param,e,function(text,imgSrc){
        	// 判断是否解析成功
        	if (text == 'error decoding QR Code') {
        		document.getElementById('toast').innerHTML = '请对准二维码';
        		document.getElementById('toast').classList.remove('hide');
        	} else {
        		document.getElementById('toast').innerHTML = '识别成功';
        		document.getElementById('toast').classList.remove('hide');
        		// 如果成功,请求接口、取消定时解析图片
        		setTimeout(function () {
        			document.getElementById('toast').classList.add('hide');
        			clearInterval(getImgTiming);
        		}, 3000);
	            e.nextElementSibling.innerHTML = text;
	            e.previousElementSibling.src = imgSrc;
        	}
        });
    }
    
    // 点击扫一扫
    document.getElementById('scan').onclick = function() {
    	getMedia();
    };
</script>
</body>


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值