在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>