思路
第一步: 要能调起设备摄像头
第二步:扫码
第三步:解析二维码
技术简介
WebRTC API
WebRTC (Web Real-Time Communications)
是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间 点对点(Peer-to-Peer)
的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC
包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建 点对点(Peer-to-Peer)
的数据分享和电话会议成为可能。
重要接口
MediaStream
接口:是一个媒体内容的流.。一个流包含几个轨道,比如视频和音频轨道。
MDN : WebRTC API
核心的API navigator.mediaDevices.getUserMedia
MediaDevices
接口提供访问连接媒体输入的设备,如照相机和麦克风,以及屏幕共享等。它可以使你取得任何硬件资源的媒体数据。
MediaDevices.getUserMedia()
会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其它轨道类型。
它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream
对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise会reject回调一个 PermissionDeniedError
或者 NotFoundError
。
通常你可以使用 navigator.mediaDevices
来获取 MediaDevices
,例如:
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
/* 使用这个 stream stream */
})
.catch(function(err) {
/* 处理 error */
});
语法
var promise = navigator.mediaDevices.getUserMedia(constraints);
以下同时请求不带任何参数的音频和视频:
MDN: MediaDevices
二维码解析库 JSQR
jsQR 是一个纯 JavaScript 二维码解析库,该库读取原始图像或者是摄像头,并将定位,提取和解析其中的任何 QR码。
如果要使用 jsQR 扫描网络摄像头流,则需要 ImageData 从视频流中提取,然后可以将其传递给 jsQR。
jsQR 导出一个方法,该方法接受 4 个参数,分别是解码的 图像数据,宽、高 以及 可选的对象 进一步配置扫描行为。
imageData:格式为 [r0, g0, b0, a0, r1, g1, b1, a1, …] 的 Uint8ClampedArray( 8位无符号整型固定数组) 的 rgba 像素值。
const code = jsQR(imageData, width, height, options);
if (code) {
console.log('找到二维码!', code);
}
github:jsQR
requestAnimationFrame
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行.
window.requestAnimationFrame(callback);
MDN: requestAnimationFrame
代码实现
流程: 浏览器进行调取摄像头,调用失败执行失败的回调;调用成功,进行捕获视频流,然后扫码识别,没有扫描到二维码就继续扫描, 扫码成功之后弹出扫码内容, 并停止扫码。
初始化
<div></div>
<video src="" style="display: none"></video>
<canvas></canvas>
// 捕获视频流
var promise = navigator.mediaDevices.getUserMedia({ video: true })
promise.then((mediaStream) => {
// 成功的返回值mediaStream,既是媒体内容的流。
// 通过原生video标签,展示视频
document.querySelector('video').srcObject = mediaStream
document.querySelector('video').play()
// 调用tick之前, 这个时候已经可以看到页面上在展示我们录制到的内容
tick()
}).catch(function (err) {
console.log(err, 'err')
})
// tick方法,初始化canvas,调用jsQR识别二维码
function tick() {
let cvs = document.querySelector('canvas')
var ctx = cvs.getContext('2d')
cvs.width = '800'
cvs.height = '600'
// 通过canvas绘制每一帧图片, 使绘制的图片和video展示的图片相吻合
ctx.drawImage(document.querySelector('video'), 0, 0, '800', '600')
// 获取画布数据(存储像素点信息)
const imageData = ctx.getImageData(0, 0, '800', '600')
let code = false
// jsQR 识别二维码
code = jsQR(imageData.data, imageData.width, imageData.height)
if (code) {
// 找到二维码,并展示在页面上
document.querySelector('div').innerHTML = code.data
// 绘制矩形框
drawBox(code.location)
}
// 这次没有找到二维码,调用run方法
run()
}
function run() {
if (!document.querySelector('div').innerHTML) {
// 进行周期性扫码识别
requestAnimationFrame(tick)
}
}
可以看下, 这是扫码成功的回调。location
对象里包含了二维码具体的位置, 我们可以通过canvas
划线,把页面中的码位置圈出来
function drawBox(location) {
drawLine(location.topLeftCorner, location.topRightCorner)
drawLine(location.topRightCorner, location.bottomRightCorner)
drawLine(location.bottomRightCorner, location.bottomLeftCorner)
drawLine(location.bottomLeftCorner, location.topLeftCorner)
}
function drawLine(begin, end) {
let cvs = document.querySelector('canvas')
var ctx = cvs.getContext('2d')
ctx.beginPath()
ctx.moveTo(begin.x, begin.y)
ctx.lineTo(end.x, end.y)
ctx.lineWidth = '3'
ctx.strokeStyle = 'red'
ctx.stroke()
}
最终实现效果就是这样
到这里基本上就完事了, 可以调起摄像头, 可以正确扫码并拿到对应的值。文章来源:https://www.toymoban.com/news/detail-457935.html
参考文章: https://github.com/dragonir/h5-scan-qrcode
JSQR: https://www.npmjs.com/package/jsqr
https://blog.csdn.net/weixin_41856395/article/details/120597131文章来源地址https://www.toymoban.com/news/detail-457935.html
到了这里,关于H5调用摄像头扫码详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!