자바스크립트는
<audio>, <video>태그나 Audio, Video객체를 통해 재생 중인 오디오/비디오를 녹음/녹화하는 방법을 제공한다.
audio나 video의 차이는 audio객체를 사용하느냐, video객체를 사용하느냐의 차이밖에 없다.
# audio/video 녹음 방법
1. Audio/Video에서 재생 중인 스트림 취득: MediaStream
2. 재생 중인 스트림 녹음: MediaRecorder
3. 녹음된 스트림 재생: BlobURL(ObjectURL)
MediaStream, MediaRecorder, Blob객체의 원리를 알고 있다면 아주 간단한 일이다.
자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack
자바스트립트 Media Stream Recording API: MediaRecorder
자바스크립트 File API 파헤치기: Blob, File, FileReader, FileList, BlobURL
물론 위의 객체들을 잘 모르더라도 코드를 보면 이해될 가능성이 높으므로,
일단 코드 전문을 보고 상세 설명을 정리한다.
※ 주의 사항
아래의 html/js 코드를 PC에서 실행하면 아래와 같은 에러 로그를 보게 될 가능성이 있다.
Cannot capture from element with cross-origin data
CORS 정책과 관련된 부분으로 로컬이 아닌 서버 환경에서 실행해주면 잘 된다.
VSCode의 경우, Live Server를 통해 실행시켜주면 된다.(아래 글 참고)
[JS] VS Code로 HTML, JavaScript 개발 환경 구축/실행(@맥, 윈도우)
# audio 녹음 방법 - 예제 코드 전문
Audio객체를 통해 재생 중인 소리를 녹음하여 재생하는 예제이다.
1) "시작/정지" 버튼 클릭하면
2) audio객체의 음악이 재생되면서 녹음을 시작한다.
3) 다시 "시작/정지" 버튼을 클릭하면
4) 음악 재생/녹음이 종료되고, 녹음된 소리가 재생된다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Audio 소리 녹음</title>
</head>
<body>
<button>시작/정지</button>
<br>
<audio controls>녹음 결과 재생용</audio>
</body>
<script>
// Audio 객체 생성: HTML에 별도로 <audio>태그를 선언하고 취득해서 사용해도 된다.
const audio = new Audio("./sample_long.mp3");
// audio, button 엘리먼트 취득
const $audioEl = document.querySelector("audio");
const $button = document.querySelector("button");
// MediaRecorder(녹음기) 변수 선언
let mediaRecorder = null;
// 오디오 데이터 조각(Blob)들을 담아둘 배열 생성
const audioArray = [];
// 녹음 상태 체크용 변수
let isRecording = false;
// 버튼 클릭 이벤트 처리
$button.onclick = (event)=>{
if(!isRecording){
// Audio객체 음악 재생: 음악이 재생중이어야 스트림이 나온다.
audio.play();
// Audio객체에서 재생중인 mediaStream 취득
const mediaStream = audio.captureStream();
// MediaRecorder객체(녹음기) 생성
mediaRecorder = new MediaRecorder(mediaStream);
// 오디오 데이터 취득&저장
mediaRecorder.ondataavailable = (event)=>{
// event.data(Blob객체)로 들어오는 오디오 데이터 조각들을 배열에 담아둔다.
audioArray.push(event.data);
}
// 녹음 종료 이벤트 처리
mediaRecorder.onstop = (event)=>{
// 모든 오디오 데이터 조각들(Blob)을 통합한 Blob객체를 생성한다.
const recordedBlob = new Blob(audioArray);
// 기존에 담아둔 데이터들은 초기화 한다.
audioArray.splice(0);
// BlobURL(ObjectURL)을 만들고, audio엘리먼트에서 재생시킨다.
const recordedBlobURL = window.URL.createObjectURL(recordedBlob);
$audioEl.src = recordedBlobURL;
$audioEl.play();
}
// 녹음 시작
mediaRecorder.start();
isRecording = true;
}else{
// 녹음 종료
mediaRecorder.stop();
isRecording = false;
// Audio객체에서 재생중이던 오디오 정지 처리
audio.pause();
}
}
</script>
</html>
- 실행 결과
위 코드는 별도로Audio객체를 만들어서 음악을 재생시켰지만,
HTML상에 <audio src="오디오파일.mp3"> 을 선언해두고, JS에서 취득해서 사용해도 정확히 동일한 결과를 얻을 수 있다.
# video 녹화 방법 - 예제 코드 전문
또한 위에서 사용한 Audio객체를 Video객체로 변경하고, src로 동영상 파일을 넣어주면
Video객체를 통해 재생 중인 영상도 녹화할 수 있다.
이 예제 코드는 HTML상에 선언한 video엘리먼트에서 재생 중인 영상을 녹화한다.
1) "시작/정지" 버튼을 클릭하면,
2) 1번째 video태그에서 영상이 재생되면서 녹화를 시작한다.
3) 다시 "시작/정지"버튼을 클릭하면,
4) 녹화가 종료되고, 녹화된 영상이 2번째 video태그에서 재생된다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video 영상 녹화</title>
</head>
<body>
<button>시작/정지</button>
<br>
<video id="video_file" src="./sample_video.mp4" controls>파일 재생용</video>
<br>
<video id="video_record" controls>녹화 결과 재생용</video>
</body>
<script>
// video, button 엘리먼트 취득
const $video_file = document.querySelector("#video_file");
const $video_record = document.querySelector("#video_record");
const $button = document.querySelector("button");
// MediaRecorder(녹화기) 변수 선언
let mediaRecorder = null;
// 비디오 데이터 조각(Blob)들을 담아둘 배열 생성
const videoArray = [];
// 녹화 상태 체크용 변수
let isRecording = false;
// 버튼 클릭 이벤트 처리
$button.onclick = (event)=>{
if(!isRecording){
// 1번째 video 태그 영상 재생: 영상이 재생중이어야 스트림이 나온다.
$video_file.play();
// 재생중인 영상의 mediaStream 취득
const mediaStream = $video_file.captureStream();
// MediaRecorder객체(녹화기) 생성
mediaRecorder = new MediaRecorder(mediaStream);
// 비디오 데이터 취득&저장
mediaRecorder.ondataavailable = (event)=>{
// event.data(Blob객체)로 들어오는 비디오 데이터 조각들을 배열에 담아둔다.
videoArray.push(event.data);
}
// 녹음 종료 이벤트 처리
mediaRecorder.onstop = (event)=>{
// 모든 비디오 데이터 조각들(Blob)을 통합한 Blob객체를 생성한다.
const recordedBlob = new Blob(videoArray);
// 기존에 담아둔 데이터들은 초기화 한다.
videoArray.splice(0);
// BlobURL(ObjectURL)을 만들고, 2번째 video태그에서 재생시킨다.
const recordedBlobURL = window.URL.createObjectURL(recordedBlob);
$video_record.src = recordedBlobURL;
$video_record.play();
}
// 녹화 시작
mediaRecorder.start();
isRecording = true;
}else{
// 녹화 종료
mediaRecorder.stop();
isRecording = false;
// 1번째 video태그에서 재생중이던 비디오 정지 처리
$video_file.pause();
}
}
</script>
</html>
- 실행 결과
# audio/video 녹음 방법 - 코드 설명
1. 스트림(소리/영상) 취득
HTMLMediaElement.captureStream()
- Audio, Video 객체의 captureStream()메서드를 호출하면
- 재생 중인 오디오/비디오 스트림을 MediaStream객체로 반환한다.
* 단, captureStream()메서드는 브라우저별 지원 여부 체크가 필요하다.(작성 시점 기준, safari에서는 작동하지 않았다)
2. 녹음/녹화
- MediaStream을 통해 들어오는 스트림 데이터는 MediaRecorder 객체를 통해 저장할 수 있다.
1) MediaRecorder 객체 생성
new MediaRecorder(MediaStream)
: captureStream()로 취득한 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이라고도 하며 생성된 웹페이지에서만 이용가능한 주소값이다.
audio.src = blobURL
audio.play()
: BlobURL은 audio나 video태그의 src로 설정하여 재생 가능하다.
▼마이크나 카메라를 통해 입력되는 소리, 영상을 저장하는 방법은 아래 글 참고▼
[자바스크립트] 마이크 음성 소리 녹음 방법 : MediaRecorder
[자바스크립트] 카메라 영상 녹화 방법 (+무음 비디오 촬영)
'개발(Development) > Media(오디오&비디오 개발)' 카테고리의 다른 글
[자바스크립트] Web Audio API 기본 원리와 예제 코드 (0) | 2022.01.10 |
---|---|
[자바스크립트] 캔버스(canvas) 화면 캡처/녹화 방법(+파일 저장 다운로드 구현) (0) | 2021.12.12 |
[자바스크립트] 카메라 영상 녹화 방법 (+무음 비디오 촬영) (0) | 2021.12.10 |
[자바스크립트] 마이크 음성 소리 녹음 방법 : MediaRecorder (0) | 2021.12.09 |
[자바스크립트] MediaStream 예제 코드: 마이크, 카메라, audio, video, canvas (0) | 2021.12.08 |
댓글