Media Stream Recording API란 소리나 영상 등의 미디어 스트림을 녹음, 녹화하는 API이다.
이 글은 Media Stream Recording API에 대한 개념과 예제 코드를 정리한다.
# Media Stream Recording API란?
- Media Stream을 Recording 하는 API로 MediaRecorder객체 하나로 구성되어 있다.
- 즉, MediaStream객체를 통해 입력 받는 소리, 영상, 화면 등을 MediaRecorder객체로 녹음 및 녹화하는 API이다.
* 주의사항
- MediaRecorder 객체는 브라우저별 지원 여부 확인 필요(2021년 기준, Safari는 지원 안 되는 것으로 확인된다.)
# MediaRecorder로 녹음 및 녹화할 수 있는 것들
- MediaRecorder는 MediaStream객체로 입력받는 스트림(소리, 영상, 화면)을 녹음/녹화할 수 있다.
- MediaStream객체로 입력받을 수 있는 스트림은 아래와 같다.
ㄴ 마이크 입력 소리
ㄴ 카메라 입력 영상
ㄴ <audio>태그에서 재생 중인 소리
ㄴ <video>태그에서 재생 중인 영상
ㄴ <canvas>태그에서 그려지는 그림
ㄴ 브라우저 window 영역에서 그려지는 그림
# MediaStream을 취득하는 방법
1. 마이크
- navigator.mediaDevice.getUserMedia() : "마이크"로 입력받는 소리 스트림 취득
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
2. 카메라
- navigator.mediaDevice.getUserMedia() : "카메라"로 입력받는 영상 스트림 취득
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
3. <audio>태그
- HTMLMediaElement.captureStream() : <audio>엘리먼트에서 재생 중인 오디오 스트림 취득
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/captureStream
4. <video>태그
- HTMLMediaElement.captureStream() : <video>엘리먼트에서 재생 중인 비디오 스트림 취득
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/captureStream
5. <canvas>태그
- HTMLCanvasElement.captureStream() : <canvas>엘리먼트 영역을 특정 시간 동안 녹화
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/captureStream
6. window 영역
- MediaDevices.getDisplayMedia() : 브라우저 화면의 지정된 영역을 특정 시간 동안 녹화
- 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia
* navigator.mediaDevice.getUserMedia는 실제 배포 환경에서는 https에서만 작동한다.
* captureStream() 메서드는 브라우저별 지원 여부 확인 필요
▼MediaStream 자체에 대한 자세한 내용은 아래 글을 참고하자.▼
자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack
# MediaRecorder로 미디어 데이터를 저장하는 방법
입력되는 소리나 영상은 한번에 쭉 들어오는게 아니기 때문에,
들어올 때마다 배열에 담아두고 마지막에 합쳐서 사용하는게 포인트다.
여기서는 간단하게 정리만 하고, 아래의 예제코드에서 실제 사용 방법을 다루어 보겠다.
1. MediaStream 객체 취득
- 마이크, 카메라, <audio>태그, <video>태그, <canvas>태그 등에서 MediaStream을 취득한다.
2. MediaRecorder 객체 생성
- 생성자: new MediaRecorder(stream[, options])
- stream에는 취득한 MediaStream객체를 넣어주고, option에는 mime type 등을 넣어준다.
* MediaRecorder 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder
3. 녹화/녹음 시작
- 녹화/녹음 시작: MediaRecorder.start() 메서드 호출
- 녹음/녹화가 시작된 이후, 이용 가능한 미디어 데이터가 들어올 때마다 dataavailabe 이벤트가 발생한다.
- 개발자는 ondataavailable 이벤트 핸들러에서 미디어 데이터 조각들을 배열에 담아 둔다.
4. 녹화/녹음 종료
- 녹화/녹음 종료: MediaRecorder.stop() 메서드 호출
- 녹화/녹음이 종료되면 stop 이벤트가 발생한다.
- 개발자는 onstop 이벤트 핸들러에서 배열에 담아둔 미디어 데이터 조각들을 하나로 합쳐서 활용한다.
5. MediaRecorder.ondataavailable 이벤트 핸들러 정의
- 들어오는 미디어 데이터들은 이벤트 핸들러의 event.data에 Blob객체 형태로 입력된다.
- 개발자는 Blob객체를 취득할 때마다 배열에 담아 둔다.(나중에 합치기 위해)
* ondataavailable 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/ondataavailable
6. MediaRecorder.onstop 이벤트 핸들러 정의
- 녹화/녹음이 종료되면 배열에 담아 두었던 Blob들을 하나로 합친 통합 Blob객체를 만들어 활용한다.
# 예제 코드
1) 마이크로 입력되는 소리를 녹음하고,
2) 녹음이 종료되면 <audio>태그를 통해 재생하는 코드다.
* 테스트 환경: 크롬 브라우저 localhost
<!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>시작/종료</button>
<br><br>
<audio controls>녹음된 소리를 재생할 audio 엘리먼트</audio>
</body>
<script>
// audio, button 태그 취득
const $audioEl = document.querySelector("audio");
const $btn = document.querySelector("button");
// 녹음 상태 체크용 변수
let isRecording = false;
// MediaRecorder 변수 생성
let mediaRecorder = null;
// 녹음 데이터(Blob) 조각 저장 배열
const audioArray = [];
// 녹음 시작/종료 버튼 클릭 이벤트 처리
$btn.onclick = async function (event) {
// 녹음 중이 아닌 경우에만 녹음 시작 처리
if(!isRecording){
// 마이크 mediaStream 생성: Promise를 반환하므로 async/await 사용
const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true});
// MediaRecorder 생성: 마이크 MediaStream을 인자로 입력
mediaRecorder = new MediaRecorder(mediaStream);
// 이벤트핸들러: 녹음 데이터 취득 처리
mediaRecorder.ondataavailable = (event)=>{
audioArray.push(event.data); // 오디오 데이터가 취득될 때마다 배열에 담아둔다.
}
// 이벤트핸들러: 녹음 종료 처리 & 재생하기
mediaRecorder.onstop = (event)=>{
// 녹음이 종료되면, 배열에 담긴 오디오 데이터(Blob)들을 합친다: 코덱도 설정해준다.
const blob = new Blob(audioArray, {"type": "audio/ogg codecs=opus"});
audioArray.splice(0); // 기존 오디오 데이터들은 모두 비워 초기화한다.
// Blob 데이터에 접근할 수 있는 객체URL을 생성한다.
const blobURL = window.URL.createObjectURL(blob);
// audio엘리먼트로 재생한다.
$audioEl.src = blobURL;
$audioEl.play();
}
// 녹음 시작
mediaRecorder.start();
isRecording = true;
}else{
// 녹음 종료
mediaRecorder.stop();
isRecording = false;
}
}
</script>
</html>
- 실행 결과:
1) 마이크 사용 권한 허용 후,
2) 시작/종료 버튼을 눌러 목소리를 녹음하고,
3) 시작/종료 버튼을 다시 눌러 녹음을 종료하고,
4) audio태그의 재생(삼각형)버튼을 누르면 녹음된 목소리가 재생된다.
(처음엔 자동 재생된다)
위의 코드를 이해하기 위해서는 Blob, 객체URL 등에 대한 지식이 필요하다.
▼이에 대해서는 아래 글을 참고하자.▼
자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL
# 레퍼런스
MediaRecording API는 레퍼런스가 쉽고 상세하게 잘 정리되어 있는 편이니 참고하자.
- MediaRecording API: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API
- MediaRecording API 사용법: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API
- MediaRecorder 객체: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
'개발(Development) > Media(오디오&비디오 개발)' 카테고리의 다른 글
[자바스크립트] 마이크 음성 소리 녹음 방법 : MediaRecorder (0) | 2021.12.09 |
---|---|
[자바스크립트] MediaStream 예제 코드: 마이크, 카메라, audio, video, canvas (0) | 2021.12.08 |
자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack (0) | 2021.12.03 |
스트리밍(Streaming)이란: 스트림(Stream), 버퍼(Buffer) 원리 (0) | 2021.11.27 |
오디오 파형 분석(FFT: 고속 푸리에 변환): Time Domain Data to Frequency Data (0) | 2021.11.26 |
댓글