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.5k stars 547 forks source link

Changing camera source does not remove previous event handler callbacks for video element. #467

Open hdavis224 opened 3 years ago

hdavis224 commented 3 years ago

Describe the bug Changing camera source using BrowserMultiFormatReader().decodeFromVideoDevice() does not remove previous event handler callbacks for video element.

Set breakpoint when calling (from the below code) changeZXingDevice and use getEventListeners(videoElement) from the command line to see the events adding and not removing.

Secondly,, the browser displays BrowserCodeReader.js:347 Trying to play video that is already playing. warning. After pressing camera change button the browser displays the previous warning 2 more times (total of 3 warnings). Pressing again will yield 3 more warnings (total of 5 warnings), etc.

<button id="cameraChange">Change Camera</button>
<video id="video"></video>
import { BrowserMultiFormatReader} from '@zxing/library';

cameraArray : MediaDeviceInfo[] = [];
cameraIndex : number = 0;

codeReader : BrowserMultiFormatReader = new BrowserMultiFormatReader();
videoElement = <HTMLVideoElement>$('#video').get(0);
cameraSwitchIcon = $('#cameraChange');

//Cycle camera source on click
cameraSwitchIcon.on('click', () => {
    if (cameraArray.length <= 1)
        return;

    cameraIndex = (cameraIndex + 1) % cameraArray.length;
    changeZXingDevice(cameraArray[cameraIndex].deviceId);
});

codeReader.listVideoInputDevices()
    .then((videoInputDevices) => {
        cameraArray = videoInputDevices;
        let selectedDeviceId = videoInputDevices[0].deviceId
        changeZXingDevice(selectedDeviceId);
    })
    .catch((err) => {
        console.error(err)
    })

changeZXingDevice(deviceId: string) {
        codeReader.decodeFromVideoDevice(deviceId, videoElement, (result, err) => {
            if (result) {
                console.log(result);
            }
        });
        console.log(`Started continuous decode from camera with id ${deviceId}`);
    }

Expected behavior Previous video events replaced when changing camera source.

Desktop (please complete the following information):

Additional context Looking into the source, I believe the issue is that BrowserCodeReader.js:328-330 event listener names don't match those used in BrowserCodeReader.js:_destroyVideoElement():760 to remove the event listeners.

Additionally, BrowserCodeReader.js:_destroyVideoElement():768 this.videoPlayingEventListener is never defined.

github-actions[bot] commented 6 months ago

Stale issue message