2

I'm building a QR scanner inside a ReactJS web app that is supposed to run on both Android and iOS. However, I cannot get the torch/flashlight to work on iOS.

I'm using the @blackbox-vision toolbox to handle both the torch and the QR scanner. As far as I understand you need to start the camera functionality and can use the video stream to manipulate the torch. Below code works fine on Android but not on iOS:

import { useState, useEffect, useRef } from "react";
import { QrReader } from "@blackbox-vision/react-qr-reader";
import { useTorchLight } from "@blackbox-vision/use-torch-light";

import styles from "./view.module.css";

import IconButton from "../../components/UI/iconbutton/view";

function SAQRView() {
  const streamRef = useRef(null);
  const [on, toggle] = useTorchLight(streamRef.current);
  const [showTorchToggleButton, setShowTorchToggleButton] = useState(false);

  const [msg, setMsg] = useState("");

  const setRef = ({ stream }) => {
    streamRef.current = stream;
    setShowTorchToggleButton(true);
  };

  const previewStyle = {
    width: "100%",
  };

  const onError = (error) => {
    console.log(error);
  };

  const onTorchClick = (event) => {
      toggle();
  };

  return (
    <>
      <div className={styles.container}>
        <div className={styles.sub_container}>
          <QrReader
            delay={100}
            showViewFinder={false}
            style={previewStyle}
            onLoad={setRef}
            onError={onError}
            onScan={setData}
            constraints={{
              facingMode: "environment",
              video: true,
            }}
          />
          <div className={styles.footer}>
            {showTorchToggleButton && (
              <IconButton
                icon="Flash_off"
                toggleIcon="Flash_on"
                isToggled={on}
                onClick={onTorchClick}
              />
            )}
          </div>
          {msg}
        </div>
      </div>
    </>
  );
}

export default SAQRView;

So then I tried manipulating the video stream manually:

import { useState, useEffect, useRef } from "react";
import { QrReader } from "@blackbox-vision/react-qr-reader";
import { useTorchLight } from "@blackbox-vision/use-torch-light";

import styles from "./view.module.css";

import IconButton from "../../components/UI/iconbutton/view";

function SAQRView() {
  const streamRef = useRef(null);
  const [on, toggle] = useTorchLight(streamRef.current);
  const [showTorchToggleButton, setShowTorchToggleButton] = useState(false);

  const [msg, setMsg] = useState("");

  const setRef = ({ stream }) => {
    streamRef.current = stream;
    setShowTorchToggleButton(true);
  };

  const previewStyle = {
    width: "100%",
  };

  const onError = (error) => {
    console.log(error);
  };

  const onTorchClick = (event) => {
    const tracks = streamRef.current.getVideoTracks();
    const track = tracks[0];
      
    setMsg(JSON.stringify(track.getCapabilities(), null, 2));
    
    try {
      if (!track.getCapabilities().torch) {
        alert("No torch available.");
      }
      track.applyConstraints({
        advanced: [
          {
            torch: true,
          },
        ],
      });
    } catch (error) {
      alert(error);
    }
  };

  return (
    <>
      <div className={styles.container}>
        <div className={styles.sub_container}>
          <QrReader
            delay={100}
            showViewFinder={false}
            style={previewStyle}
            onLoad={setRef}
            onError={onError}
            onScan={setData}
            constraints={{
              facingMode: "environment",
              video: true,
            }}
          />
          <div className={styles.footer}>
            {showTorchToggleButton && (
              <IconButton
                icon="Flash_off"
                toggleIcon="Flash_on"
                isToggled={on}
                onClick={onTorchClick}
              />
            )}
          </div>
          {msg}
        </div>
      </div>
    </>
  );
}

export default SAQRView;

Again, this works on Android, but not iOS. Notice that I stringify the track capabilities and print them at the bottom of the screen. For Android this looks as follows:

enter image description here

And for iOS, it looks like this:

enter image description here

So it seems that iOS cannot access the torch capability. However, the torch will be greyed out when the QR scanner is active, so it does seem to grab hold of the torch.

Also we have tried installing the Chrome web browser but this gave exactly the same result.

Can I get around this and if so, how?

Anteino
  • 1,044
  • 7
  • 28
  • So far I understood that it is simply not possible on iOS :( – Anteino Oct 19 '22 at 09:45
  • Hey Anteino, I am trying to make a camera app with flash functionality. Can you help me with how can I take pictures/frames from a button click? I don't want qr read functionality. – Mihir Jan 11 '23 at 00:39
  • I think the blackbox-vision toolbox has a functionality for that. I think it should not be hard to find examples online. – Anteino Jan 11 '23 at 08:54

0 Answers0