IT/React

React 웹캠 - 2. getUserMedia

루벤초이 2021. 3. 30. 22:01

React 웹캠 시리즈입니다.

Sample Code


 

오늘은 웹캠을 통해 영상을 보여주는 간단한 React 앱을 만들어보겠습니다.

예제 코드: Sample Code
소스 위치: src/tutorial/Tutorial03-Webcam.js

 

navigator.mediaDevices.getUserMedia()

단순히 navigator.mediaDevices.getUserMedia()만 호출하면 웹캠을 사용할 수 있습니다. 함수 인자로는 video를 쓸 것인지 audio를 쓸 것인지 true/false 값을 넣어주는 게 전부입니다.

 

Tip. 좀 더 자세히 알아보자면, 이 구문에서 navigator란 브라우저에서 기본으로 제공되는 Web API 인터페이스 객체인데요, 브라우저를 사용하는 user agent의 상태와 신원 정보를 나타냅니다. 뒤이어 나오는 mediaDevices은 카메라, 마이크 등과 같이 현재 연결된 미디어 장치에 접근할 수 있는 객체입니다. getUserMedia()는 미디어 접근을 요청하는 함수로 Promise(비동기 작업의 미래 결과)를 리턴합니다.

 

getUserMedia()를 사용하여 카메라를 불러오는 간단한 React 앱을 만들어봅시다.

import React from 'react';
import { Button } from 'reactstrap';

const getWebcam = (callback) => {
  try {
    const constraints = {
      'video': true,
      'audio': false
    }
    navigator.mediaDevices.getUserMedia(constraints)
      .then(callback);
  } catch (err) {
    console.log(err);
    return undefined;
  }
}

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

웹캠을 가져오는 부분은 React와는 무관하게 javascript 코드이므로 별도 함수로 정의하는 것이 깔끔하겠죠? constraints는 좀 더 많은 옵션이 있지만, 기본적으로 video, audio만 이해하고 넘어갑시다. 말 그대로 위 코드는 audio를 닫겠다는 의미입니다.  주의! 마이크 입력을 사용할 경우(audio : true), PC 마이크 입력때문에 하울링이 생길 수 있으니 볼륨을 작게 해두세요.

 

Styles는 video 엘리먼트의 크기 속성을 나타내려고 편의상 정의한 함수입니다. CSS 스타일을 적용하는 방법은 다양한데, 지금 이 컴포넌트에서만 사용하는 스타일이 몇 개 있는 경우라면 이런 방법도 좋겠지요. 이제 나머지 React 컴포넌트 TestOverlay 코드 부분을 보겠습니다.

function TestOverlay() {
  const [playing, setPlaying] = React.useState(undefined);

  const videoRef = React.useRef(null);

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

  const startOrStop = () => {
    if (playing) {
      const s = videoRef.current.srcObject;
      s.getTracks().forEach((track) => {
        track.stop();
      });
    } else {
      getWebcam((stream => {
        setPlaying(true);
        videoRef.current.srcObject = stream;
      }));
    }
    setPlaying(!playing);
  }

  return (<>
    <div style={{ width: '100vw', height: '100vh', padding: '3em' }}>
      <video ref={videoRef} autoPlay style={Styles.Video} />
      <Button color="warning" onClick={() => startOrStop()}>{playing ? 'Stop' : 'Start'} </Button>
    </div >
  </>);
}

export default TestOverlay;

코드 순서대로 설명하자면, 우선 playing이라는 state를 사용해서 웹캠 입력을 토글링합니다. useEffect(..., [ ]) 구문은 클래스의 componentDidMount()에 해당, 즉 컴포넌트가 올라왔을 때 최초 1회 호출되는 부분으로, getWebcam()을 이 안에서 호출했습니다. getWebcam(callback) 인자로 넘겨준 콜백은 playing state를 true로 하고 스트림을 이 컴포넌트의 <video> 태그 소스로 넣어주는 구문입니다.

 

useRef()를 사용하면 return()으로 렌더링하는 엘리먼트들을 참조할 수 있고 이때 참조된 객체의 .current. 속성을 이용해서 사용합니다. startOrStop()이라는 함수를 만들어 웹캠을 켜고 끌 수 있도록 했으며, 이를 버튼에 연동했습니다. playing state를 이용해서 버튼 텍스트가 바뀌도록 했고요.

 

쉽죠? 실행해 봅시다. 결과 화면에는 제 얼굴이 나오기 때문에 스크린샷은 매너스킵합니다. 

728x90
반응형

'IT > React' 카테고리의 다른 글

React 실습 - Class vs. Hook  (0) 2021.04.01
React 웹캠 - 3. Canvas  (0) 2021.03.31
React 웹캠 - 1. Promise 비동기 함수의 이해  (0) 2021.03.29
React 실습 - Overlay  (0) 2021.03.15
React 실습 - props & state  (0) 2021.03.15