zxing-js / library

Multi-format 1D/2D barcode image processing library, usable in JavaScript ecosystem.
https://zxing-js.github.io/library/
Apache License 2.0
2.39k stars 536 forks source link

iPhone/iOS camera black on Progressive Web App, but works if I switch away then back to it #431

Open craigjb123 opened 3 years ago

craigjb123 commented 3 years ago

Andriod appears to work just fine.

On iPhone when I activate the camera it prompts me for permission, then once I allow reveals a black rectangle. If I switch away from the app then back, the camera works and the barcode scans properly.

I'm mimicking the code from here: https://zxing-js.github.io/library/examples/barcode-camera/ (which appears to work just fine)

Any ideas? Thanks!

(function () {
    window.zxing = {

        start: function (autostop, wrapper) {

            console.log("autostop" + autostop);

            let selectedDeviceId;
            const codeReader = new ZXing.BrowserBarcodeReader()

            console.log('ZXing code reader initialized');

            codeReader.getVideoInputDevices()

                .then((videoInputDevices) => {
                    const sourceSelect = document.getElementById("sourceSelect")

                    selectedDeviceId = videoInputDevices[0].deviceId

                    if (videoInputDevices.length > 1) {

                        videoInputDevices.forEach((element) => {
                            const sourceOption = document.createElement("option");
                            sourceOption.text = element.label;
                            sourceOption.value = element.deviceId;
                            sourceSelect.appendChild(sourceOption);
                            selectedDeviceId = element.deviceId;
                        });

                        sourceSelect.onchange = () => {
                            selectedDeviceId = sourceSelect.value;
                            codeReader.reset();
                            StartScan();
                        }

                        const sourceSelectPanel = document.getElementById("sourceSelectPanel");
                        sourceSelectPanel.style.display = "block";
                    }

                    StartScan(autostop);

                    document.getElementById("startButton").addEventListener("click",
                        () => {
                            StartScan(autostop);
                        });

                    function StartScan(autostop) {

                        alert(selectedDeviceId);

                        // start the camera
                        codeReader.decodeOnceFromVideoDevice(selectedDeviceId, "video")
                            .then((result) => {

                                document.getElementById("result").textContent = result.text;

                                var supportsVibrate = "vibrate" in navigator;

                                if (supportsVibrate) navigator.vibrate(1000);

                                if (autostop) {
                                    console.log("autostop");
                                    codeReader.reset();
                                    return wrapper.invokeMethodAsync("invokeFromJS", result.text);

                                } else {
                                    console.log("None-stop");
                                    codeReader.reset();
                                    wrapper.invokeMethodAsync("invokeFromJS", result.text);
                                }

                            }).catch((err) => {
                                // alert(err);
                                console.error(err);
                                // document.getElementById("result").textContent = err;
                            });

                    }

                    document.getElementById("resetButton").addEventListener("click",
                        () => {
                            document.getElementById("result").textContent = "";
                            codeReader.reset();
                            console.log("Reset.");
                        });

                    document.getElementById("closeButton").addEventListener("click",
                        () => {
                            document.getElementById("result").textContent = "";
                            codeReader.reset();
                            console.log("closeButton.");
                            wrapper.invokeMethodAsync("invokeFromJSClose");
                        });

                })
                .catch((err) => {
                    console.error(err);
                });
        }
    };
})();
David-Ly-91 commented 3 years ago

I ran into this issue. Its specifically due to the fact that Safari will not autoplay video without some sort of user input, in your case, its the user flipping the camera. What I did was dynamically draw the div and created the video tag within it and ran the play function on the video tag.

odahcam commented 3 years ago

Ideally for user input API we should show a dialog or something for the user to click (like a dumb message) so we have interaction thus freedom to play with those APIs. It may vary from browser to browser and OS to OS, so it's very tricky to try to track all scenarios, but once you got user input in your application it's easier to work on.

softboy99 commented 2 years ago

Hi, on android pwa, it is blank. there is no question dialog show us to allow use camera, which is ok on pc

nhthai2811 commented 1 year ago

Hi, Is there any way to solve this problem? I am also facing the same situation when opening the camera on PWA app, the camera does not work but when exiting and re-entering the app, it still works normally.

github-actions[bot] commented 2 months ago

Stale issue message