前端实现很哇塞的浏览器端扫码功能

背景

不久前我做了关于获取浏览器摄像头并扫码识别的功能,本文中梳理了涉及到知识点及具体代码实现,整理成此篇文章内容。

本文主要介绍,通过使用基于 vue 技术栈的前端开发技术,在浏览器端调起摄像头 📷,并进行扫码识别功能,对识别到的二维码进行跳转或其他操作处理。本文内容分为背景介绍、实现效果、技术简介、代码实现、总结等部分组成。

实现效果

本实例中主要有两个页面首页和扫码页,具体实现效果如下图所示。

  • 首页:点击 SCAN QRCODE 按钮,进入到扫码页。
  • 扫码页:首次进入时,或弹出 获取摄像头访问权限的系统提示框,点击允许访问,页面开始加载摄像头数据并开始进行二维码捕获拾取,若捕获到二维码,开始进行二维码解析,解析成功后加载识别成功弹窗。

📸 在线体验:https://dragonir.github.io/h5-scan-qrcode

📌 提示:需要在有摄像头设备的浏览器中竖屏访问。手机横竖屏检测小知识可前往我的另一篇文章《五十音小游戏中的前端知识》 中进行了解。

技术简介

WebRTC API

WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间 点对点(Peer-to-Peer) 的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建 点对点(Peer-to-Peer) 的数据分享和电话会议成为可能。

三个主要接口

  • MediaStream:能够通过设备的摄像头及话筒获得视频、音频的同步流。
  • RTCPeerConnection:是 WebRTC 用于构建点对点之间稳定、高效的流传输的组件。
  • RTCDataChannel:使得浏览器之间建立一个高吞吐量、低延时的信道,用于传输任意数据。

🔗 前往 MDN 深入学习:WebRTC_API

WebRTC adapter

虽然 WebRTC 规范已经相对健全稳固了,但是并不是所有的浏览器都实现了它所有的功能,有些浏览器需要在一些或者所有的 WebRTC API上添加前缀才能正常使用。

WebRTC 组织在 github 上提供了一个 WebRTC适配器(WebRTC adapter) 来解决在不同浏览器上实现 WebRTC 的兼容性问题。这个适配器是一个 JavaScript垫片,它可以让你根据 WebRTC 规范描述的那样去写代码,在所有支持 WebRTC 的浏览器中不用去写前缀或者其他兼容性解决方法。

🔗 前往 MDN 深入学习:WebRTC adapter

核心的API navigator.mediaDevices.getUserMedia

网页调用摄像头需要调用 getUserMedia APIMediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个 MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器 等等),也可能是其它轨道类型。

它返回一个 Promise 对象,成功后会 resolve 回调一个 MediaStream对象;若用户拒绝了使用权限,或者需要的媒体源不可用,promisereject 回调一个 PermissionDeniedError 或者 NotFoundError 。(返回的 promise对象 可能既不会 resolve 也不会 reject,因为用户不是必须选择允许或拒绝。)

通常可以使用 navigator.mediaDevices 来获取 MediaDevices ,例如:

navigator.mediaDevices.getUserMedia(constraints)
  .then(function(stream) {
   
    // 使用这个stream
  })
  .catch(function(err) {
   
    // 处理error
  })

🔗 前往 MDN 深入学习:navigator.mediaDevices.getUserMedia

二维码解析库 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

代码实现

流程

整个扫码流程如下图所示:页面初始化,先检查浏览器是否支持 mediaDevices 相关API,浏览器进行调去摄像头,调用失败,就执行失败回调;调用成功,进行捕获视频流,然后进行扫码识别,没有扫瞄到可识别的二维码就继续扫描,扫码成功后绘制扫描成功图案并进行成功回调。

下文内容对流程进行拆分,分别实现对应的功能。

扫码组件 Scaner

页面结构

我们先看下页面结构,主要由 4 部分组成:

  • 提示框。
  • 扫码框。
  • video:展示摄像头捕获视频流。
  • canvas: 绘制视频帧,用于二维码识别。
<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 r
  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值