WebAssembly Video Transcode

Jun's Coding Journey·2022년 11월 28일
0

[Challenge] Youtube Clone

목록 보기
19/19

FFmpeg is a free and open -source software consisting of a suite of libraries and programs for handling video, audio, and other multimedia files and streams. With FFmpeg, we can do a lot of things with media-related files such as converting a video format, adding subtitles, changing the quality of the video, streaming a video, etc. To use FFmpeg, we also need a good server that can run the video smoothly. However, maintaining a server can become very expensive if we are trying to upload quality videos. This is where WebAssembly comes into play.

WebAssembly is an open standard that allows websites to run very fast code. Initially, we can only write HTML, CSS, and JavaScript on our frontend. However, WebAssembly allows us to use languages other than JavaScript that runs faster on the frontend. In short, WebAssembly allows us to run high quality program other than JavaScript(which may lack power) on the browser.

When we are running FFmpeg to convert files, we are assuming the file will be converted on the users computer.

We will be using WebAssembly to run FFmpeg.

To install WebAssembly supported FFmpeg, we install the following npm package:

npm i @ffmpeg/ffmpeg @ffmpeg/core

Transcode Video

After installing FFmpeg, we import the code on our JavaScript file.

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

Next, we implement FFmpeg on our function that handles the download process. Here, it is essential that we use a promise method to run the code as we are running a heavy code that we usually do not run on JavaScript.

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

To create a file in the FFmpeg world, we use the writeFile method. Then, we need to give a name for the file(this can be any name). Finally, we need to give a binary data which is the data for the video file.

ffmpeg.FS("writeFile", "recording.webm", await fetchFile(videoFile));

To run the code, we implement the code on the FFmpeg documentation (ffmpeg.org/ffmpeg.html).

Order: input, name of file, frame rate, output

await ffmpeg.run("-i", "recording.webm", "-r", "60", "output.mp4");

Download Transcoded Video (Converting to Mp4)

To load our converted file, we use the readFile method and put the file we want to load. This file will be represented in an array of positive numbers.

const mp4File = ffmpeg.FS("readFile", "output.mp4");

Next, we need to created a blob using all the number data which represents the video file. To access, this array, we need to use the buffer property. Make sure to also add the type of file that will be converted.

const mp4Blob = new Blob([mp4File.buffer], { type: "video/mp4" });

We also need to make a URL for data that is received when we stopped recording a video. At this point, we will finally be able to get a blob URL that will signal that the file is converted from webm to mp4.

const mp4Url = URL.createObjectURL(mp4Blob);

Don't forget to change the file format of the anchors

  a.href = mp4Url;
  a.download = "MyRecording.mp4";

Thumbnail

To capture a thumbnail, we need to run the ffmpege.run function again. Inside the function, we input the file we want to use, the point in which we want to capture our thumbnail, and choose the number of times we want to capture.

await ffmpeg.run(
  "-i",
  "recording.webm",
  "-ss",
  "00:00:01",
  "-frames:v",
  "1",
  "thumbnail.jpg"
);

Similar to the mp4File, we create a file and blob for the thumbnail.

const thumbFile = ffmpeg.FS("readFile", "thumbnail.jpg");
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();

To increase speed, we can unlink the the download process.

ffmpeg.FS("unlink", "recording.webm");
ffmpeg.FS("unlink", "output.mp4");
ffmpeg.FS("unlink", "thumbnail.jpg");

URL.revokeObjectURL(mp4Url);
URL.revokeObjectURL(thumbUrl);
URL.revokeObjectURL(videoFile);
profile
Greatness From Small Beginnings

0개의 댓글