ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

聊聊H5浏览器实现扫一扫

2021-10-14 17:33:06  阅读:247  来源: 互联网

标签:function const 扫一扫 H5 item useState result codeReader 浏览器


我们开发了一款H5产品,原本是由小程序跳转进入的,结果客户因为域名未备案原因,导致产品无法在移动端使用。继而我们将程序嵌入APP,奈何客户方APP里面居然米有提供扫一扫接口导致产品无法使用。于是自己调研了一下怎样不借助平台自己实现扫一扫功能。找了相当多的资料,结果在某哥的文章中找到了解决方法,点此可看(掘金),在此也谢谢这位大神的文章,让我脱离苦海。接下来我讲下我的实现:

我们移动端用的是react

第一步引入插件zxing

cnpm i -S @zxing/library@0.15.1

此处注意,一定要使用0.15.x或者0.16.0版本,其他版本会报错

第二步,测试页面代码

import React, {useState, useEffect} from 'react';
import { Toast, Button } from 'antd-mobile';
import { BrowserQRCodeReader } from '@zxing/library';

// 此方法是为了兼容ios无法获取设备ID而写的
async function getVedioPermission(){
    let m = await navigator.mediaDevices.getUserMedia({video:true, audio:true}).catch(function(){Promise.resolve(null)})
    if(!m){
      Toast.fail('获取权限失败,label 和 deviceId不显示',3);
    }
    let d = await navigator.mediaDevices.enumerateDevices(); 
    // let str = ""
    let did = '';
    d.forEach(function(item) {
      // str+=`kind: ${item.kind};\ngroupId: ${item.groupId}; \ndeviceId: ${item.deviceId}; \nlabel: ${item.label};\n`;
      if (item.kind === 'videoinput') {
        did = item.deviceId; // 获取最后一个视频设备的id(原则上最后一个是后置摄像头)
      }
    })
    // alert(str); // 查看系统所有设备列表
    return Promise.resolve(did);
}

function initReader(){
  const codeReader = new BrowserQRCodeReader();
  return codeReader.getVideoInputDevices()
  .then(async videoInputDevices => {
    if (videoInputDevices.length <= 0){
      throw Error('没找到摄像头啊');
    }
    // 双摄的时候采用后置,否则采用第一个
    let idid = videoInputDevices[videoInputDevices.length -1].deviceId || videoInputDevices[0].deviceId;
    if (!idid) {
      idid = await getVedioPermission();
    }
    return {
        videoDeviceID: idid,
        codeReader
    }
  })
  .catch(err => {
    console.log(err, 15);
  })
}

function App() {

  const [reader, setReader] = useState();
  const [deviceID, setDeviceID] = useState();

  const [message, setMessage] = useState();
  const [result, setResult] = useState();

  useEffect(() => {
    (async function (){
      if(!reader){
        const {videoDeviceID, codeReader} = await initReader();
        setReader(codeReader);
        setDeviceID(videoDeviceID);
      }
    })()
  }, [reader]);

  const decode = (codeReader, selectedDeviceId) => {
    codeReader.decodeFromInputVideoDevice(selectedDeviceId, 'video')
    .then((result) => {
      //console.log(result);
      setResult(result.text);
    }).catch((err) => {
      alert(JSON.stringify(err));
      setMessage(err.toString());
    })
  }

  return <div className="App">
  
    <div className="container" style={{textAlign:'center', width:'100%'}}>
      <div>
        <video id="video" width="200" height="200" style={{border: '1px solid gray', margin:'30px'}} />
        <Button style={{margin:'30px'}} size="lg" color="primary" onClick={() => decode(reader, deviceID)}>扫一扫</Button>
      </div>
    </div>
    <div>{result}</div>
    <div>{message}</div>
  </div>
}

export default App;

第三步,启动服务,切忌PC端测试的话要用localhost访问,否则无权限;

发布到服务器上使用的话,谨记需要https协议,否则也无权限访问。

不过根据资料显示IOS需要在safari版本在11之后的才支持,我没有测试

标签:function,const,扫一扫,H5,item,useState,result,codeReader,浏览器
来源: https://blog.csdn.net/sinat_28904949/article/details/120768130

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有