mebjas / html5-qrcode

A cross platform HTML5 QR code reader. See end to end implementation at: https://scanapp.org
https://qrcode.minhazav.dev
Apache License 2.0
4.92k stars 960 forks source link

Scanner not recognizing qr codes #699

Closed FlamboD closed 1 year ago

FlamboD commented 1 year ago

When pointing the scanner at a QR code, nothing happens. The scanner works when uploading a file but it doesn't seem to be able to read QR codes live.

I've tried on a Samsung Galaxy A32 and a Samsung S21FE, neither can scan live

miguelmachado17 commented 1 year ago

I was about to open a issue about this problem, but since you already open i will this one instead.

I'm also having this problem, doing file upload works without any problem's but scanning live doenst do anything (Border's don't turn green). However using the "https://blog.minhazav.dev/research/html5-qrcode.html" works, but "https://scanapp.org/" doesn't.

Phone tested: Oneplus 7T

Tested code: ---------------------------------TEST CODE(1)----------------------------------------------------

function onScanSuccess(decodedText, decodedResult) { // handle the scanned code as you like, for example: console.log(Code matched = ${decodedText}, decodedResult); }

function onScanFailure(error) { // handle scan failure, usually better to ignore and keep scanning. // for example: console.warn(Code scan error = ${error}); }

let html5QrcodeScanner = new Html5QrcodeScanner( "reader", { fps: 10, qrbox: {width: 250, height: 250} }, / verbose= / false); html5QrcodeScanner.render(onScanSuccess, onScanFailure);

---------------------------------TEST CODE(2)----------------------------------------------------

const html5QrCode = new Html5Qrcode("reader");
const qrCodeSuccessCallback = (decodedText, decodedResult) => {
    document.getElementById("articlenumber").value = decodedText;
    /* handle success */
};
const config = 
    {
    fps: 8, qrbox: { width: 250, height: 250 }, rememberLastUsedCamera: true, disableFlip: true,
    aspectRatio: 1, facingMode: { exact: "environment" }, focusMode: "continuous",
    supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA, Html5QrcodeScanType.SCAN_TYPE_FILE], 
            formatsToSupport: [Html5QrcodeSupportedFormats.QR_CODE],
    showTorchButtonIfSupported: true, useBarCodeDetectorIfSupported: true, showZoomSliderIfSupported: true, 
            defaultZoomValueIfSupported: 2
};
    html5QrCode.start({ facingMode: "environment" }, config, qrCodeSuccessCallback);
miguelmachado17 commented 1 year ago

Quick Update

I just fixed by changing CDN from:

jbdxbl5 commented 1 year ago

This is a bug in version 2.3.5. Use 2.3.4 to solve this problem

sharkooon commented 1 year ago

Having the same issues not recognising qr/barcodes using the latest: https://unpkg.com/html5-qrcode.

Moving to 2.3.4 is a temporary solution!

bauer00 commented 1 year ago

I also noticed the latest version (v2.3.6) isn't scanning. I'm using the npm version in a VueJS 3 project. v2.3.4 seems to work.

I've noticed that in the README the Html5QrcodeScannerState isn't up-to-date: https://github.com/mebjas/html5-qrcode/blob/v2.3.6/README.md?plain=1#L358

Because scanning didn't work, I called getState() right after calling start() and I got 2. According to the README that would mean PAUSED, while the actual state is SCANNING. https://github.com/mebjas/html5-qrcode/blob/v2.3.6/src/state-manager.ts#L11

cramaboule commented 1 year ago

I also have the same problem with the 2.3.6 Different tablets, different phones.

Moving back to 2.3.4 temporary solved my issue.

phonosys commented 1 year ago

looks like 2.3.6 is broken.. does not recognize any qr. going back to 2.3.4 resolved the issue.

pneves001 commented 1 year ago

I also have teh same problem. But this problem seems to be common to all zxing-js based qr code readers. So its not unique to this project. It appears to be a problem with the error correction or checksum. I'm not too familiar with the image standard or I would fix it.

I'm using vue v2. Moving back to 2.3.4 did nothing. But I'm using node 14..19. What version of node are you all using?

mebjas commented 1 year ago

The library got broken due to a merge.

Fixed published in version 2.3.7

Sorry for bad developer experience. 🙇

Next immediate priority for me is to setup an end to end test which runs before / after every merge and definitely before any push.

Any ideas are welcome here.

I have verified the fixes in scanapp.org. Please let me know if this fixes the same.

mebjas commented 1 year ago

Tracker for e2e testing --> https://github.com/mebjas/html5-qrcode/issues/702

bauer00 commented 1 year ago

I can confirm, version 2.3.7 is working again. Thanks for the quick fix!

pneves001 commented 1 year ago

I'm still unable to get it to work. It doesn't detect QR codes for me. All I get is the following error message over and over again

app.js:120213 NotFoundException at RSSExpandedReader.decodeRow2pairs (https://nsbizsol.com/js/app.js:120234:35) at RSSExpandedReader.decodeRow (https://nsbizsol.com/js/app.js:120208:63) at MultiFormatOneDReader.decodeRow (https://nsbizsol.com/js/app.js:121337:44) at MultiFormatOneDReader.doDecode (https://nsbizsol.com/js/app.js:116759:45) at MultiFormatOneDReader.decode (https://nsbizsol.com/js/app.js:116663:29) at MultiFormatReader.decodeInternal (https://nsbizsol.com/js/app.js:130751:35) at MultiFormatReader.decode (https://nsbizsol.com/js/app.js:130648:25) at ZXingHtml5QrcodeDecoder.decode (https://nsbizsol.com/js/app.js:110105:35) at https://nsbizsol.com/js/app.js:110094:31 at new Promise ()

With the occasional following message in my console. The borders never turn green so there is no indication that Its even detecting the code. I've tried 2.3.7, 2.3.6 and 2.3.4. I've also tried upgrading to node version v18.14.1

app.js:107110 Error happend while scanning context BaseLoggger.logError @ app.js:107110 (anonymous) @ app.js:108414 Promise.catch (async) webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 Promise.catch (async) __webpack_modules__../node_modules/html5-qrcode/cjs/html5-qrcode.js.Html5Qrcode.foreverScan @ app.js:108413 (anonymous) @ app.js:108397 setTimeout (async) triggerNextScan @ app.js:108396 (anonymous) @ app.js:108415 21:10:28.811

pneves001 commented 1 year ago

The following is my code and how I'm calling it:

`

import Vue from 'vue'; import { EventBus } from './app.js';

import { focus } from 'vue-focus'; import { mixin as focusMixin } from 'vue-focus';

import {Html5Qrcode, Html5QrcodeSupportedFormats, Html5QrcodeScanType, } from "html5-qrcode"; import {NotFoundException} from "html5-qrcode/third_party/zxing-js.umd.js";

Vue.component('qr_scanner_modal',{ prop: [ 'videoSource' ],

data: function ()
  {
  return {
        qr_error: null,
        qrcanvas: null,
        context: null,
        qrvideo:  null,
        hints: null,
        formats: null,
        videoSource: {},
        qr: null,
        selected_source: null,
        polling: null,
        localMediaStream: null,
        scanLineDirect: 'down',
        scanlineOffset: 0,
        qr_title: "",
        visible: false,
        focused: true,
        qr_result: ""
        };
  },
mixins: [ focusMixin ],

created: function ()
        {

        EventBus.$on('trigger-qrcode-scanner', (qrTitle) => this.show(qrTitle));
        },

mounted: function ()
        {
        let self = this;

        this.$root.$on('bv::modal::show', () => this.$nextTick(() => this.mountQRReader()));
        },

methods: {
        mountQRReader: function ()
            {

            let self = this;

            Html5Qrcode.getCameras().then(sourceInfos => {

                            self.videoSource = sourceInfos;
                            })
                        .catch(function (err)
                            {
                            console.log(err.name + ": " + err.message);
                            });
            },
        show: function (qrTitle)
                {
                console.log("Show modal called.");

                this.qr_title = qrTitle + " - QR / Magstripe Reader";

                this.$bvModal.show('qr_code_scanner');
                },

        dismiss:  function()
                {
                this.stopScan();

                this.$bvModal.hide('qr_code_scanner');
                },

        selectSource: function (source)
                {
                console.log(source); 
                this.selected_source = source;

             /*  let formatsToSupport =  [   Html5QrcodeSupportedFormats.QR_CODE,
                                            Html5QrcodeSupportedFormats.AZTEC,
                                            Html5QrcodeSupportedFormats.CODABAR,
                                            Html5QrcodeSupportedFormats.CODE_39,
                                            Html5QrcodeSupportedFormats.CODE_93,
                                            Html5QrcodeSupportedFormats.CODE_128,
                                            Html5QrcodeSupportedFormats.DATA_MATRIX,
                                            Html5QrcodeSupportedFormats.MAXICODE,
                                            Html5QrcodeSupportedFormats.ITF,
                                            Html5QrcodeSupportedFormats.EAN_13,
                                            Html5QrcodeSupportedFormats.EAN_8,
                                            Html5QrcodeSupportedFormats.PDF_417,
                                            Html5QrcodeSupportedFormats.RSS_14,
                                            Html5QrcodeSupportedFormats.RSS_EXPANDED,
                                            Html5QrcodeSupportedFormats.UPC_A,
                                            Html5QrcodeSupportedFormats.UPC_E,
                                            Html5QrcodeSupportedFormats.UPC_EAN_EXTENSION
                                        ] ;
                */

                let formatsToSupport =  [Html5QrcodeSupportedFormats.QR_CODE,
                                        Html5QrcodeSupportedFormats.DATA_MATRIX]; 

                let config = { 
                              fps: 50,  
                              qrbox: { width: 250, height: 250 }, 
                              supportedScanTypes: [Html5QrcodeScanType.SCAN_TYPE_CAMERA]
                              }; 

                this.qr = new Html5Qrcode('qrreader', true, formatsToSupport);

                this.qr.start(
                    this.selected_source, 
                    config, 
                    function (decodedText, decodedResult) { this.read(decodedText, decodedResult); },
                    function (errorMessage) { this.scanError(errorMessage); } )
                    .catch(function (err) { this.scanError(err); });
                },

        read: function (value, decodedResult)
                {
                console.log('read callback called.');
                console.log("Code matched = ${value},  ${decodedResult}");
                console.log(value);

                this.qr_result = value;    

                EventBus.$emit('qr_code_returned', value);

                this.stopScan();
                },

        scanError: function (err)
                {
                if (err && !(err instanceof NotFoundException))
                    {
                    this.qr_error = err;
                    }
                },

        stopScan: function ()
                {
                this.qr.stop(); 
                },

         },
template: `
        <b-modal id="qr_code_scanner"
                 v-bind:title="qr_title"
                 v-bind:videoSource='videoSource'
                 hide-footer >
                        <div class="alert alert-danger" v-show="qr_error != null">
                            {{qr_error}}
                        </div>
                        <div>
                               <a href='#' v-for="source in videoSource" v-on:click="selectSource(source.id)" class='btn btn-primary'>@{{ source.label  }}</a>
                       </div>
                       <div class="large-centered col-lg-12 col-md-12 col-sm-12" style="overflow: hidden;">
                               <input type="text" ref="qr_result" name='qr_result' v-focus="focused" v-model='qr_result' class="form-control" />
                               <div id="qrreader" width="400px"></div>
                       </div>
                <div class="modal-footer">
                    <a href='#' v-on:click='dismiss()' class='btn btn-primary'>Cancel</a>
                </div>
       </b-modal>
        `
});

Vue.use('qr_scanner_modal');

const searchBox = (document.getElementById("search_box") === null) ? null : new Vue({ el: '#search_box', data: function () { return { qr_result: "" }; }, created: function () { EventBus.$on('qr_code_returned', (result) => this.qr_code_returned(result)); }, methods: { activate_qr_scanner: function (title) { console.log('activate_qr_scanner called.'); EventBus.$emit('trigger-qrcode-scanner', title); }, qr_code_returned: function (result) { this.qr_result = result.result; } } });

`

bauer00 commented 1 year ago

It's not directly a solution, but the way you're checking for an error in the scanError function doesn't really work. You're using this function for both, as scanError callback of start and also in a catch scenario, but in the callback defined in start, the first parameter is a string, so err instanceof NotFoundException will not work and is the reason why you get this error over and over again.

I used a simple string search for that, but I also use a different callback function for the catch scenario:

    if (msg.indexOf('NotFoundException') >= 0) {
        // Expected behavior when scanning
        return
    }

There are a lot of reasons why a code isn't recognized, if you're working with QR-Codes, try it with a really simple QR-Code first, if you haven't done that already.

pneves001 commented 1 year ago

Thank you you actually led me to the solution. It turns out the read function in my class was not being found due to the fact that the this pointer was pointing to the wrong scope. So I did a

let self = this;

and now it works perfectly. By getting me to change the catch function it created a situation where I could identify the problem. Thank you thank you thank you. You don't know how much panic this bug has caused me.

I will now confirm that the scanning issue is fixed. And you can probably close the bug.

mebjas commented 1 year ago

Marking this specific bug as fixed.