728x90
마이크로 입력 받는 오디오를 녹음하는 방법
펌글 출처 :
https://curryyou.tistory.com/446
<!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 = [];
//object.onclick = function(){myScript}; 자바스크립트 onclick 이벤트
//async함수 //function 앞에 async를 붙이면 해당 함수는 항상 promise를 반환합니다.
$btn.onclick = async function (event){
//녹음중이아니면
if(!isRecording){
//1. MediaStream 객체 취득
//mediaStream 생성: 메서드가 호출되는 순간 사용자에게 마이크, 카메라 사용 권한(permission)을 요청 한다.
//권한이 승인되면 마이크, 카메라에서 소리, 영상 스트림을 취득하여 Promise<MediaStream>을 반환한다.
//Promise를 반환하므로 async/await 사용
//await 키워드를 만나면 프라미스가 처리될 때까지 기다리고, 결과는 그 이후 변수에 반환됨
const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true});
//2.mediaRecorder 객체 생성
//MediaRecorder는 MediaStream객체로 입력받는 스트림(소리, 영상, 화면)을 녹음/녹화할 수 있다.
//stream에는 취득한 MediaStream객체를 넣어준다.
mediaRecorder = new MediaRecorder(mediaStream);
//3. 이벤트핸들러: 녹음 데이터 취득 처리
//MediaRecorder.ondataavailable 이벤트 핸들러 정의
//들어오는 미디어 데이터들은 이벤트 핸들러의 event.data에 Blob객체 형태로 입력된다.
//개발자는 Blob객체를 취득할 때마다 배열에 담아 둔다.(나중에 합치기 위해)
//Blob이란? - binary large object의 약자 : 이 객체는 주로 이미지, 비디오, 사운드 등과 같은 멀티미디어 객체들을 나타냅니다.
mediaRecorder.ondataavailable = (event) => {
audioArray.push(event.data); // 오디오 데이터가 취득될 때마다 배열에 담아둔다.
}
//4.이벤트핸들러: 녹음 종료 처리 & 재생하기
mediaRecorder.onstop = (event) => {
//녹음이 종료되면, 배열에 담긴 오디오 데이터(Blob)들을 합친다: 코덱도 설정해준다.
const blob = new Blob(audioArray, {"type" : "audio/ogg codecs=opus"});
//기존 오디오 데이터들은 모두 비워 초기화한다.
audioArray.splice(0);
//자바스크립트의 window.URL.createObjectURL() 함수는 Blob 객체를 URL로 변환합니다.
//Blob 데이터에 접근할 수 있는 주소를 생성한다.
const blobURL = window.URL.createObjectURL(blob);
// audio엘리먼트로 재생한다.
$audioEl.src = blobURL;
$audioEl.play();
}
//0.녹음시작
mediaRecorder.start();
isRecording = true;
} else {
//녹음 종료
mediaRecorder.stop();
isRecording = false;
}
}
}
</script>
</html>
아래 코드는 jquery로 변경 + 시작버튼, 종료버튼 나눔
<div>
<!-- 녹음기능구현 -->
<button id="start-btn">녹음시작</button>
<button id="stop-btn">녹음종료</button>
<audio controls>녹음된것확인하기</audio>
</div>
//화면이 모두 로딩된 다음 실행된다.
$(document).ready(function () {
const $audioEl = $("audio")[0]; // jQuery를 사용하므로 첫 번째 엘리먼트를 선택
const $startBtn = $("#start-btn");
const $stopBtn = $("#stop-btn");
let mediaRecorder = null;
const audioArray = [];
$startBtn.click(async function () {
try {
const mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(mediaStream);
mediaRecorder.ondataavailable = (event) => {
audioArray.push(event.data);
}
mediaRecorder.start();
} catch (error) {
console.error("Error accessing microphone:", error);
}
});
$stopBtn.click(function () {
if (mediaRecorder && mediaRecorder.state !== "inactive") {
mediaRecorder.stop();
mediaRecorder.onstop = (event) => {
const blob = new Blob(audioArray, { "type": "audio/ogg; codecs=opus" });
audioArray.splice(0);
const blobURL = window.URL.createObjectURL(blob);
$audioEl.src = blobURL;
$audioEl.play();
}
}
});
});
코드 해석 시 알아야 할 사항
추가 정리,공부 필요 :
자바스트립트 Media Stream Recording API: MediaRecorder
자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL
이전 포스팅 복습 필요:
※ 주의 사항
1. 이 코드에서 사용되는 MediaRecorder는 브라우저별로 지원 여부를 확인해야 한다.
- 글 작성 시점 기준으로 Chrome에서는 작동하나, Safari는 작동하지 않았다.
2. 이 코드에서 사용되는 getUserMedia()는 서버 환경에서는 https에서만 작동한다.
- 개인 PC에서 html파일을 실행하는 경우엔 잘 작동한다.
728x90
'STUDY > JavaScript' 카테고리의 다른 글
[JS] npm 정의와 npm 설치방법 정리 (0) | 2023.08.30 |
---|---|
[JS] Web Speech API의 SpeechSynesisUtterance (0) | 2023.08.28 |
[JS] async와 await 란? (0) | 2023.08.11 |
[JS] 콜백함수 쉽게 배워보기 (0) | 2023.08.09 |
[JS] canvas api - 오각형 육각형 그리기 (0) | 2023.06.21 |