olefirenko / vue-barcode-reader

A Vue.js set of components to scan barcodes and QR codes.
214 stars 77 forks source link

Barcode scans take a long time or do not scan at all since the newest version #55

Open simonbaumeler opened 1 year ago

simonbaumeler commented 1 year ago

Referring to this issue in the demo repository: https://github.com/olefirenko/vue-barcode-reader-example/issues/1

jacowisper commented 1 year ago

Same here

sk-tjdownes commented 1 year ago

Same. It's intermittent, some take much longer than others

sk-tjdownes commented 1 year ago

In trying to resolve this issue, I discovered that resolving the zxing library dependency to the latest 0.20.0 version does indeed resolve the slowness issue. My scans are now instant.

package.json:

"resolutions": {
    "@zxing/library":  "^0.20.0"
}
simonbaumeler commented 1 year ago

@sk-tjdownes what versions of vue and the barcode reader are you using? For me that fix does not seem to work i still get slow or no scans. Could you maybe provide the project in which is its working for you?

sk-tjdownes commented 1 year ago

@sk-tjdownes what versions of vue and the barcode reader are you using? For me that fix does not seem to work i still get slow or no scans. Could you maybe provide the project in which is its working for you?

   "vue": "^3.3.4",
    "vue-barcode-reader": "^1.0.3"

Project is a private repo, sorry

sk-tjdownes commented 1 year ago

@simonbaumeler I'm using yarn. If you're using npm, try overrides instead of resolutions

jacowisper commented 1 year ago

I reverted to building my own component using "@zxing/library": "^0.20.0" directly, here is the code :

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';
import { BrowserMultiFormatReader } from '@zxing/library';
import { useTemplateStore } from '@/stores/template';

const store = useTemplateStore();
const scanner = ref();
const emits = defineEmits(['scanned']);

const codeReader = ref();
const selectedDeviceId = ref();
const isMediaStreamAPISupported = ref(true);
const videoInputDevicesList = ref();
const scanVis = ref(false);

const startScan = (deviceId: string) => {
  store.scannerCamera = deviceId;
  selectedDeviceId.value = deviceId;
  scanVis.value = true;
  codeReader.value.decodeFromVideoDevice(
    selectedDeviceId.value,
    'video',
    (result: { getText: () => string; text: string | null }, err: string | null) => {
      if (result) {
        console.log(result);
        emits('scanned', result.getText());
      }
      if (err) {
        //  console.error(err)
      }
    }
  );
  console.log(`Started continuous decode from camera with id ${selectedDeviceId.value}`);
};

onBeforeUnmount(() => {
  if (codeReader.value) {
    codeReader.value.reset();
  }
});

onMounted(() => {
  isMediaStreamAPISupported.value = navigator && navigator.mediaDevices && 'enumerateDevices' in navigator.mediaDevices;

  if (isMediaStreamAPISupported.value) {
    codeReader.value = new BrowserMultiFormatReader();

    codeReader.value
      .listVideoInputDevices()
      .then((videoInputDevices: MediaDeviceInfo[]) => {
        videoInputDevicesList.value = videoInputDevices;
      })
      .catch((err: Error) => {
        if (err == null) console.error(err);
      });

    if (store.scannerCamera !== '') {
      startScan(store.scannerCamera);
    }
  }
  /*   setTimeout(() => {
      emits('scanned', '4444');
    }, 1000); */
});

const resetScreen = () => {
  store.scannerCamera = '';
  codeReader.value.reset();
  scanVis.value = false;
};
</script>

<template>
  <div v-if="!isMediaStreamAPISupported">
    <h3 class="mt-3 text-danger text-center">Camera not supported or permission denied</h3>
  </div>

  <div v-if="isMediaStreamAPISupported">
    <div class="row mb-3">
      <div class="col">
        <div class="dropdown">
          <button
            type="button"
            class="btn btn-alt-secondary dropdown-toggle"
            id="dropdown-default-alt-secondary"
            data-bs-toggle="dropdown"
            aria-haspopup="true"
            aria-expanded="false"
          >
            Choose Camera
          </button>
          <div class="dropdown-menu fs-sm" aria-labelledby="dropdown-default-alt-secondary">
            <a
              @click="startScan(th.deviceId)"
              v-for="th in videoInputDevicesList"
              :key="th.deviceId"
              class="dropdown-item"
              href="javascript:void(0)"
              >{{ th.label }}</a
            >
          </div>
        </div>
      </div>

      <div class="col text-end">
        <button @click="resetScreen" type="button" class="btn btn-alt-secondary">Reset</button>
      </div>
    </div>

    <div v-if="scanVis" class="scanner-container">
      <video id="video" poster="data:image/gif,AAAA" ref="scanner"></video>
      <div class="overlay-element"></div>
      <div class="laser"></div>
    </div>
  </div>
</template>

<style scoped>
video {
  max-width: 100%;
  max-height: 100%;
}

.scanner-container {
  position: relative;
}

.overlay-element {
  position: absolute;
  top: 0;
  width: 100%;
  height: 99%;
  background: rgba(30, 30, 30, 0.5);

  -webkit-clip-path: polygon(0% 0%, 0% 100%, 20% 100%, 20% 20%, 80% 20%, 80% 80%, 20% 80%, 20% 100%, 100% 100%, 100% 0%);
  clip-path: polygon(0% 0%, 0% 100%, 20% 100%, 20% 20%, 80% 20%, 80% 80%, 20% 80%, 20% 100%, 100% 100%, 100% 0%);
}

.laser {
  width: 60%;
  margin-left: 20%;
  background-color: tomato;
  height: 1px;
  position: absolute;
  top: 30%;
  z-index: 2;
  box-shadow: 0 0 4px red;
  -webkit-animation: scanning 2s infinite;
  animation: scanning 2s infinite;
}

@-webkit-keyframes scanning {
  50% {
    -webkit-transform: translateY(75px);
    transform: translateY(75px);
  }
}

@keyframes scanning {
  50% {
    -webkit-transform: translateY(75px);
    transform: translateY(75px);
  }
}
</style>
simonbaumeler commented 1 year ago

@sk-tjdownes i found the missing piece. When checking the package-lock.json i still got some 19x versions eventhough having: "overrides": { "@zxing/library": "^0.20.0" }

but

"overrides": { "vue-barcode-reader": { "@zxing/library": "^0.20.0" }, "@zxing/library": "^0.20.0" }

did the job. QR scanns are now almost instant and barcode scans are at least possible but still slow. But i think thats the nature of scanning barcodes without a laser. Thanks for you help. :)

teckel12 commented 1 year ago

I've forked this library and added many enhancements which makes it work much better, including selecting the correct camera that supports autofocus, activating the torch (flash) and using the latest version of the zxing library. Check it out and let me know how it works for you:

https://github.com/teckel12/vue-barcode-reader

sk-tjdownes commented 1 year ago

I've forked this library and added many enhancements which makes it work much better

Well done. Have you submitted a pull request? Hoping we can get these enhancements back into the main repo

jacowisper commented 1 year ago

I've forked this library and added many enhancements which makes it work much better, including selecting the correct camera that supports autofocus, activating the torch (flash) and using the latest version of the zxing library. Check it out and let me know how it works for you:

https://github.com/teckel12/vue-barcode-reader

Thank you @teckel12 . Cant wait to try it out.

teckel12 commented 1 year ago

@sk-tjdownes This repo appears to be abandoned, other pull requests have gone unmerged, which I why I forked it and created a new npm package as a replacement.