【问题标题】:Video output not changed when changing source in zxing js library在 zxing js 库中更改源时视频输出未更改
【发布时间】:2020-07-14 07:53:34
【问题描述】:

我有一个反应组件:

import React, { useEffect, useState } from 'react';
import { BarcodeFormat, BrowserMultiFormatReader, DecodeHintType } from '@zxing/library';

function BarcodeScanner ( props )
{
    const [ videoInputDevices, setVideoInputDevices ] = useState ( [] );
    const [ selectedVideoDevice, selectVideoDevice ] = useState ( '' );
    const hints = new Map ();
    const formats = [ BarcodeFormat.CODE_128, BarcodeFormat.CODE_39, BarcodeFormat.EAN_8, BarcodeFormat.EAN_13 ];
    hints.set ( DecodeHintType.POSSIBLE_FORMATS, formats );
    const reader = new BrowserMultiFormatReader ( hints );
    useEffect ( () =>
    {
        ( async () =>
        {
            const videoInputDeviceList = await reader.listVideoInputDevices ();
            setVideoInputDevices ( videoInputDeviceList );
            if ( videoInputDeviceList.length > 0 )
            {
                selectVideoDevice ( videoInputDeviceList[ 0 ].deviceId );
            }
        } ) ();
    }, [] );

    useEffect ( () =>
    {
        if ( selectedVideoDevice )
        {
            reader.reset ();
            reader.decodeFromVideoDevice ( selectedVideoDevice, 'videoElement', ( res ) =>
            {
                if ( res )
                {
                    console.log ( 'result is', res );
                    alert ( res.getText () );
                }
            } ).then ( res => console.log ( 'result', res ) ).catch ( err => console.log ( 'error', err ) );
        }
    }, [ selectedVideoDevice ] );

    return <div
        onChange={ ( event ) =>
        {
            const deviceId = event.target.value;
            selectVideoDevice ( deviceId );
        } }>
        <select>
            {
                videoInputDevices.map ( ( inputDevice, index ) =>
                {
                    return <option value={ inputDevice.deviceId }
                                   key={ index }>
                        { inputDevice.label || inputDevice.deviceId }
                    </option>
                } )
            }
        </select>
        <br/>
        <video id="videoElement" width="600" height="400" style={ { border: "1px solid gray" } }/>
    </div>
}

export default BarcodeScanner;

代码很简单。我得到输入列表并将它们加载到选择字段中。在第一次运行时,我选择了第一个视频输入设备,如果用户更改设备,条形码阅读器将重新启动并使用新的输入设备。

问题是当我将 Android 设备上的视频源从后置摄像头更改为前置摄像头时,我的视频输出没有改变。

谢谢。

【问题讨论】:

  • 我未能重现您的问题。您的代码在我的手机上有效。再试一次您的代码 - bonreadertest.surge.sh 您正在观看某些手机/浏览器/ZXing 特定问题,或者在过去几个月中修复了某些问题。

标签: javascript reactjs barcode zxing barcode-scanner


【解决方案1】:

我对基于 windows、linux 和 android、firefox 和 chrome 的浏览器进行了一些测试,并修复了一些问题和编译警告。似乎有些初始化/生命周期问题可能会引起您的观察。

import React, { useMemo, useState } from "react";
import {
  BarcodeFormat,
  BrowserMultiFormatReader,
  DecodeHintType,
} from "@zxing/library";
import QrCodeParser from "./QrCodeParser";


function BarcodeScanner(props) {
  const [videoInputDevices, setVideoInputDevices] = useState([]);
  const [selectedVideoDevice, selectVideoDevice] = useState("");
  const [sum, setSum] = useState("");

  useMemo(() => {
    const hints = new Map();
    const formats = [BarcodeFormat.QR_CODE];
    hints.set(DecodeHintType.POSSIBLE_FORMATS, formats);
    const reader = new BrowserMultiFormatReader(hints);
    (async () => {
      const videoInputDeviceList = await reader.listVideoInputDevices();
      setVideoInputDevices(videoInputDeviceList);
      if (videoInputDeviceList.length > 0 && selectedVideoDevice==null) {
          selectVideoDevice(videoInputDeviceList[0].deviceId);
      }
    })();

    reader
      .decodeFromVideoDevice(selectedVideoDevice, "videoElement", (res) => {
        if (res) {
          const rawText = res.getText();
         
          setSum( rawText );
        }
      })
      .then((res) => console.log("result", res))
      .catch((err) => console.log("error", err));
  }, [selectedVideoDevice]);

  return (
    <div
      onChange={(event) => {
        const deviceId = event.target.value;
        selectVideoDevice(deviceId);
      }}
    >
      <select>
        {videoInputDevices.map((inputDevice, index) => {
          return (
            <option value={inputDevice.deviceId} key={index}>
              {inputDevice.label || inputDevice.deviceId}
            </option>
          );
        })}
      </select>
      <br />
      <video
        id="videoElement"
        width="600"
        height="400"
        style={{ border: "1px solid gray" }}
      />
      <div id="sum">{sum}</div>
    </div>
  );
}

Github

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2014-07-16
    • 1970-01-01
    相关资源
    最近更新 更多