client 폴더에 recorder.js 파일을 추가한다.
webpack 적용을 위해 webpack.config.json 파일 entry 부분에 recorder.js 를 추가한다.
webpack을 재시동한다.
//webpack.config.js
entry: {
main: BASE_JS + "main.js",
videoController: BASE_JS + "videoController.js",
recorder: BASE_JS + "recorder.js",
},
upload.pug 에 recorder.js 파일을 연결시켜준다.
upload.pug 에 script 추가한다.
// upload.pug
block scripts
script(src="/static/js/recorder.js")
비디오 녹화를 진행할 upload.pug 에 비디오와 녹화버튼을 만든다.
// upload.pug
div
video#preview
button#recorderBtn 촬영하기
비디오 녹화를 위해 비디오 preview 를 만든다.
// recorder.js
const init = async () => {
stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
width: 50,
hiehgt: 50,
},
}); // media stream 객체 반환
video.srcObject = stream;
video.play();
};
init();
MediaDevices 인터페이스의 getUserMedia() 메서드는 사용자에게 미디어 입력 장치 사용 권한을 요청하며, 사용자가 수락하면 요청한 미디어 종류의 트랙을 포함한 MediaStream (en-US)을 반환합니다. 스트림은 카메라, 비디오 녹화 장치, 스크린 공유 장치 등 하드웨어와 가장 비디오 소스가 생성하는 비디오 트랙과, 마이크, A/D 변환기 등 물리적과 가상 오디오 장치가 생성하는 오디오 스트림, 그리고 그 외의 다른 종류의 스트림을 포함할 수 있습니다.
HTMLMediaElement 인터페이스의 srcObject 속성은 HTMLMediaElement와 연결된 미디어의 소스 역할을 하는 객체를 설정하거나 반환합니다.
객체는 MediaStream, MediaSource, Blob 또는 File(Blob에서 상속됨)일 수 있습니다.
출처 - mdn web docs
recorder.js 에 recorderBtn 클릭 시 발생하는 이벤트 핸들러를 만든다.
// recorder.js
recorderBtn.addEventListener("click", handleStart);
// recorder.js
// 촬영하기 버튼 누를 시 발생되는 이벤트 핸들러
const handleStart = () => {
recorderBtn.innerText = "녹화중";
recorderBtn.disabled = true;
recorderBtn.removeEventListener("click", handleStart);
// stream을 매개변수로 MediaRecorder 생성자를 호출
recorder = new MediaRecorder(stream, {
mimeType: "video/webm",
});
// 비디오 녹화가 끝날 시 실행
recorder.ondataavailable = (event) => {
videoFile = URL.createObjectURL(event.data);
video.srcObject = null;
video.src = videoFile;
video.loop = true;
video.play();
recorderBtn.innerText = "다운로드";
recorderBtn.disabled = false;
recorderBtn.addEventListener("click", handleDownload);
};
recorder.start();
setTimeout(() => {
recorder.stop();
}, 3000);
};
기록할 MediaStream이 지정된 새 MediaRecorder 객체를 만듭니다. 컨테이너의 MIME 유형(예: "video/webm" 또는 "video/mp4")과 오디오 및 비디오 트랙의 비트 전송률 또는 단일 전체 비트 전송률 설정과 같은 작업을 수행하는 옵션을 사용할 수 있습니다.
출처 - mdn web docs
- 녹화가 중단되면 저장된 데이터의 최종 video를 담은
dataavailable
이벤트가 발생한다.MediaRecorder.ondataavailable
함수를 이용해 dataavailable 이벤트를 핸들링할 수 있다.- dataavailable 이벤트는 data 속성을 가진 BlobEvent로써 여기에 녹화된 video에 대한 정보가 담겨 있다.
- event.data 는 일종의 파일(blob - 뒤에서 설명)인데, 이를 이용해 무언가를 하기 위해서는 url에 집어넣어 해당 파일에 접근할 수 있도록 만들어야 한다.
- URL.createObjectURL() 은 브라우저의 메모리에서만 존재하는 url을 만든다.
- 이 url은 실제로 웹 사이트에는 존재하지 않는 url로써 단순히 접근할 수 있는 파일을 가리키고 있다.
- 다시 말해, 해당 url은 브라우저에 의해 만들어져 브라우저 상에서만 존재하는 것으로써, 브라우저의 메모리에 파일을 저장한 후 브라우저가 그 파일에 접근할 수 있도록 한다.
- 실제로 존재하는 url이 아니라 브라우저가 파일을 보여주는 방법일 뿐이므로 백엔드에는 존재하지 않기 때문에 서버가 열려 있어도 컴퓨터를 껐다 다시 돌아오면 해당 url은 없어진다.
출처 - leesyong.log
a 태그를 만들고 a 태그의 href 에 videoFile을 넣는다.
다운로드 시, 파일 이름을 "MyVideo.webm" 으로 설정한 후
a 태그를 body에 추가한다.
그 뒤 click 함수를 실행한다. (실제로 사용자가 클릭하는 것은 아님)
// recorder.js
const handleDownload = async () => {
const a = document.createElement("a");
a.href = videoFile;
a.download = "MyVideo.webm";
document.body.appendChild(a);
a.click();
};