별도 라이브러리 없이,
자바스크립트만으로 마이크로 입력 받는 오디오를 녹음하는 방법을 정리한다.
대략 아래와 같은 순서로 진행하면 된다.
1. 마이크 소리 입력: MediaStream
2. 입력된 소리 녹음: MediaRecorder
3. 녹음된 소리 재생: Blob, Audio
마이크 음성 녹음의 원리를 알기 위해서는
MediaStream, MediaRecorder, Blob 등에 대해 알아두면 좋다.
▼이에 대해서는 아래 글을 참고하자.▼
자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack
자바스트립트 Media Stream Recording API: MediaRecorder
자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL
물론 위의 내용을 완벽히 모르더라도 구현은 가능하다.
개발자는 코드로 이해하는게 더 빠를 때도 많으니까.
그럼 시작하자.
# 마이크 음성 녹음 - 예제 코드 전문
자바스크립트에서 목소리를 녹음하는 코드 전문이다.
코드에 대한 상세 설명은 아래에서 다룬다.
<!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>
// 엘리먼트 취득
const $audioEl = document.querySelector("audio");
const $btn = document.querySelector("button");
// 녹음중 상태 변수
let isRecording = false;
// MediaRecorder 변수 생성
let mediaRecorder = null;
// 녹음 데이터 저장 배열
const audioArray = [];
$btn.onclick = async function (event) {
if(!isRecording){
// 마이크 mediaStream 생성: Promise를 반환하므로 async/await 사용
const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true});
// MediaRecorder 생성
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 데이터에 접근할 수 있는 주소를 생성한다.
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) "audio태그"의 플레이 버튼을 누르면 녹음된 목소리가 재생된다.
위의 코드에 대한 상세 설명은 아래에서 정리한다.
# 마이크 음성 녹음 - 상세 설명
1. 소리 취득
navigator.mediaDevices.getUserMedia({audio: true})
- 마이크가 입력 받는 소리는 MediaStream객체로 들어온다.
- 위의 getUserMedia()메서드를 호출하면, Promise<MediaStream> 형태로 소리 데이터가 들어온다.
* 단, getUserMedia()는 https 환경에서만 작동하니 주의하자!(로컬 환경에서 실행하는건 상관 없다)
* Promise를 반환하므로 then()으로 받아서 사용하거나, async/await 구문을 사용해야 한다.
2. 소리 녹음
- MediaStream을 통해 들어오는 오디오 데이터는 MediaRecorder 객체를 통해 저장할 수 있다.
1) MediaRecorder 객체 생성
new MediaRecorder(MediaStream)
: getUserMedia()로 취득한 MediaStream을 인자로 넣어 생성자를 호출해준다.
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이라고도 하며 생성된 웹페이지에서만 이용가능한 주소값이다.
audio.src = blobURL
audio.play()
: BlobURL은 audio나 video태그의 src로 설정하여 재생 가능하다.
※ 주의 사항
1. 이 코드에서 사용되는 MediaRecorder는 브라우저별로 지원 여부를 확인해야 한다.
- 글 작성 시점 기준으로 Chrome에서는 작동하나, Safari는 작동하지 않았다.
2. 이 코드에서 사용되는 getUserMedia()는 서버 환경에서는 https에서만 작동한다.
- 개인 PC에서 html파일을 실행하는 경우엔 잘 작동한다.
▼MediaStream, MediaRecorder, Blob에 대한 자세한 내용은 아래 글을 참고하자.▼
자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack
자바스트립트 Media Stream Recording API: MediaRecorder
자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL
▼브라우저 상에서 카메라로 비디오(동영상) 녹화하는 방법은 아래 글 참고▼
[자바스크립트] 카메라 영상 녹화 방법 (+무음 비디오 촬영)
▼audio, video 엘리먼트로 재생중인 소리/영상 녹화 방법은 아래 글 참고▼
[자바스크립트] audio/video 태그에서 재생 중인 소리/영상 녹음 방법
출처: https://curryyou.tistory.com/446 [카레유]
'개발언어 > 자바스크립트' 카테고리의 다른 글
[javascript] MediaRecorder 웹에서 마이크녹음 예제1 (0) | 2022.02.14 |
---|---|
[Web API] MediaStream Recording 업로드 (0) | 2022.02.09 |
[자바스크립트] 마이크 녹음 테스트 (0) | 2022.02.09 |
자바스크립트 마인드맵 (0) | 2021.09.28 |
코드공부방 추천 (0) | 2021.06.09 |