이번 시간에는 video recorder를 만들어보자.
음성, 영상, 데이터 등의 작은 조각들이 하나의 줄기를 이뤄 전송되는 데이터 통로이다.
이 stream은 audio track이나 video track과 같은 여러 개의 "track"들로 구성된다.
let stream;
...
const getStream = async () => {
stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
width: 600,
height: 400,
},
});
video.srcObject = stream;
video.play();
};
...
getStream();
코드는 위와 같이 작성했다. 마지막에 video.play()를 해야 video가 동작한다.
유저에게 media 사용에 대한 허락을 요구하는 method다.
위의 경우, video 사용 허가만 요청하고 있다.
stream을 만들었으면 연결해야 한다. src는 url만 받을 수 있으므로 srcObject를 이용해 stream을 연결한다. 참고로 다른 브라우저들은 srcObject로 stream
만 받을 수 있지만, 사파리는 stream, mediaSource, blob, file
들을 받을 수 있다.
let recorder;
let videoFile;
...
const recordStop = () => {
btn.innerText = "start";
recorder.stop();
};
const recordStart = () => {
btn.innerText = "stop";
btn.removeEventListener("click", recordStart);
btn.addEventListener("click", recordStop);
recorder = new MediaRecorder(stream);
recorder.start();
recorder.ondataavailable = (event) => {
videoFile = URL.createObjectURL(event.data);
video.srcObject = null;
video.src = videoFile;
video.loop = true;
video.width = 600;
video.height = 400;
video.play();
};
};
...
btn.addEventListener("click", recordStart);
mediaRecorder object를 만들어주는 생성자다.
첫 번째 인자로 "stream", 두 번째 인자로 "option"을 넣어준다.
Blob
을 사용할 수 있을 때 알려주는 event다. recorder.stop()
이 실행돼야 비로소 호출된다. 뒤에 나오는 함수는 녹화한 영상을 바로 볼 수 있게 만들어준다. 하나씩 살펴보자.
ondataavailable이 실행되면 event 결과는 아래와 같다.
...
data: Blob {size: 37049, type: "video/x-matroska;codecs=avc1"}
...
방금 녹화한 영상이 Blob
object 형태로 출력됐다. 이제 이 Blob을 video와 연결해주면 된다. srcObject는 인자로 stream만 받기 때문에(사파리 제외) createObjectURL
method를 사용해 Blob을 url object 형태로 바꿔서 src에 저장해준다.
참고로 createObjectURL
은 인자로 Blob, File, mediaSource
를 받는다.