본문 바로가기
개발(Development)/Media(오디오&비디오 개발)

[자바스크립트] 카메라 영상 녹화 방법 (+무음 비디오 촬영)

by 카레유 2021. 12. 10.

웹 브라우저 상에서

노트북이나 스마트폰의 전면/후면 카메라로 촬영하는 동영상을 녹음해야 하는 경우가 있다.

 

이 글은 별도 라이브러리 없이!

순수 자바스크립트만으로 카메라로 입력 받는 영상(비디오)를 녹화하는 방법을 정리한다.

* 참고로 별도 라이브러리 없이 순수 자바스크립트만 사용하는 방식을 바닐라 자바스크립트(Vanilla Javascript)라고 한다.

 

# 카메라 영상 녹화 순서

1. 카메라 영상 취득: MediaStream

2. 취득한 영상 저장: MediaRecorder

3. 녹화된 영상 재생: Blob, Video

 

옵션 설정에 따라 오디오 없이 비디오만 녹화하면 무음 영상 녹화도 가능하다.

 

▼이를 위해 사용되는 MediaStream, MediaRecorder, Blob 객체에 대해서는 아래글을 참고하자.▼

자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack

자바스트립트 Media Stream Recording API: MediaRecorder

자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL

 

물론 위의 내용을 완벽히 모르더라도 실제 작동하는 코드를 보면 대충 감이 올 것이다.

먼저 예제 코드 전문을 살펴보고, 코드에 대한 상세 설명을 정리한다.


# 카메라 비디오 녹화 방법 - 예제 코드 전문

아래 샘플 코드는 

1) "시작" 버튼을 클릭하면 "첫번째 video" 태그에서 실시간 영상을 재생하고,

2) "정지" 버튼을 클릭하면 "두번째 video" 태그에서 녹화된 영상을 재생한다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>카메라 영상 녹화</title>
</head>
<body>
    <button id="btn_start">시작</button>
    <button id="btn_stop">정지</button>
    <br><br>
    <video id="video_realtime" controls>실시간 영상 재생용</video>
    <video id="video_record" controls>녹화된 영상 재생용</video>
</body>

<script>
    // video, button 엘리먼트 취득
    const $video_realtime = document.querySelector("#video_realtime");
    const $video_record = document.querySelector("#video_record");
    const $btn_start = document.querySelector("#btn_start");
    const $btn_stop = document.querySelector("#btn_stop");

    // MediaRecorder(녹화기) 변수 선언
    let mediaRecorder = null;

    // 영상 데이터를 담아줄 배열 선언
    const arrVideoData = [];
    

    // 시작 버튼 이벤트 처리
    $btn_start.onclick = async function(event) {
        
        // 카메라 입력영상 스트림 생성
        const mediaStream = await navigator.mediaDevices.getUserMedia({
            audio: true,
            video: true
        });

        // 실시간 영상 재생 처리: 첫번째 video태그에서 재생
        $video_realtime.srcObject = mediaStream;
        $video_realtime.onloadedmetadata = (event)=>{
            $video_realtime.play();
        }

        // mediaRecorder객체(녹화기) 생성
        mediaRecorder = new MediaRecorder(mediaStream);


        // 녹화 데이터 입력 이벤트 처리
        mediaRecorder.ondataavailable = (event)=>{
            // 녹화 데이터(Blob)가 들어올 때마다 배열에 담아두기
            arrVideoData.push(event.data);
        }


        // 녹화 종료 이벤트 처리
        mediaRecorder.onstop = (event)=>{
            // 배열에 담아둔 녹화 데이터들을 통합한 Blob객체 생성
            const videoBlob = new Blob(arrVideoData);

            // BlobURL(ObjectURL) 생성
            const blobURL = window.URL.createObjectURL(videoBlob);
            
            // 녹화된 영상 재생: 두번째 video태그에서 재생
            $video_record.src = blobURL;
            $video_record.play();
            
            // 기존 녹화 데이터 제거
            arrVideoData.splice(0);
            
        }

        // 녹화 시작!
        mediaRecorder.start();
    }


    // 종료 버튼 이벤트 처리
    $btn_stop.onclick = (event)=>{
        // 녹화 종료!
        mediaRecorder.stop();
    }

