Basically, I was trying to get a webcam screenshot with react. But the condition is it will get the screenshot only after giving access to it and after each 10 seconds interval.
The problem is the webcam screen must be there to take a screenshot. But I don't want the webcam screen to be there but when I press a button it should take the screenshot.
I was using this library React webcam
I tried with visibility hidden to the div and also zIndex to be big negative value with absolute position but its not taking the screenshot without that webcam div.
This is the component I'm using from that library. Tried to remove height and width also but without that webcam screen to be top of the screen it is not taking the image. Showing only blank white image.
<Webcam
audio={false}
height={200}
ref={webcamRef}
screenshotFormat={screenshotFormat}
width={200}
videoConstraints={videoConstraints}
onUserMedia={handleWebCamEnabled}
onUserMediaError={handleWebCamError}
/>
CodePudding user response:
It looks like the component library you've chosen doesn't support the feature you're requesting. It also sound more like a hook functionality than an actual component.
I've written a snippet down below which should match your specifications. It uses the MediaDevices.getUserMedia
API which the component in the library does as well.
Once it gets a stream
it will start an interval. In that interval it will try to take a screenshot of the stream for the given interval duration with the ImageCapture API. If a screenshot was succesfully taken it adds the Blob
to the screenshots
state.
import {useRef, useState, useEffect } from 'react';
const useWebcamScreenshotInterval = (duration) => {
const intervalRef = useRef(null);
const [stream, setStream] = useState(null);
const [screenshots, setScreenshots] = useState([]);
useEffect(() => {
const constraints = {
audio: false,
video: true
};
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => setStream(stream))
.catch(error => console.log(error))
}, []);
useEffect(() => {
if (stream !== null) {
const track = stream.getVideoTracks()[0];
const imageCapture = new ImageCapture(track);
intervalRef.current = setInterval(() => {
imageCapture.takePhoto()
.then(blob => {
setScreenshots(prevState => ([
...prevState,
blob
]))
})
.catch(error => {
console.log(error);
clearInterval(intervalRef.current);
})
}, duration);
}
return () => {
clearInterval(intervalRef.current);
};
}, [stream, duration]);
return screenshots;
}
export default useWebcamScreenshotInterval;
Now you will be able to use this hook inside of any component you like. Note that screenshots
will be an array of Blob
objects. You'll need to use URL.createObjectURL
to create a path to the blobs if you want to use them as image sources.
const screenshots = useWebcamScreenshotInterval(10000);
Also note that the ImageCapture API support is spotty at best.
You might want to look into creating a fallback