상세 컨텐츠

본문 제목

ch14. webassembly video transcode

노마드/유튜브

by hippo0207 2022. 9. 2. 15:37

본문

0. intro

  • 다운받은 영상 문제들 수정할거
  • FFmpeg 로 webm >> mp4변환, 비디오썸네일 추출
  • 무료로 하기위해  webAssembly쓸거 >>프론트에서 매우빠른 코드를 실행하게 해줌
  • ffmpeg.wasm > 비디오변환위해 사용자의 컴퓨터(브라우저) 사용함 (우리의 서버가 아닌)

1. transcode video

  • 만들어진 binaryData :: 밑에코드에서 만들어진 event.data 이거임. blob
recorder.ondataavailable = (event) => {
    videoFile = URL.createObjectURL(event.data);
    // blob:http://localhost:4000/938d5a5f-4b94-4bf8-ae62-75f4cb083194
    // >>   브라우저 메모리상에 존재하는 url > 이걸로 파일에 접근가능

import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";

const handleDownload = async () => {
  const ffmpeg = createFFmpeg({log: true});
  await ffmpeg.load();

  //FS = file system
  ffmpeg.FS("writeFile", "recording.webm", await fetchFile(videoFile));
  
  // ffmpeg.run(input, input,..,"초당프레임수" output)
  await ffmpeg.run("-i", "recording.webm","-r", "60", "output.mp4");

2. download transcode video

const handleDownload = async () => {
  ...
  const mp4File = ffmpeg.FS("readFile", "output.mp4"); // >> array 형태임

  //create blob from array  << arrayBuffer로 만들어야함
  const mp4Blob = new Blob([mp4File.buffer], { type: "video/mp4" });

  const mp4Url = URL.createObjectURL(mp4Blob);

  const a = document.createElement("a");
  a.href = mp4Url;
  a.download = "MyRecording.mp4";
  document.body.appendChild(a);
  a.click();
  startBtn.innerText = "Start Recording";
};
  • sharedBuffer 에러 해결법
[server.js]
app.use((req, res, next) => {
  res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
  res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
  next();
});

=================
[header.pug]
...
else 
    img.header__avatar(src="/" + loggedInUser.avatarUrl, crossorigin)

3. thumbnail

const handleDownload = async () => {
  const ffmpeg = createFFmpeg({ log: true });
  await ffmpeg.load();
  ...

  // ss>> 영상의 특정시간대로 가게해줌, -frames:v>> 이동한시간의 스샷n장 찍음
  await ffmpeg.run(
    "-i",
    "recording.webm",
    "-ss",
    "00:00:01",
    "-frames:v",
    "1",
    "thumbnail.jpg"
  );

  const thumbFile = ffmpeg.FS("readFile", "thumbnail.jpg");

  //create blob from array  << arrayBuffer로 만들어야함
  const thumbBlob = new Blob([thumbFile.buffer], { type: "image/jpg" });

  const thumbUrl = URL.createObjectURL(thumbBlob);

  const thumbA = document.createElement("a");
  thumbA.href = thumbUrl;
  thumbA.download = "MyThumbnail.jpg";
  document.body.appendChild(thumbA);
  thumbA.click();
	...
};
  • 속도향상위해 file unlink 추가함
const handleDownload = async () => { 
  ffmpeg.FS("unlink", "recording.webm");
  ffmpeg.FS("unlink", "output.mp4");
  ffmpeg.FS("unlink", "thumbnail.jpg");

  URL.revokeObjectURL(mp4Url);
  URL.revokeObjectURL(thumbUrl);
  URL.revokeObjectURL(videoFile);
}

4. thumbnail upload

  • actonBtn.disabled = true, false 로 작동중 버튼사용유무 조절함
  • Video.js >> thumbUrl 추가함
[video.js]
const videoSchema = new mongoose.Schema({
  ...
  thumbUrl: { type: String, required: true },
  
===========================
[upload.pug]
form(method="POST", enctype="multipart/form-data") 
        label(for="video") Video File 
        input(type="file", accept="video/*", required, id="video", name="video")
        label(for="thumb") Thumbnail File 
        input(type="file", accept="image/*", required, id="thumb", name="thumb")
===========================
[videoRouter.js]
videoRouter
  .route("/upload")
  .all(protectorMiddleware)
  .get(getUpload)
  .post(videoUpload.single("video"), postUpload);
  
  >>
  
  videoRouter
  .route("/upload")
  .all(protectorMiddleware)
  .get(getUpload)
  .post(
    videoUpload.fields([
      { name: "video", maxCount: 1 },
      { name: "thumb", maxCount: 1 },
    ]),
    postUpload
  );
  • >> upload 에서 파일 두개보냄 >> videoRouter 수정필요 
    • middlewares >> videoUpload >> upload form 으로부터 video 파일받음
    • >> post(videoUpload).single("video") >> .fields( {} ) 로 바꿔야 함

[videoContorller.js]
export const postUpload = async (req, res) => {
  ..
  const { video, thumb } = req.files;
  ..
  try {
    const newVideo = await Video.create({
      ..
      fileUrl: video[0].path,
      thumbUrl: thumb[0].path,
      ..
    });
    ..
};
  • 홈화면에 섬네일이미지 추가하기
    • 윈도우는 백슬래시로 path찾음 >> 변경필요 
[Video.js]

videoSchema.static("changePathFormula", (urlPath) => {
  return urlPath.replace(/\\/g, "/");
});

----------------------
[videoController.js]
export const postUpload = async (req, res) => {
  ...
      thumbUrl: Video.changePathFormula(thumb[0].path),

 

'노마드 > 유튜브' 카테고리의 다른 글

ch16. comment section  (0) 2022.09.05
ch15. flash message  (0) 2022.09.05
ch13. video recorder  (0) 2022.09.01
ch12. Views api << 템플릿 렌더링 X  (0) 2022.09.01
ch11.6~ video play (2)  (0) 2022.08.31

관련글 더보기

댓글 영역