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.38k stars 536 forks source link

REQUEST: Controlling the LED/Light #267

Open Mazecreator opened 4 years ago

Mazecreator commented 4 years ago

It would be nice to be able to activate/deactivate the light on the camera. This would be a great feature to be able to use this in poor lighting conditions.

slokhorst commented 4 years ago

This sounds very useful! Here is a code sample to start out with: https://stackoverflow.com/a/47153547/1427212

odahcam commented 4 years ago

We actually already did that! 🎉 But it's only available on our Angular wrapper. 😭

Just take a look on the code (just follow the torch haha):

https://github.com/zxing-js/ngx-scanner/blob/1079dec0e905821fa4e3038a4ced095e395f1a64/projects/zxing-scanner/src/lib/browser-multi-format-continuous-reader.ts#L129-L144

So, any of you would be very welcome to port the code from there to here so we could make use of that nice feature here too. 😊

Thanks.

slokhorst commented 4 years ago

It's actually pretty easy to use with the library currently:

/* existing code to setup and start ZXing */
const scanner = new ZXing.BrowserMultiFormatReader();
scanner.decodeFromVideoDevice(/* ... */);

/* now the addition to start the torch */
scanner.stream.getVideoTracks()[0].applyConstraints({
    advanced: [{torch: true}] // or false to turn off the torch
});
odahcam commented 4 years ago

Yep, but the idea would be abstract it into the lib so users wouldn't need to know how to do this, but you sure can use that way.

github-actions[bot] commented 4 years ago

Stale issue message

andretgregorio commented 3 years ago

Hello, guys.

I'm using zxing-js/library and it's being freat so far! We just got some new requirements to try to control the torch from the UI. I have tried @slokhorst solution - which would be already great - but it doesn't work. It seems like scanner.stream is always undefined (and by the way, it is a protected attribute on the type definition). I've tried to extend the BrowserMultiFormatReader to add the custom setTorch function (as described on issue #128), but stream is always undefined also.

We are currently using version 0.17.0.

I'm also copying my implementation code below. If anyone can provide any thoughts or orientations on this, I would appreciate a lot! :smile:

import { useEffect, useState } from 'react';
import { NotFoundException, BrowserMultiFormatReader } from '@zxing/library';
import { makeStyles } from '@material-ui/core';
import Box from '@material-ui/core/Box';

const useStyles = makeStyles(() => ({
  video: {
    width: '100%',
    height: '100%',
    objectFit: 'cover',
  },
}));

const videoElementId = 'videoScanner';
const timeBetweenScansMillis = 1500;

interface Props {
  onDetected: (result: string) => void;
  orientation: 'landscape' | 'portrait';
}

export default function CameraScanner({ onDetected, orientation }: Props) {
  const [isTorchOn, setIsTorchOn] = useState(true);
  const classes = useStyles();

  useEffect(() => {
    const codeReader = new BrowserMultiFormatReader(
      undefined,
      timeBetweenScansMillis
    );

    codeReader.decodeFromVideoDevice(null, videoElementId, (result, err) => {
      if (result) {
        onDetected(result.getText());
      }

      if (err && !(err instanceof NotFoundException)) {
        throw Error(JSON.stringify(err));
      }
    });

    codeReader.stream.getVideoTracks()[0].applyConstraints({
      advanced: [
        {
          torch: isTorchOn,
          fillLightMode: isTorchOn ? 'torch' : 'none',
        } as any,
      ],
    });
  }, [orientation]);

  const toggleTorch = () => setIsTorchOn(!isTorchOn);

  return (
    <Box
      overflow="hidden"
      border={5}
      borderRadius={8}
      borderColor="white"
      height="240px"
      m={4}
    >
      <button onClick={toggleTorch}>Torch on/off</button>
      <video id={videoElementId} className={classes.video} />
    </Box>
  );
}
sabitertan commented 3 years ago

@andretgregorio Didn't test, but you are not passing current device Id to decodeFromVideoDevice.

I am not sure if this feature is a concern of base library. This sounds like more of a implementation problem which is implemented in browser implementation. As we are using base library in BlazorBarcodeScanner , you can check my example too: https://github.com/sabitertan/BlazorBarcodeScanner/blob/master/BlazorBarcodeScanner.ZXing.JS/wwwroot/BlazorBarcodeScanner.js

odahcam commented 3 years ago

@sabitertan thanks for sharing, very interesting torch function indeed. I played a lot with torch myself and noticed a lot of inconsistencies between devices and browsers, did you notice it too? If so, how are you working around it?

sabitertan commented 3 years ago

@odahcam I initially get that function from browser implementation :) I just implemented torch but I think there is no way turn "off" unless you destroy stream/track and reinitialize it. (at least that is what I understand from standard :) https://w3c.github.io/mediacapture-image/#torch )

And yes still inconsistence API, needs more testing :/

odahcam commented 3 years ago

Yeah, it's kinda tricky and painful hahah. So I discovered some controls work better than others and in some devices you really can't turn off the torch and in some you actually can. Very odd, but at the same time that's kind of we can expect from an experimental bleeding edge API...