ericblade / quagga2

An advanced barcode-scanner written in Javascript and TypeScript - Continuation from https://github.com/serratus/quaggajs
MIT License
747 stars 85 forks source link

Camera won't switch on Ipad Mini #355

Open chobo2 opened 3 years ago

chobo2 commented 3 years ago

Hi

I having a weird problem where on an old ipad mini (running safari 14) shows all the cameras (back and front) but even though it sees the back camera it never switches to the back cameras, it keeps pulling the wrong camera up. All other devices that I tested work fine with my code.

https://barcodes.z4.web.core.windows.net/

$(function () {
  Quagga.CameraAccess.request(null, {}).then(function () {
    Quagga.CameraAccess.release().then(function () {
      Quagga.CameraAccess.enumerateVideoDevices().then(function (devices) {
        start(devices);
      });
    });
  });

  function tryToDetermineRightCamera(devices) {
    var backDevices = devices.filter(function (device) {
      return device.label.toUpperCase().includes("BACK");
    });

    if (backDevices.length > 0) {
      return backDevices[0].deviceId;
    } else {
      return devices[0].deviceId;
    }
  }

  function start(devices) {
    var deviceId = tryToDetermineRightCamera(devices);

    Quagga.init(
      {
        inputStream: {
          name: "Live",
          type: "LiveStream",
          target: "#container",
          constraints: {
            width: { min: 640 },
            height: { min: 480 },
            deviceId: deviceId,
          },
        },
        decoder: {
          readers: ["upc_reader", "ean_reader"],
        },
      },
      function (err) {
        if (err) {
          console.log(err);
          alert(err);
          return;
        }
        $("#cameras-selection").empty();
        Quagga.start();
        possibleCameraOptions(deviceId);

      }
    );
  }

  function possibleCameraOptions(deviceId){
    setTimeout(function () {
      Quagga.CameraAccess.enumerateVideoDevices().then(function (devices2) {
        devices2.forEach((device2) => {
          function pruneText(text) {
            return text.length > 30 ? text.substr(0, 30) : text;
          }
          var selected = deviceId == device2.deviceId;

          if (selected) {
            $("#cameras-selection").append(
              `<option value="${
                device2.deviceId
              }" selected="selected">${pruneText(device2.label)}</option>`
            );
          } else {
            $("#cameras-selection").append(
              `<option value="${device2.deviceId}">${pruneText(
                device2.label
              )}</option>`
            );
          }
        });
      });
    }, 50);
  }

  function printObject(o) {
    var out = "";
    for (var p in o) {
      out += p + ": " + o[p] + "\n";
    }
    alert(out);
  }

  $("#cameras-selection").change(function () {
    var optionSelected = $(this).find("option:selected");
    var deviceId = optionSelected.val();

    Quagga.stop();

    setTimeout(function () {
        Quagga.init(
          {
            inputStream: {
              name: "Live",
              type: "LiveStream",
              target: "#container",
              constraints: {
                width: { min: 640 },
                height: { min: 480 },
                deviceId: deviceId,
              },
            },
            decoder: {
              readers: ["upc_reader", "ean_reader"],
            },
          },
          function (err) {
            if (err) {
              console.log(err);
              alert(err);
              return;
            }
            Quagga.start();
          }
        );
    }, 100);
  });

  Quagga.onDetected(function (result) {
    if (result.codeResult) {
      $(".search-box").val(result.codeResult.code);
    }
  });

  Quagga.onProcessed(function (result) {
    var drawingCtx = Quagga.canvas.ctx.overlay,
      drawingCanvas = Quagga.canvas.dom.overlay;

    if (result) {
      if (result.boxes) {
        drawingCtx.clearRect(
          0,
          0,
          parseInt(drawingCanvas.getAttribute("width")),
          parseInt(drawingCanvas.getAttribute("height"))
        );
        result.boxes
          .filter(function (box) {
            return box !== result.box;
          })
          .forEach(function (box) {
            Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
              color: "green",
              lineWidth: 2,
            });
          });
      }

      if (result.box) {
        Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, {
          color: "#00F",
          lineWidth: 2,
        });
      }

      if (result.codeResult && result.codeResult.code) {
        Quagga.ImageDebug.drawPath(
          result.line,
          { x: "x", y: "y" },
          drawingCtx,
          { color: "red", lineWidth: 3 }
        );
      }
    }
  });
});
ericblade commented 3 years ago

If it works on everything other than a specific iOS device, I'd point at that being either a problem with that version of iOS, something with that hardware, or something that specific iOS or hardware device is returning that is confusing the selection mechanic.

ericblade commented 3 years ago

Anyone else with an iPad Mini able to verify issues?

chobo2 commented 3 years ago

If it works on everything other than a specific iOS device, I'd point at that being either a problem with that version of iOS, something with that hardware, or something that specific iOS or hardware device is returning that is confusing the selection mechanic.

It works with my limited devices, of Iphone 6, moto g6, samsung A50.

I have no good way even to debug what is going on. I am stuck to alerting textboxes out and seeing if the right device id is being passed in which from what I can tell it is.

Thing is I go to the live sample and no problem with the ipad but I looked at the code quiet abit and I can't figure out what is different from my code.

RobertDickey commented 3 years ago

I'm not sure if this is still needed - but I have ALL of the latest iOS, iPadOS, and MacOS devices. Let me know if something needs tested. I'm currently working on figuring out a way to reduce the overheating issue when using this outside for periods of time. Although I just found this fork, I've been working off of the old one.

ericblade commented 3 years ago

Overheating? You might try turning the frequency down. It wouldn't surprise me if there are less than optimal code paths, but I haven't really researched optimizing the code, more optimizing the readability.