qr-scanner icon indicating copy to clipboard operation
qr-scanner copied to clipboard

pause the scanner

Open Timer91 opened this issue 3 years ago • 9 comments

Perhaps, I'm not thinking in the right way, but I need to make just one API call for each QR code I scan.
But when I scan one, the callback passed to the constructor is called many times.

Should I do this check by myself or is there a way to pause the scan?

Timer91 avatar Nov 18 '21 15:11 Timer91

qrScanner.pause()

peteevans1230 avatar Nov 19 '21 14:11 peteevans1230

@peteevans1230 thanks your answer.

I've tried this method and the following code works.

const
    elVideo = document.querySelector( "video" )
;

QrScanner
    .listCameras(true)
    .then( devices => {
        if ( devices && devices.length ) {
            const
                qrScanner = new QrScanner( elVideo, ( result ) => {
                    // `this` is equal to `Window`, not the instance of QrScanner.
                    console.log( this );
                    
                    qrScanner.pause();
                } )
            ;
            
            qrScanner.setCamera( 'environment' );
            qrScanner.start();
        }
    } );

Note that this in the callback is not equal to the QrScanner instance. It would be great to be able to do this. It would allow not to declare the function at instantiation and access to our instance from inside.

Timer91 avatar Nov 22 '21 08:11 Timer91

Btw, is there a way to pause the QR code scanner without disabling the camera?

EDIT:

I've found that way:

qrScanner._active = !1;

It would be interesting to talk about it in documentation.

Timer91 avatar Nov 22 '21 09:11 Timer91

After several tests, it does not work with _active.

In the following example, qrScanner._active is set to true. But the scanner does not scan QR code anymore.

QrScanner
    .listCameras(true)
    .then( devices => {
        if ( devices && devices.length ) {
            const
                qrScanner = new QrScanner( elVideo, ( qrCodeResult ) => {
                    /* disable QrScanner */
                    qrScanner._active = !1;

                   const
                        requestOptions = {
                            method: "POST",
                            credentials: "include",
                            headers: myHeaders,
                            body: JSON.stringify( {} )
                        };
                    ;

                    fetch( `${API}/route/`, requestOptions )
                        .then( response => response.json() )
                        .then( result => {
                            console.log( result );
                            /* enable QrScanner */
                            qrScanner._active = !0;
                        } )
                        .catch( error => console.log( "error", error ) );
                } )
            ;
            
            qrScanner.setCamera( "environment" );
            qrScanner.start();
        }
    } );

Any idea?

Timer91 avatar Nov 22 '21 16:11 Timer91

@peteevans1230 : I've tried your snippet, but TypeError: qrScanner.resume is not a function. I've checked in the library, this function does not exist...

It works with qrScanner.start() instead of resume.

Timer91 avatar Nov 23 '21 08:11 Timer91

@Timer91 my bad. While i was working on figuring out a solution to the issues i was having with this lib. I actually switched to a different lib, https://github.com/mebjas/html5-qrcode. The code snippet above was actually referencing the other lib. Sorry for the confusion.

The one referenced above is, in my humble OP, is a little more user friendly and has the features that i needed.

peteevans1230 avatar Nov 23 '21 16:11 peteevans1230

Hello, if you only want to scan a single frame, the regular way would be to call qrScanner.stop() or qrScanner.destroy() afterwards. However, do i read that correctly that you want the video stream to continue? I'd be interested to know what your usecase is.

For now, continuing the video stream is not supported via the public api, but I imagine, you could set qrScanner._scanFrame = () => {}; or qrScanner._maxScansPerSecond = 0;. I've not tested this though.

danimoh avatar Feb 04 '22 14:02 danimoh

In my use-case, we are using the camera to scan several (~20-30) QR codes with about a minute between each scan. To prevent having to initialize the camera and scanner each scan, I'm currently just toggling the scanner visibility with CSS, thus providing a better user experience without delay. But the camera feed and scanning is of course still running in the background, which I imagine puts a drain on the battery when its used for half an hour.

So if possible I'd prefer to be able to pause both the feed from the camera and the processing, and resume when a new scan is required.

I dont know if the browser camera API allows quick pause / resume of the video feed, but I guess it should be quite easy to disable the QR code detection to save some processor usage (I dont know how big of an impact it would have though).

I tried using the pause() method, but when resuming using start(), it still takes 1-2 seconds to re-initialize.

RuneSP avatar Mar 01 '22 15:03 RuneSP

After several tests, it does not work with _active.

In the following example, qrScanner._active is set to true. But the scanner does not scan QR code anymore.

QrScanner
    .listCameras(true)
    .then( devices => {
        if ( devices && devices.length ) {
            const
                qrScanner = new QrScanner( elVideo, ( qrCodeResult ) => {
                    /* disable QrScanner */
                    qrScanner._active = !1;

                   const
                        requestOptions = {
                            method: "POST",
                            credentials: "include",
                            headers: myHeaders,
                            body: JSON.stringify( {} )
                        };
                    ;

                    fetch( `${API}/route/`, requestOptions )
                        .then( response => response.json() )
                        .then( result => {
                            console.log( result );
                            /* enable QrScanner */
                            qrScanner._active = !0;
                        } )
                        .catch( error => console.log( "error", error ) );
                } )
            ;
            
            qrScanner.setCamera( "environment" );
            qrScanner.start();
        }
    } );

Any idea?

Toggling _active does work, but you have to manually call qrScanner._scanFrame() after setting _active = true, as _scanFrame is calling itself (and setting _active to false will cause it to return)

edit: also make sure to set _active = true before calling qrScanner.stop()

RuneSP avatar Mar 01 '22 15:03 RuneSP