자바스크립트로 녹화기능 만들기
js에 recoder.js파일 생성 후
webpack.config.js에
설정후 npm run dev:assets로 재시작하면
assets/js/recoder.js 파일이 생성됨
MediaDevices //녹음 녹화에 접근하는 속성
https://developer.mozilla.org/ko/docs/Web/API/MediaDevices
getUserMedia()
https://developer.mozilla.org/ko/docs/Web/API/MediaDevices/getUserMedia
constraints
요청할 미디어 유형과 각각에 대한 요구사항을 지정하는 MediaStreamConstraints 객체.
constraints 매개변수는 두 개의 구성 요소, video와 audio를 가지는 객체로, 요청할 미디어 유형에 대해 설명합니다. 둘 중 적어도 하나는 지정해야 합니다.
사용자가 수락하게되면 stream을 받게된다.
비디오 미리보기
전체 코드
upload .pug 에 video#preview추가
const startBtn = document.getElementById("startBtn");
const video = document.getElementById("preview");
const handleStart = async() =>{
const stream = await navigator.mediaDevices.getUserMedia({ //stream으로 카메라에 잡힌 부분을 미리보기 할 수 있다. 이 것을 video elment에 담아보자
audio:false,
video:{width:200, height:300},
});
video.srcObject = stream; //html의 src와 다름 stream(0과1로이루어진 데이타인데)을 위해 사용함 MediaStream, MediaSource,Blob,File를 실행할 때 video에 주는 무언가
video.play();
}
startBtn.addEventListener("click", handleStart)ansyc await에대한 regenerator 에러 뜸 -->
프론트엔드에서 async await 사용하려면 regenerator설치하거나 or 그냥 promise 문법으로 사용
regenerator-runtime
npm i regenerator-runtime
import regeneratorRuntime from "regenerator-runtime";
recorder.js보단 main.js에 import 하여 //main.js는 base.js에 script src로 불러옴
base.pug에 script 불러와서 모든 async await에 사용 할 수있도록
pug
div
video#preview
btn#startBtn Start Recording
지금까지는 눌러서 미리보기를 실행했는데
미리보기는 미리 실행되고 눌르면 녹화가 되는 방식을 구현해 볼 것임
const init= async() =>{
const stream = await navigator.mediaDevices.getUserMedia({
audio:false,
video:{width:200, height:300},
});
video.srcObject = stream;
video.play();
}
init(); //init으로 이름 변경하고 기본으로 시작하게해
------
하나의 버튼에 두개 이벤트 등록
startBtn.removeEventListener("click", handleStart);
startBtn.addEventListener("click", handleStop);
------
녹화하기 MediaRecorder();
비디오든 오디오든 녹화하고mp4등으로 포맷을 저장할 수있음
녹화하고 stream으로 전달해보자
handleStart function에
const recorder = new MaidnRecorder(stream); 녹화하고 싶지만
const init= async() =>{
const stream = await navigator.mediaDevices.getUserMedia({
audio:false,
video:{width:200, height:300},
}); // 다른 함수에 있는 const stream에 접근 할 수 없다.
let stream; // 그래서 빈 변수 let으로 외부에 지정해놓고
const handleStart= () => {
startBtn.innerText ="Stop Recording";
startBtn.removeEventListener("click",handleStart);
startBtn.addEventListener("click", hanldeStop);
const recorder = new MediaRecorder(stream); // MediaRecorder event를 사용하지 않으면 소용없는 코드
recorder.start(); //
}
const init = async() =>{
stream = await navigator.mediaDevices.getUserMedia({ //const stream이아니고 stream 업데이트
audio:false,
video:{width:200, height:300},
});
video.srcObject = stream;
video.play();
}t);
-----
const handleStart= () => {
startBtn.innerText ="Stop Recording";
startBtn.removeEventListener("click",handleStart);
startBtn.addEventListener("click", hanldeStop);
const recorder = new MediaRecorder(stream);
recorder.ondataavailable = (e) =>{ //녹화가 멈추면 발생되는 이벤트
console.log("recording done");
console.log(e);
console.log(e.data); // 파일
//event로 data property를 가진 Blob Event를 받게됨 data를 받으면 사용자가 다운로드 받게할 수있음
}
console.log(recorder); //state:inactive
recorder.start();
console.log(recorder); //state:recording
setTimeout(()=>{
recorder.stop();
},10000); //recorder.stop()이 되면 dataavailable에 접근가능 , blob데이터 받아
}

