schmich / instascan

HTML5 QR code scanner using your webcam
https://schmich.github.io/instascan/
MIT License
2.96k stars 863 forks source link

Safari issues: This web page was reloaded because of a problem occurred. #200

Open kibagami-jubei opened 5 years ago

kibagami-jubei commented 5 years ago

For my mobile website, I'm using the scanner library and users have been noticing this crash (which has been occurring intermittently): This web page was reloaded because of a problem occurred.

This happens when the page moves back and forth from scanning. The crash is intermittent.

Has anyone come across this before? Does anyone know how to fix this?

I will post code later.

kibagami-jubei commented 5 years ago

Hi all, here is my JS code! Thanks.

let scanner = null;
var DeviceCameraDDLID = 'ddlCameras';
var DeviceCameras = null;
var partVerBarcodeTypeKey = 'partVerBarcodeType';

$(document).on('pageshow', '#GetBarcodeValue', function () {

    getHeaderBarVideo('GetBarcodeValue_HeaderBar', false);
    console.log('GetBarcodeValue.html');
    addActivityLog('GetBarcodeValue.html');
    InitScanner();

    $("#" + DeviceCameraDDLID).on('change', function () {
        var cameraSel = $('#' + DeviceCameraDDLID + ' option:selected').index();

        if (cameraSel != 0) {

            //Minus one cause the dummy select value. 
            var index = cameraSel - 1;
            window.localStorage.setItem(_keySelectedCamera, index);
            scanner.start(DeviceCameras[index]);
            $('#dialCamSelection').popup('close');
        }
    });
});

$(document).on('pagehide', '#GetBarcodeValue', function () {
    if (scanner != null) {
        scanner.removeAllListeners();
        scanner.stop();
    }
});

function barcodeIsValid(bcValue) {
    return bcValue != null && bcValue != 'null' && bcValue != undefined && bcValue > 0;
}

function HandleBarcodeValue(value) {

    if (isNaN(value) || value == '' || value == true) {
        //I don't know!
        //It's over, blow up!
        console.log(value);
    }

    //Handle like barcode value as before.
    var isAddWO;
    _barcode = value;

    if (_isApp)
        isAddWO = window.sessionStorage.getItem(_keyAddWOFromScan) == 'true' ? true : false;
    else {
        isAddWO = $.cookie('isForAdd') == 'true' ? true : false;
    }

    if (isAddWO == 'true' || isAddWO) {
        $.mobile.changePage('../WorkOrder/AddWorkOrders.html?barcode=' + _barcode);
        return; 
    }
    if (barcodeIsValid(_barcode)) {
        localStorage.setItem(_keyLastScannedBarcodeVal, _barcode);
    }

    var bcType = GetBarcodeType();

    if (bcType == 'part') {
        if (isNaN(_barcode) == false) {
            var reqPage = localStorage.getItem(_keyScanRequestPage);
            $.mobile.changePage(reqPage + '?barcode=' + _barcode);
        } 
        else 
        {
            showErrorMessage(_ScanTypeFailure);
        }
    } else if (bcType == 'location') { 
        var id = parseInt(PV.RetrieveLocationIDValue(_barcode));

        if (id > 0) {
            var reqPage = localStorage.getItem(_keyScanRequestPage);
            $.mobile.changePage(reqPage + '?barcode=' + _barcode);
        } 
        else 
        {
            showErrorMessage(_ScanTypeFailure);
        }       
    }
}

function InitScanner() {

    //Get video element. 
    scanner = new Instascan.Scanner({ video: document.getElementById('scanner'), mirror: false });

    //Set handler! 
    //Gets invoked when QR decoding finds content.  
    scanner.addListener('scan', function (content) {
        console.log(content);
        HandleBarcodeValue(content);
    });

    //Select cameras.
    InitCameras();

}

function InitCameras() {

    DeviceCameras = null;

    if (DeviceCameras == null) {

        Instascan.Camera.getCameras().then(function (cameras) {
            DeviceCameras = cameras;
            SetCameraSelection();
            PopulateCameras();

        }).catch(function (e) {
            console.log(e);
        });
    }
}

function PopulateCameras() {
    if (DeviceCameras.length > 0) {
        DDL.PopulateCamerasList(DeviceCameraDDLID, DeviceCameras);
    } else {
        alert('No cameras found.')
        console.error('No cameras found.');
    }

    if (DeviceCameras.length == 1) {
        scanner.start(DeviceCameras[0]);
    }
}

function OpenModalCameraSelect() {
    $('#dialCamSelection').popup('open');
}

function SetCameraSelection() {

    var index = window.localStorage.getItem(_keySelectedCamera);

    if (index == null) {
        if (DeviceCameras.length == 1) {
            scanner.start(DeviceCameras[0]);
        } else {
            //Find rear camera.
            for (index = 0; index < DeviceCameras.length; index++) {
                var name = DeviceCameras[index].name;
                if (name.indexOf("back") > -1 || name.indexOf("rear") > -1 || 
                    name.indexOf("Back") > -1) {    
                    window.localStorage.setItem(_keySelectedCamera, index);
                    scanner.start(DeviceCameras[index]);
                }
            }
        }
    } else {
        scanner.start(DeviceCameras[index]);
    }
}

function GetBarcodeType() {
    var type = localStorage.getItem(partVerBarcodeTypeKey);

    if (type == 'undefined') {
        type = 'part';
    }

    return type;
}
kibagami-jubei commented 5 years ago

Anybody?

johnatitide commented 5 years ago

I have the same problem, but I worked my way around it by adding a wait time of 3 seconds after doing anything with the camera. Its feels a little dirty, but it keeps my app running. Otherwise I'm very happy, scanning works really well.

kibagami-jubei commented 5 years ago

I have the same problem, but I worked my way around it by adding a wait time of 3 seconds after doing anything with the camera. Its feels a little dirty, but it keeps my app running. Otherwise I'm very happy, scanning works really well.

Are we talking applying waits to the camera object and its functions?

johnatitide commented 5 years ago

I have the same problem, but I worked my way around it by adding a wait time of 3 seconds after doing anything with the camera. Its feels a little dirty, but it keeps my app running. Otherwise I'm very happy, scanning works really well.

Are we talking applying waits to the camera object and its functions?

No, I just show a loader for three seconds between scanner.start and scanner.stop actions.

kibagami-jubei commented 5 years ago

I have the same problem, but I worked my way around it by adding a wait time of 3 seconds after doing anything with the camera. Its feels a little dirty, but it keeps my app running. Otherwise I'm very happy, scanning works really well.

Are we talking applying waits to the camera object and its functions?

No, I just show a loader for three seconds between scanner.start and scanner.stop actions.

Okay, that's great. I might apply that but while I looking at this problem again to attempt your solution, I found that iOS and Safari have fixed the issue with one of their recent updates. Check the screen shot below, I enabled these guys in iOS settings for Safari. Check below:

Also to note: it's iOS 12.2 on an iPhone 8.

imgpsh_mobile_save