mozmorris / react-webcam

Webcam component
https://codepen.io/mozmorris/pen/JLZdoP
MIT License
1.65k stars 281 forks source link

ISO settings #269

Closed BradPrit09 closed 3 years ago

BradPrit09 commented 3 years ago

Hi, I find this package very nice to use, Thank you. I was playing around with the package and found an issue with the Image/Stream quality (media stream feed), is there any property to increase the iso, saturation, or brightness/contrast of the feed. I was using Chrome for testing the quality.

Thanks, @mozmorris

mozmorris commented 3 years ago

@BradPrit09 good question. Check the video constraints - contrast, brightness, iso, etc are supported by many devices. https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints

JINU98 commented 3 years ago

@mozmorris please look at it.

Brightness Settings is only applicable when applied directly in the media stream itself.

navigator.mediaDevices.getUserMedia({
    video: {
      facingMode: 'environment',
    }
  })
  .then((stream) => {
    const video = document.querySelector('video');
    video.srcObject = stream;

    // get the active track of the stream
    const track = stream.getVideoTracks()[0];

    video.addEventListener('loadedmetadata', (e) => {
       window.setTimeout(() => (
         onCapabilitiesReady(track.getCapabilities())
       ), 500);
    });

    function onCapabilitiesReady(capabilities) {
      console.log(capabilities);
      if (capabilities.brightness) {
        track.applyConstraints({
          frameRate:2,
          advanced: [{brightness: capabilities.brightness.max,}]
        })
        .then(() => {
          console.log(track.getConstraints());
        })
        .catch(e => console.log(e));
      }
    }

  })
  .catch(err => console.error('getUserMedia() failed: ', err));

when I use react webcam for applying brightness changes no changes in the stream is observed.

import React from "react";
import Webcam from "react-webcam";
import {
  Grid, Button, Select, MenuItem, makeStyles,
  Card, CardActionArea, CardActions,
} from "@material-ui/core";
import CameraIcon from "@material-ui/icons/CameraAlt";
import CameraRecord from "@material-ui/icons/Videocam";
import StopCameraRecord from "@material-ui/icons/VideocamOff";

const useStyles = makeStyles((theme) => ({
  button: {
    textTransform: "none",
    marginLeft: theme.spacing(3),
  },
}));

const WebcamCapture = ({ onFrameCapture = ((frame) => { }), onVideoCapture = ((data) => { }) }) => {
  const webcamRef = React.useRef(null);
  const mediaRecorderRef = React.useRef(null);
  const [capturing, setCapturing] = React.useState(false);
  const [recordedChunks, setRecordedChunks] = React.useState([]);
  const [deviceId, setDeviceId] = React.useState({});
  const [devices, setDevices] = React.useState([]);

  const handleDevices = React.useCallback(
    (mediaDevices) => {
      const videoDevices = mediaDevices.filter(({ kind }) => kind === "videoinput");
      if (videoDevices.length > 0) { setDeviceId(videoDevices[0].deviceId); }
      setDevices(videoDevices);
    },
    [setDevices],
  );

  React.useEffect(
    () => {
      navigator.mediaDevices.enumerateDevices().then(handleDevices);
    },
    [handleDevices],
  );

  const handleDownload = React.useCallback(() => {
    if (recordedChunks.length) {
      const blob = new Blob(recordedChunks, {
        type: "video/webm",
      });

      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = function () {
        const base64data = reader.result;
        onVideoCapture?.(base64data);
        setRecordedChunks([]);
      };
    }
  }, [recordedChunks]);

  const capture = React.useCallback(() => {
    const imageSrc = webcamRef.current.getScreenshot();
    onFrameCapture?.(imageSrc);
  }, [webcamRef]);

  const handleDataAvailable = React.useCallback(
    ({ data }) => {
      if (data.size > 0) {
        setRecordedChunks((prev) => prev.concat(data));
      }
    },
    [setRecordedChunks],
  );

  const handleStartCaptureClick = React.useCallback(() => {
    setCapturing(true);
    mediaRecorderRef.current = new MediaRecorder(webcamRef.current.stream, {
      mimeType: "video/webm",
    });
    mediaRecorderRef.current.addEventListener(
      "dataavailable",
      handleDataAvailable,
    );
    mediaRecorderRef.current.start();
  }, [webcamRef, setCapturing, mediaRecorderRef]);

  const handleStopCaptureClick = React.useCallback(() => {
    mediaRecorderRef.current.stop();
    setCapturing(false);
  }, [mediaRecorderRef, webcamRef, setCapturing], handleDownload());

  const handleOnUserMedia = () => {
    webcamRef.current.stream.addEventListener("inactive", (target) => {
      console.log("Camera was stopped");
      console.error(target);
    });
  };

  const handleDeviceChange = (event) => {
    setDeviceId(event.target.value);
  };

  const videoConstraints = {
    width: 800,
    height: 720,
    brightness:-50,
    frameRate:20  //frame rate is applied to the stream but brightness is not.
    };
  const classes = useStyles();
  return (
    <Card>
      <CardActionArea>
        <Webcam
          audio={false}
          // width="50%"
          ref={webcamRef}
          screenshotFormat="image/jpeg"
          forceScreenshotSourceSize
          screenshotQuality={1}
          // My default Resolution 640×480
          // minScreenshotHeight={640}
          // minScreenshotWidth={480}
          videoConstraints={videoConstraints }
          onUserMedia={handleOnUserMedia}
        />
      </CardActionArea>
    </Card>

  );
};

export default WebcamCapture;