让网页调用摄像头和识别二维码信息是两个功能

网页调用摄像头

js调用摄像头可以使用MediaDevices.getUserMedia API,这个API在绝大部分现代浏览器中都支持,它的功能是获取摄像头的视频流数据,所以你还需要video标签配合播放视频,这样实现在网页上实时显示摄像头内容.

如果你的浏览器太旧,不支持MediaDevices.getUserMedia API,可以试试navigator.getUserMedia API

如果你想在电脑网页上调用摄像头,但是你的电脑又没有摄像头,你可以使用局域网摄像头,有很多可以实现的app.在手机上安装后,局域网访问或者在在电脑上安装指定的软件即可,注意请不要使用古早的usb电脑摄像头,视频清晰度太小的话,会导致识别不出来,并且这种摄像头一般没有自动对焦功能,只要一部手机就可以实现功能了.

识别图片中的二维码信息

有一项实验性质的API Barcode Detection API支持对于二维码和条形码的识别,但是限制较多,并且兼容度不高.所以我使用由作者:undecaf编写的barcode-detector-polyfill库,其原理是通过Wasm模块也就是WebAssembly运行C/C++来对图片进行精准的二维码识别.我实现的路径就是在页面上显示摄像头内容,然后循环对视频标签进行识别.

视频的宽度大小对于识别的精度与耗时有影响

示例代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS实时扫描二维码</title>
  </head>
  <body>
    <p>摄像头图像</p>
    <!-- 视频元素的autoplay="true" playsinline不可少 -->
    <video id="videoEl" autoplay="true" playsinline></video>
    <br />
    <button onclick="identify()">开始识别条形码</button>
    <p>识别状态:<span id="state">未开始</span></p>
    <p>识别结果:<span id="number"></span></p>
    <!-- 核心就是靠barcode-detector-polyfill实现,所以当你编写代码时,请前往https://github.com/undecaf/barcode-detector-polyfill获取最新版本 -->
    <!-- 这个只是示例,国内访问这两个很慢还会跨域,所以推荐使用ES module安装到你的项目 npm install @undecaf/barcode-detector-polyfill -->
    <!-- 官方npm链接https://www.npmjs.com/package/@undecaf/barcode-detector-polyfill -->
    <script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.9.15/dist/index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@undecaf/barcode-detector-polyfill@0.9.21/dist/index.js"></script>
    <script>
      // 检查并初始化BarcodeDetector API
      (function initBarcodeDetector() {
        try {
          window["BarcodeDetector"].getSupportedFormats();
        } catch {
          window["BarcodeDetector"] =
            barcodeDetectorPolyfill.BarcodeDetectorPolyfill;
        }
      })();

      // 获取视频元素和识别器实例
      const videoEl = document.getElementById("videoEl");
      const detector = new window.BarcodeDetector();
      let identificationTimer = null;

      // 初始化摄像头并设置视频流
      async function checkCamera() {
        try {
          const stream = await navigator.mediaDevices.getUserMedia({
            audio: false,
            video: { facingMode: "environment" },
          });
          videoEl.srcObject = stream;
          videoEl.play();

          // 页面卸载时释放资源
          window.addEventListener("beforeunload", () => {
            stream.getTracks().forEach((track) => track.stop());
          });
        } catch (error) {
          console.error("无法访问摄像头:", error);
        }
      }

      // 识别条形码功能
      async function identifyBarcodes() {
        try {
          const results = await detector.detect(videoEl);
          if (results.length > 0) {
            document.getElementById("number").innerText = results[0].rawValue;
            stopIdentification();
          }
        } catch (error) {
          console.error("条形码识别失败:", error);
        }
      }

      // 开启或停止条形码识别
      function identify(start = true) {
        if (start) {
          document.getElementById("state").innerText = "识别中...";
          identificationTimer = setInterval(identifyBarcodes, 500);
        } else {
          stopIdentification();
          document.getElementById("state").innerText = "结束识别";
        }
      }

      // 停止条形码识别并清除定时器
      function stopIdentification() {
        if (identificationTimer) {
          clearInterval(identificationTimer);
          identificationTimer = null;
        }
      }

      // 页面加载时初始化摄像头
      window.onload = checkCamera;
    </script>
  </body>
</html>
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