</script>
</html>

 

- 실행 결과

1) 시작 버튼 클릭

2) 마이크/카메라 사용 권한 허용

3) 카메라로 촬영을하고 정지버튼 클릭

4) 녹화된 영상이 재생된다.

 

주석에 충분한 설명을 달아 두었다.

주요 코드에 대한 상세 설명은 아래 글에 정리했다.


# 카메라 동영상 녹화 방법 - 상세 설명

1. 영상 취득

 navigator.mediaDevices.getUserMedia({audio: true, video:true}

- getUserMedia()메서드는 카메라와 마이크로 입력 받는 영상(비디오+오디오) 스트림을 Promise<MediaStream> 로 반환한다.

- getUserMedia() 메서드의 인자(MediaTrackConstraints)로 마이크, 카메라 옵션을 조정할 수 있다.

const cameraStream = await navigator.mediaDevices.getUserMedia({
	audio: {echoCancellation: true}, // 에코 제거 설정
	video: {
		width: 1024, height: 600, // 해상도 설정
		facingMode: "user" // 셀카카메라 설정. 후면카메라는 "environment"
	}
});

- MediaTrackConstraints에 대한 더 자세한 사항은 아래 레퍼런스를 참고하자.

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

  ㄴ https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints

* audio: false로 설정하면 무음 영상이 녹화된다.

* 단, getUserMedia()는 https 환경에서만 작동한다!(로컬에서 html 실행은 가능하다.) 

* Promise는 then/catch나 async/await 구문을 사용해야 한다.

 

 

2. 영상 녹화

- MediaStream을 통해 들어오는 비디오 데이터는 MediaRecorder 객체를 통해 저장할 수 있다.

 

1) MediaRecorder 객체 생성

 new MediaRecorder(MediaStream

: getUserMedia()로 취득한 MediaStream을 인자로 넣어 생성자를 호출해준다.

* MediaRecorder 는 브라우저별 지원 여부를 체크하고 사용해야 한다.(작성 시점 기준 safari는 작동X)

 

2) 이벤트 핸들러 정의

 mediaRecorder.ondataavailable 

: 이용가능한 영상 데이터가 들어올 때마다 호출된다.

: 데이터 조각들은 이벤트 핸들러의 인자 event.data(Blob객체)로 취득할 수 있다.

: 취득한 Blob객체들은 나중에 합치기 위해 배열 등에 저장해 둔다.

 mediaRecorder.onstop 

: 녹화가 종료되면 호출된다.

: 배열에 저장해둔 영상 데이터(Blob)들을 합친다.

 

3) 녹화 시작

 mediaRecorder.start() 

: 녹화를 시작하는 메서드다.

: 녹화가 시작되면 이용가능한 데이터(Blob)가 들어올 때마다 dataavailabel이벤트가 호출된다.

 

4) 녹음 종료

mediaRecorder.stop()

: 녹화를 종료하는 메서드다.

: 녹음이 종료되면 stop이벤트가 호출된다.

 

3. 영상 재생

 window.URL.createObjectURL(Blob

: 통합한 영상 데이터(Blob)를 BlobURL로 생성한다.

: BlobURL은 Blob객체가 저장하고 있는 데이터를 가르키는 임시 URL이다.

* BlobURL은 생성된 웹페이지에서만 이용가능한 주소값으로 ObjectURL이라고도 한다.

 

 video.src = blobURL 

 video.play() 

: BlobURL은 audio나 video태그의 src로 설정하여 재생 가능하다.


▼마이크로 입력되는 소리(오디오)를 녹음하는 방법은 아래 글을 참고하자.▼

[자바스크립트] 마이크 음성 소리 녹음 방법 : MediaRecorder

 

▼<audio>나 <video>태그에서 재생중인 오디오/비디오 녹음 방법은 아래 글 참고▼

[자바스크립트] audio/video 태그에서 재생 중인 소리/영상 녹음 방법

 

댓글