Last active
January 27, 2023 16:44
-
-
Save S3ak/4b493b998d7586ea0b4ce0c03a062267 to your computer and use it in GitHub Desktop.
Camera module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable @next/next/no-img-element */ | |
import { Button, Container, Paper, Title, Text, Card } from "@mantine/core"; | |
import { useRef } from "react"; | |
import { setTimeout } from "timers"; | |
/** | |
* Captures the image using the browsers camera api | |
* @component */ | |
export default function Capture() { | |
const videoRef = useRef<HTMLVideoElement>(null); | |
const canvasRef = useRef<HTMLCanvasElement>(null); | |
const photoRef = useRef<HTMLImageElement>(null); | |
// TODO: get this from device | |
let width = 320; // We will scale the photo width to this | |
let height = 320; // This will be computed based on the input stream | |
// const supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); | |
const constraints = { | |
audio: false, | |
video: true, | |
}; | |
function clearphoto() { | |
if (!canvasRef.current?.getContext("2d") || !photoRef.current) { | |
return; | |
} | |
const canvas = canvasRef.current; | |
const context = canvas.getContext("2d"); | |
// FIXME: Do this check earlier | |
if (!context || typeof canvas === null) { | |
return; | |
} | |
context.fillStyle = "#AAA"; | |
context.fillRect(0, 0, canvas.width, canvas.height); | |
// TODO: Use jpg format, DRY | |
const data = canvas.toDataURL("image/png"); | |
// TODO: Use setState | |
photoRef.current.setAttribute("src", data); | |
} | |
function takepicture() { | |
const canvas = canvasRef.current; | |
if ( | |
!canvas?.getContext("2d") || | |
canvas == null || | |
canvas?.getContext("2d") == null || | |
!photoRef.current || | |
!videoRef.current | |
) { | |
return; | |
} | |
const context = canvas.getContext("2d"); | |
console.log("Take photo", context); | |
if (width && height) { | |
canvas.width = width; | |
canvas.height = height; | |
// FIXME: Type checking hell | |
if (context) context.drawImage(videoRef.current, 0, 0, width, height); | |
// TODO: Use jpg format, DRY | |
const data = canvas.toDataURL("image/png"); | |
console.log("data >>>>", data); | |
// TODO: Create SetImageSrc Func | |
photoRef.current.setAttribute("src", data); | |
} else { | |
clearphoto(); | |
} | |
} | |
function handleSuccess(stream: MediaStream) { | |
const videoTracks = stream.getVideoTracks(); | |
if (!videoRef.current) { | |
return; | |
} | |
console.log("videoRef >>>", videoRef.current); | |
videoRef.current.srcObject = stream; | |
videoRef.current.play(); | |
setTimeout(() => { | |
videoTracks[0].stop(); | |
// TODO: Decide on a timeout, maybe 90 seconds | |
}, 10 * 1000); | |
// TODO: Turn off camera when component unmounts | |
} | |
function handleError(error: any) { | |
if (error.name === "OverconstrainedError") { | |
} else if (error.name === "NotAllowedError") { | |
console.log( | |
"Permissions have not been granted to use your camera and " + | |
"microphone, you need to allow the page access to your devices in " + | |
"order for the demo to work." | |
); | |
} | |
console.log(`getUserMedia error: ${error.name}`, error); | |
} | |
const requestCameriaPermission = async () => { | |
try { | |
const stream = await navigator.mediaDevices.getUserMedia(constraints); | |
handleSuccess(stream); | |
console.log("stream >>>>", stream); | |
} catch (err) { | |
handleError(err); | |
} | |
}; | |
return ( | |
<Container> | |
<Paper> | |
<Title order={2}>Capture</Title> | |
<Text>Capture</Text> | |
<Button onClick={requestCameriaPermission}>Capture</Button> | |
<Card> | |
<canvas ref={canvasRef} style={{ display: "none" }} /> | |
<video autoPlay playsInline ref={videoRef} /> | |
<img alt="My photo" ref={photoRef} /> | |
</Card> | |
<Button onClick={() => takepicture()}>Take Photo</Button> | |
</Paper> | |
</Container> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment