Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuaggaJS Barcode scanner not working for Androids #493

Open
shayanvalaie opened this issue Feb 7, 2023 · 1 comment
Open

QuaggaJS Barcode scanner not working for Androids #493

shayanvalaie opened this issue Feb 7, 2023 · 1 comment

Comments

@shayanvalaie
Copy link

I have created a barcode scanner in my react component using QuaggaJS. The scanner is meant to be used on mobile devices through the web view. It's working fine on all iPhone devices but is not scanning correctly on androids. I am guessing this is a resolution issue in the constraints but have not found a solution that works.

import { useNavigate } from "react-router-dom";
import Quagga from "@ericblade/quagga2";
import adapter from "webrtc-adapter";
import LogService from "../../services/LogService";
import "./BarcodeScanner.css";

const BarcodeScanner = (props) => {
  const navigate = useNavigate();
  const logService = new LogService();
  let mainCameraDeviceId = "";

  

  useEffect(() => {
    async function getBackDevices() {
      await Quagga.CameraAccess.request();

      let devices = await Quagga.CameraAccess.enumerateVideoDevices()
      .then((devices) => devices)
      .catch((err) => {
        logService.Log("Error", "Error when enumerating video devices", err);
        console.error(`${err.name}: ${err.message}`);
      });

      let backDevices = [];

      devices.forEach((device) => {
        logService.Log("Debug", "Detected Device",device);
        if(device.kind.toLowerCase().includes("videoinput") && device.label.toLowerCase().includes("back")) {
          backDevices.push(device);
          console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);
        }
      });

      if (backDevices.length == 0 && devices.length == 1) {
        backDevices.push(devices[0]);
      }

      logService.Log("Debug", "Detected back devices", backDevices);
      mainCameraDeviceId = backDevices[backDevices.length-1].deviceId;  
      startQuagga();
    }
    
    getBackDevices();
  }, []);


  function startQuagga() {
    logService.Log("Debug", "Selected camera device", mainCameraDeviceId);

    let customConstraints = {
      focusMode: 'continuous',
      facingMode: "environment",
      zoom: {min: 1.5, max: 2},
      deviceId: mainCameraDeviceId,
      width: 640,
      height: 480
    }
    
    if(props.deviceType == "iPhone") {
      customConstraints.width = { min: 480 };
      customConstraints.height = { min: 1281 };
    }

    

    logService.Log("Debug", "Device Type", props.deviceType);
    logService.Log("Debug", "Quagga constraints", customConstraints);

    try {
      Quagga.init(
        {
          inputStream: {
            name: "Live",
            type: "LiveStream",
            target: document.querySelector("#interactive"),
            constraints: customConstraints
          },
          locate: true,
          decoder: {
            readers: [
              "upc_reader"
            ],
            multiple: false
          },
        },
        function (err) {
          if (err != null) {
            console.log(err);
            props.onError(err);
            stopScanner();
            return;
          }
          console.log("Initialization finished. Ready to start");
          Quagga.start();
        }
      );
    } catch {
      props.onError("Failed to open camera");
    }
  }

  Quagga.onDetected((data) => {
    props.onDetected(data.codeResult.code);
    Quagga.stop();

  });


  const stopScanner = () => {
    console.log("stopping Quagga");
    Quagga.stop();
  };


  return (
    <div
    
      className="barcode-scanner viewport"
      id="interactive"
    >
      
      <div className="box-overlay"></div>
    </div>
  );
};

export default BarcodeScanner;```
@ericblade
Copy link
Collaborator

my experience is that you can give a camera deviceId or a facingMode as a constraint, but not both. Also, most Androids these days seem to have a camera device that goes to a wide-angle lens, which is useless for barcode scanning because of the fisheye effect. I haven't figured out a good way to filter those devices out, so until/unless s omeone does come up with a good way, it's probably best to let the user supply which camera device works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants