![](https://img2020.cnblogs.com/blog/772544/202110/772544-20211014085859146-787620276.png)
## 背景
不久前我做了关于获取浏览器摄像头并扫码识别的功能,本文中梳理了涉及到知识点及具体代码实现,整理成此篇文章内容。
本文主要介绍,通过使用基于 `vue` 技术栈的前端开发技术,在浏览器端调起摄像头 `📷`,并进行扫码识别功能,对识别到的二维码进行跳转或其他操作处理。本文内容分为背景介绍、实现效果、技术简介、代码实现、总结等部分组成。
## 实现效果
本实例中主要有两个页面首页和扫码页,具体实现效果如下图所示。
* 首页:点击 `SCAN QRCODE` 按钮,进入到扫码页。
* 扫码页:首次进入时,或弹出 `获取摄像头访问权限的系统提示框`,点击允许访问,页面开始加载摄像头数据并开始进行二维码捕获拾取,若捕获到二维码,开始进行二维码解析,解析成功后加载识别成功弹窗。
![](https://img2020.cnblogs.com/blog/772544/202110/772544-20211014085910878-405058356.gif)
> `📸` 在线体验:https://dragonir.github.io/h5-scan-qrcode
![](https://img2020.cnblogs.com/blog/772544/202110/772544-20211014085936872-953138653.png)
> `📌` 提示:需要在有摄像头设备的浏览器中竖屏访问。手机横竖屏检测小知识可前往我的另一篇文章[《五十音小游戏中的前端知识》](https://juejin.cn/post/6987393152332070920) 中进行了解。
## 技术简介
### WebRTC API
**WebRTC (Web Real-Time Communications) 是一项实时通讯技术**,它允许网络应用或者站点,在**不借助中间媒介**的情况下,建立浏览器之间 `点对点(Peer-to-Peer)` 的连接,实现视频流和(或)音频流或者其他任意数据的传输。`WebRTC` 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建 `点对点(Peer-to-Peer)` 的数据分享和电话会议成为可能。
**三个主要接口**:
* `MediaStream`:能够通过设备的摄像头及话筒获得视频、音频的同步流。
* `RTCPeerConnection`:是 `WebRTC` 用于构建点对点之间稳定、高效的流传输的组件。
* `RTCDataChannel`:使得浏览器之间建立一个高吞吐量、低延时的信道,用于传输任意数据。
> `🔗` 前往 `MDN` 深入学习:[WebRTC_API](https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API)
### WebRTC adapter
虽然 `WebRTC` 规范已经相对健全稳固了,但是并不是所有的浏览器都实现了它所有的功能,有些浏览器需要在一些或者所有的 `WebRTC API`上添加前缀才能正常使用。
`WebRTC` 组织在 `github` 上提供了一个 `WebRTC适配器(WebRTC adapter)` 来解决在不同浏览器上实现 `WebRTC` 的兼容性问题。这个适配器是一个 `JavaScript垫片`,它可以让你根据 `WebRTC` 规范描述的那样去写代码,在所有支持 `WebRTC` 的浏览器中不用去写前缀或者其他兼容性解决方法。
> `🔗` 前往 `MDN` 深入学习:[WebRTC adapter](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/adapter.js)
### 核心的API `navigator.mediaDevices.getUserMedia`
网页调用摄像头需要调用 `getUserMedia API`,`MediaDevices.getUserMedia()` 会提示用户给予使用媒体输入的许可,媒体输入会产生一个 `MediaStream`,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、`A/D转换器` 等等),也可能是其它轨道类型。
它返回一个 `Promise` 对象,成功后会 `resolve` 回调一个 `MediaStream对象`;若用户拒绝了使用权限,或者需要的媒体源不可用,`promise` 会 `reject` 回调一个 `PermissionDeniedError` 或者 `NotFoundError` 。(返回的 `promise对象` 可能既不会 `resolve` 也不会 `reject`,因为用户不是必须选择允许或拒绝。)
通常可以使用 `navigator.mediaDevices` 来获取 `MediaDevices` ,例如:
```js
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
// 使用这个stream
})
.catch(function(err) {
// 处理error
})
```
> `🔗` 前往 `MDN` 深入学习:[navigator.mediaDevices.getUserMedia](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia)
### 二维码解析库 `JSQR`
`jsQR` 是一个纯 `JavaScript` 二维码解析库,该库读取原始图像或者是摄像头,并将定位,提取和解析其中的任何 `QR码`。
如果要使用 `jsQR` 扫描网络摄像头流,则需要 `ImageData` 从视频流中提取,然后可以将其传递给 `jsQR`。
`jsQR` 导出一个方法,该方法接受 `4` 个参数,分别是解码的 `图像数据`,`宽`、`高` 以及 `可选的对象` 进一步配置扫描行为。
`imageData`:格式为 `[r0, g0, b0, a0, r1, g1, b1, a1, ...]` 的 `Uint8ClampedArray( 8位无符号整型固定数组)` 的 `rgba` 像素值。
```js
const code = jsQR(imageData, width, height, options);
if (code) {
console.log('找到二维码!', code);
}
```
> `🔗` 前往 `github` 深入了解:[jsQR](https://github.com/cozmo/jsQR)
## 代码实现
### 流程
整个扫码流程如下图所示:页面初始化,先检查浏览器是否支持 `mediaDevices` 相关`API`,浏览器进行调去摄像头,调用失败,就执行失败回调;调用成功,进行捕获视频流,然后进行扫码识别,没有扫瞄到可识别的二维码就继续扫描,扫码成功后绘制扫描成功图案并进行成功回调。
![](https://img2020.cnblogs.com/blog/772544/202110/772544-20211014085958959-714223482.png)
下文内容对流程进行拆分,分别实现对应的功能。
### 扫码组件 `Scaner`
#### 页面结构
我们先看下页面结构,主要由 `4` 部分组成:
* 提示框。
* 扫码框。
* `video`:展示摄像头捕获视频流。
* `canvas`: 绘制视频帧,用于二维码识别。
```html
<template>
<div class="scaner" ref="scaner">
<!-- 提示框:用于在不兼容的浏览器中显示提示语 -->
<div class="banner" v-if="showBanner">
<i class="close_icon" @click="() => showBanner = false"></i>
<p class="text">若当前浏览器无法扫码,请切换其他浏览器尝试</p>
</div>
<!-- 扫码框:显示扫码动画 -->
<div class="cover">
<p class="line"></p>
<span class="square top left"></span>
<span class="square top right"></span>
<span class="square bottom right"></span>
<span class="square bottom left"></span>
<p class="tips">将二维码放入框内,即可自动扫描</p>
</div>
<!-- 视频流显示 -->
<video
v-show="showPlay"
class="source"
ref="video"
:width="videoWH.width"
:height="videoWH.height"
controls
></video>
<canvas v-show="!showPlay" ref="canvas" />
<button v-show="showPlay" @click="run">开始</button>
</div>
</template>
```
#### 方法:绘制
* 画线。
* 画框(用于扫码成功后绘制矩形图形)。
![](https://img2020.cnblogs.com/blog/772544/202110/772544-20211014090011600-1539245730.png)
```js
// 画线
drawLine (begin, end) {
this.canvas.beginPath();
this.canvas.moveTo(begin.x, begin.y);
this.canvas.lineTo(end.x, end.y);
this.canvas.lineWidth = this.lineWidth;
this.canvas.strokeStyle = this.lineColor;
this.canvas.stroke();
},
// 画框
drawBox (location) {
if (this.drawOnfound) {
this.drawLine(location.topLeftCorner, location.topRightCorner);
this.drawLine(location.
没有合适的资源?快使用搜索试试~ 我知道了~
vue2 扫码获取二维码内容
共94个文件
png:17个
sample:13个
js:12个
需积分: 50 6 下载量 38 浏览量
2022-07-28
10:23:12
上传
评论 2
收藏 18.65MB ZIP 举报
温馨提示
扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码获取二维码内容扫码扫码扫码
资源详情
资源评论
资源推荐
收起资源包目录
扫码.zip (94个子文件)
扫码
images
landscape.png 248KB
docs
css
Home.5f7c86c2.css 1KB
Scan.cc5e7f39.css 3KB
app.7c140b88.css 138B
favicon.png 157KB
landscape.png 140KB
img
bg.139a02de.png 165KB
button.b9b80257.png 12KB
_config.yml 0B
index.html 2KB
js
chunk-vendors.06d24464.js 122KB
Home.84a28d29.js 781B
app.2cac13a9.js 4KB
Scan.dc211281.js 212KB
vue.config.js 72B
package.json 1KB
.git
index 4KB
hooks
fsmonitor-watchman.sample 5KB
post-update 858B
pre-push.sample 1KB
prepare-commit-msg.sample 1KB
pre-merge-commit.sample 416B
pre-applypatch 870B
commit-msg 854B
post-applypatch 874B
post-checkout 866B
pre-rebase 854B
pre-push 846B
push-to-checkout 878B
applypatch-msg.sample 478B
post-merge 854B
update 838B
pre-commit.sample 2KB
sendemail-validate 886B
post-commit 858B
prepare-commit-msg 913B
pre-receive.sample 544B
pre-applypatch.sample 424B
commit-msg.sample 896B
pre-rebase.sample 5KB
post-rewrite 862B
update.sample 4KB
post-update.sample 189B
post-receive 862B
applypatch-msg 870B
pre-commit 854B
pre-auto-gc 858B
push-to-checkout.sample 3KB
pre-receive 858B
config 309B
description 73B
refs
tags
heads
master 41B
remotes
origin
HEAD 32B
logs
refs
heads
master 182B
remotes
origin
HEAD 182B
HEAD 182B
packed-refs 114B
objects
info
pack
pack-500749fc65e5002441bed312a1771709b265ba15.pack 16.22MB
pack-500749fc65e5002441bed312a1771709b265ba15.idx 4KB
info
exclude 240B
HEAD 23B
package-lock.json 1MB
dist
css
Home.5f7c86c2.css 1KB
Scan.199b87c1.css 3KB
app.a7acea31.css 138B
favicon.png 157KB
landscape.png 140KB
img
bg.139a02de.png 165KB
button.b9b80257.png 12KB
_config.yml 0B
index.html 2KB
js
Scan.62d287ed.js 212KB
chunk-vendors.06d24464.js 122KB
app.51d402d8.js 4KB
Home.bb15071a.js 781B
src
App.vue 335B
assets
banner.png 157KB
bg.png 165KB
back.png 359B
preview.png 263KB
close.png 413B
button.png 12KB
views
scan.vue 2KB
home.vue 2KB
main.js 192B
components
Scaner.vue 9KB
router
index.js 461B
.gitignore 254B
public
favicon.png 40KB
landscape.png 140KB
_config.yml 0B
index.html 2KB
README.md 16KB
babel.config.js 78B
共 94 条
- 1
yasuo56
- 粉丝: 2400
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0