npm install react-webcam
기본 사용법은 다음과 같다.
import React from "react";
import Webcam from "react-webcam";
const WebcamComponent = () => <Webcam />;
이렇게 사용하면 거울 모달창을 닫아도 webcam은 켜져있다. webcam을 끄는 기능을 추가해주겠다.
react-webcam 라이브러리에서는 끄는 기능을 제공하지 않아 따로 기능을 추가하였다.
우선 모질라에서 MediaStream의 상속을 받는 객체 videoElem의 소스 스트림을 정지시키고 해제하는 코드를 찾을 수 있었다.
function stopStreamedVideo(videoElem) {
const stream = videoElem.srcObject;
const tracks = stream.getTracks();
tracks.forEach((track) => {
track.stop();
});
videoElem.srcObject = null;
}
MediaStream이란
오디오, 비디오 같은 미디어 스트림을 다루는 객체이다.
소스스트림이란
미디어 요소(예: 비디오 요소, 오디오 요소)의 입력 소스로 사용되는 데이터 스트림입니다. 일반적으로 웹캠, 마이크, 화면 공유 등과 같은 입력 장치에서 제공되는 실시간 비디오 또는 오디오 스트림을 의미합니다.
위의 두 코드를 합치고 기타 설정을 적용해보았다.
export const Mirror = () => {
const webcamRef = useRef<Webcam | null>(null);
const stopWebCam = () => {
if (webcamRef.current?.video) {
const stream = webcamRef.current?.video.srcObject as MediaStream;
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
webcamRef.current.video.srcObject = null;
}
};
return (
<>
<button onClick={stopWebCam}>끄기</button>
<Webcam
ref={webcamRef}
audio={false}
mirrored={true}
screenshotFormat="image/jpeg"
></Webcam>
</>
);
};
버튼으로 webcam을 끄는 과정이 불필요한 것 같아 모달창을 닫음과 동시에 webcam이 꺼지도록 코드를 수정해보겠다.
webcamRef는 useRef로 관리하는 변수로 외부로 export가 되지 않기 때문에 webcamRef를 외부에서 접근할 방법을 찾아야 한다.
type WebcamRefType = React.MutableRefObject<Webcam | null>;
let webcamRef: WebcamRefType = { current: null };
export const setWebcamRef = (ref: WebcamRefType) => {
webcamRef = ref;
};
export const stopWebCam = () => {
if (webcamRef?.current?.video) {
const stream = webcamRef.current.video.srcObject as MediaStream;
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
webcamRef.current.video.srcObject = null;
}
};
export const Mirror = () => {
const webcamRef = useRef(null);
useEffect(() => {
setWebcamRef(webcamRef);
}, []);
const videoConstraints = {
width: 2480,
height: 1440,
facingMode: "user",
};
return (
<>
<Webcam
audio={false}
ref={webcamRef}
mirrored={true}
screenshotFormat="image/jpeg"
style={{
position: "absolute",
textAlign: "center",
height: "100%",
width: "100%",
objectFit: "cover",
}}
videoConstraints={videoConstraints}
></Webcam>
</>
);
};
현재 모달의 name이 mirror일 때 stopWebCam()을 수행한다.
...
const handleModal = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
dispatch(closeModal(""));
if (modal?.name === "mirror") {
stopWebCam();
}
};
...
<button onClick={handleModal}>X</button>
...