MediaRecorder
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
MediaRecorder ondataavailable
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/ondataavailable
handlestop을 누르면
recorder.stop()하게 하고지만 hanldeStart에 recoder를 상수 변수로 만들었음
따라서 let recorder로 외부에 변수지정
const handleStart= () => {
startBtn.innerText ="Stop Recording";
startBtn.removeEventListener("click",handleStart);
startBtn.addEventListener("click", hanldeStop);
recorder = new MediaRecorder(stream,{mimeType:"video/webm"});
recorder.ondataavailable = (e) =>{
const videoFile = URL.createObjectURL(e.data); //브라우저 메모리에서만 가능한 URL을 만들어 줌
video.srcObject= null; //미리보기제거
video.src = videoFile;
video.loop = true;
video.play();
}
recorder.start();
}
URL.createObjectURL() creates an URL that is only available on the browser memory.
Simply, a URL that is pointing to the file. 브라우저에서 생성한 url이고 브라우저에서만 파일에 접근 할 수있는 url
We get the data after getting ondataavailable.
We put the data in URL.createObjectURL().
localhost에 존재하는 파일이아니고 브라우저에 메모리에 있는 파일 접근하기위해서 해당 url 필요
URL.createObjectURL()
https://developer.mozilla.org/ko/docs/Web/API/URL/createObjectURL
URL.createObjectURL() - Web API | MDN
URL.createObjectURL() 정적 메서드는 주어진 객체를 가리키는 URL을 DOMString으로 반환합니다.
developer.mozilla.org
------
녹화한거 다운로드하기
let videoFile//공유하기 위해 전역변수로
const handleDownload =()=>{
const a = document.createElement("a");
a.href= videoFile;
a.download ="MyRecording.webm"; //다운로드할 파일의 포맷 정해주기
document.body.appendChild(a);
a.click();
}
const hanldeStop = () =>{
startBtn.innerText = "Download Recording";
startBtn.removeEventListener("click",hanldeStop);
startBtn.addEventListener("click", handleDownload);
recorder.stop();
}
FFmpeg
webmpg --> mp4, 비디오 썸네일 추출
ff를 사용할려면 백엔드에서 사용해야함 ,콘솔
실행비용이큰 프로그램을 브라우저에서 실행 할 수 있음
서버처리(비용)로 하지않고 우리의 사용자 처리능력으로
우리가 사용 할 개념 ffmpeg + webassembly -> ffmpeg.wasm
비디오를 변환하기위해 사용자의 컴퓨터를 사용함
유투브 --> 업로도 된비디오를 비싼 서버에서 변환
우리는 웹어셈블리로 사용자 컴퓨터의 처리능력을 사용 할 것임 서버x,
그리고 웹 어셈블리로 ffmpeg 이용 할 것임
npm install @ffmpeg/ffmpeg @ffmpeg/core
https://github.com/ffmpegwasm/ffmpeg.wasm
https://www.npmjs.com/package/@ffmpeg/ffmpeg
웹 어셈블리는 자바스크립트의 무덤일까?
https://www.youtube.com/watch?v=KjgDxBLv0bM
reocorder.js
const handleDownload =async()=>{
const ffmpeg = createFFmpeg({log:true});
await ffmpeg.load();
//ffmpeg세상에 filesysntem, 파일을 생성해 줌 , 파일명, binary Data videoFile은 URL을 가르 킴
ffmpeg.FS("writeFile", "recording.webm", await fetchFile(videoFile));
ffppeg 실행 , input, 위에서 생성한 파일, 60초프레임단위로, 가상 파일 시스템에 생길 파일
await ffmpeg.run("-i", "recording.webm", "-r", "60", "output.mp4");
'코딩 > Today I Learn' 카테고리의 다른 글
에러로깅 (0) | 2022.01.11 |
---|---|
01.05공부 (0) | 2022.01.05 |
1/03 공부 (0) | 2022.01.03 |
12.29수 공부 (0) | 2021.12.29 |
12.28일 화 공부 (0) | 2021.12.28 |