그냥 블로그

[React] React로 자세 추정 - 1. 웹캠 연결하기 본문

Front-End/React

[React] React로 자세 추정 - 1. 웹캠 연결하기

코딩하는 공대생 2023. 11. 8. 09:58
반응형

프로젝트에서 실시간 포즈 감지를 프론트에서 하게 되었다. '-`

 

사용 언어 : TypeScript, React

프레임워크 / 라이브러리 : vite, Recoil, eslint, prettierignore, 

 

 

빠른 제작을 위해 모델은 

https://teachablemachine.withgoogle.com/

 

Teachable Machine

Train a computer to recognize your own images, sounds, & poses. A fast, easy way to create machine learning models for your sites, apps, and more – no expertise or coding required.

teachablemachine.withgoogle.com

Teachable Machine을 사용할 예정이고, 

 

기존에 React로 만들어놓은 프로젝트에 실시간 포즈 감지 기능을 붙여볼까 한다.

 

그러기 위해선 먼저, 프론트에서 웹캠 연결을 해야하는데 

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

 

MediaDevices: getUserMedia() method - Web APIs | MDN

The MediaDevices.getUserMedia() method prompts the user for permission to use a media input which produces a MediaStream with tracks containing the requested types of media.

developer.mozilla.org

getUserMedia를 사용하면 된다고..

 

인터넷 서칭 좀 하면, 프론트에서 간단하게 띄우는걸 찾을 수 있다.

import React, { useRef, useEffect, useState } from 'react';
// 콜백 타입 정의
type StreamCallback = (stream: MediaStream) => void;

// getWebcam 함수는 StreamCallback을 인자로 받아 비동기로 작업을 수행합니다.
const getWebcam = (callback: StreamCallback): void => {
  try {
    const constraints = { video: true, audio: false };
    navigator.mediaDevices.getUserMedia(constraints)
      .then(callback)
      .catch((err) => console.log(err)); // catch로 에러를 잡습니다.
  } catch (err) {
    console.error(err);
  }
};

const Styles = {
  Video: { width: "100%", height: "100%", background: 'rgba(245, 240, 215, 0.5)' },
  None: { display: 'none' },
};

const TestOverlay: React.FC = () => {
  const [playing, setPlaying] = useState<boolean | undefined>(undefined);
  const videoRef = useRef<HTMLVideoElement | null>(null);

  useEffect(() => {
    getWebcam((stream: MediaStream) => {
      setPlaying(true);
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
      }
    });
  }, []);

  const startOrStop = () => {
    if (playing && videoRef.current?.srcObject) {
      const tracks = (videoRef.current.srcObject as MediaStream).getTracks();
      tracks.forEach((track) => {
        track.stop();
      });
      setPlaying(false);
    } else {
      getWebcam((stream: MediaStream) => {
        setPlaying(true);
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
        }
      });
    }
  };

  return (
    <div style={{ width: '100vw', height: '100vh', padding: '3em' }}>
      <video ref={videoRef} autoPlay style={Styles.Video}>
        <track kind="captions" src="captions_ko.vtt" srcLang="ko" label="한국어" />
      </video>
      <button type="button" onClick={startOrStop}>
        {playing ? 'Stop' : 'Start'}
      </button>
    </div>
  );
};

export default TestOverlay;

 

근데 여기서 카메라 허용을 페이지에 들어가자마자 받아야 하기 때문에 그 부분은 나중에 변경시켜줘야 할 것 같다. 

 

웹캠은 잘 됨.