-> 사람들이 버튼을 누르면 비디오 녹음이 시작됨. 5초로 제한을 둘거고, 5초가 지나면 녹화된 비디오를 다운받을 수 있게됨.
// entry에 추가
recorder : "./src/client/js/recorder.js",
// script선언해주기
block scripts
script(src="/assets/js/recorder.js")
//버튼 추가
block content
div
video#preview.hidden
button#startBtn.hidden Start Recording
button#initBtn if u record video, Click here
const startBtn = document.getElementById("startBtn");
const video = document.getElementById("preview")
const handleStart = async() => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: {width:500, height:500},
});
video.srcObject = stream; // video에 stream넣어주기 -> stream이 object라서 video.src가 아니라 video.Object임.
video.play();
};
startBtn.addEventListener("click", handleStart);
기본 사용법:
constraints
요청할 미디어 유형과 각각에 대한 요구사항을 지정하는 MediaStreamConstraints 객체. constraints 매개변수는 두 개의 구성 요소, video와 audio를 가지는 객체로, 요청할 미디어 유형에 대해 설명합니다. 둘 중 적어도 하나는 지정해야 합니다.
{ audio: true, video: true }
regenerator-runtime
Regenerator로 컴파일된 생성기 및 비동기 함수를 위한 독립 실행형 런타임입니다. -> async, await을 사용하기 위해 설치 및 import해줘야함.
npm i regenerator-runtime
-> main.js에 import regeneratorRuntime from "regenerator-runtime"; 해주고 base.pug에 script(src="/assets/js/main.js") 추가
HTMLMediaElement 인터페이스의 srcObject 속성은 HTMLMediaElement와 연결된 미디어의 소스 역할을 하는 객체를 설정하거나 반환합니다.
그 객체는 MediaStream, MediaSource, Blob 또는 파일(Blob에서 상속됨)일 수 있습니다.
사용 예시
이 예에서 카메라의 MediaStream은 새로 생성된 요소에 할당됩니다.
const mediaStream = await navigator.mediaDevices.getUserMedia({video: true});
const video = document.createElement('video');
video.srcObject = mediaStream;
MediaRecorder()
기록할 MediaStream이 지정된 새 MediaRecorder 개체를 만듭니다.
stream
기록될 MediaStream입니다. 이 소스 미디어는 navigator.mediaDevices.getUserMedia()를 사용하여 생성된 스트림이나 audio, video 또는 canvas 요소에서 가져올 수 있습니다.
MediaRecorder.start()
미디어 녹화를 시작합니다. 이 메서드는 선택적으로 밀리초 단위의 값을 가진 타임슬라이스 인수를 전달할 수 있습니다.
MediaRecorder.stop()
저장된 데이터의 최종 Blob을 포함하는 dataavailable 이벤트가 발생하는 시점에서 기록을 중지합니다.
MediaRecorder ondataavailable
=> MediaRecorder.stop()이 실행될 때 발생하는 이벤트이다. recording된 데이터에 접근할 수 있도록 해준다.
URL.createObjectURL() 정적 메서드는 주어진 객체를 가리키는 URL을 DOMString으로 반환합니다. 해당 URL은 자신을 생성한 창의 document가 사라지면 함께 무효화됩니다.
=> 결과: 우리는 ondataavailable의 event.data를 이용할 것임.- > 여기에 파일이 들어가 있음.
인터페이스의 getTracks()메서드는 에 관계없이 이 스트림의 모든 개체 MediaStream를 나타내는 시퀀스를 반환합니다.
.hidden {
display: none;
}
-> 가짜 버튼 이용: a 안에 download가 있으면 href(url)로 이동하는게 아니라 href를 다운
a - download
const startBtn = document.getElementById("startBtn");
const initBtn = document.getElementById("initBtn");
const video = document.getElementById("preview");
let stream;
let recorder;
let videoFile;
const handleDownload = () => {
const a = document.createElement("a");
a.href = videoFile;
a.download = "MyRecording.webm"; // href(url)을 다운로드 함. => 다운할 때 파일명을 넣어주면 됨.
document.body.appendChild(a);
a.click();
const tracks = stream.getTracks();
tracks.forEach((track) => {
track.stop();
});
stream = null;
video.src = null;
startBtn.innerText = "Start Recording";
startBtn.removeEventListener("click",handleDownload);
startBtn.addEventListener("click", handleStart);
startBtn.classList.add("hidden");
video.classList.add("hidden");
initBtn.classList.remove("hidden");
};
const handleStop = () => {
startBtn.innerText = "Dowload Recording";
startBtn.removeEventListener("click",handleStop);
startBtn.addEventListener("click", handleDownload);
recorder.stop();
};
const handleStart = () => {
startBtn.innerText = "Stop Recording";
startBtn.removeEventListener("click", handleStart);
startBtn.addEventListener("click", handleStop);
recorder = new window.MediaRecorder(stream);//stream을 record가능한 형태로 만들어줌.
recorder.ondataavailable = (event) => {// recorder data에 접근함. / event를 감지함. event가 발생하면 다음의 것들이 실행됨. 이건 stop()일 떄 발생하므로 stop()되면 event발생 -> ondataavailable발생
videoFile = URL.createObjectURL(event.data); // 브라우저 메모리 상에 저장을 해두고, 우리가 그 파일에 접근할 수 있는 URL을 준거.
video.srcObject = null;
video.src = videoFile;
video.loop = true;
video.play();
};
recorder.start();
};
const init = async() => {
startBtn.classList.remove("hidden");
video.classList.remove("hidden");
initBtn.classList.add("hidden");
stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: true,
});
video.srcObject = stream; // video에 stream넣어주기 -> stream이 object라서 video.src가 아니라 video.Object임.
video.play();
};
initBtn.addEventListener("click", init);
startBtn.addEventListener("click", handleStart);