본문으로 바로가기

TIL 2021-11-14 ffmpeg.wasm, cross-origin isolation,webpack

category TIL 2021. 11. 14. 23:36

mp3를 mp4로 변환하는 방법을 찾으면서 생각해본 방법은 두가지였다.

 

1. video tag에 mp3를 달았을떄 동영상 컨트롤러처럼 나오느냐?

 

2. FFMPEG을 통한 MP3 -> MP4 변환

 

 

1의 경우에는 된다면 간단하니 정말 좋고 안되면 말면 식으로 생각해본 방법이었는데, 역시나? 안되었다.

 

그래서 어쩔수 없이 FFMPEG을 통해서 변환하는 방법을 사용하기로 하였다.

 

 

근데 내가 만들고 싶은 것은

 

MP3파일에 사진을 붙여 MP4 파일을 만드는 홈페이지고, 브라우저 상에서 운용되어야하였다.

 

따라서 웹어셈블리 형식으로 포팅된 FFMPEG.WASM이란 라이브러리를 사용하기로 하였다.

 

 

FFMPEG.WASM이란

 

순수 자바스크립트와 FFMPEG를 통해 브라우저 내에서 바로 녹화, 변환등을 실행해줄수 있도록 해주는 라이브러리다.

 

 

const fs = require('fs');
const { createFFmpeg, fetchFile } = require('@ffmpeg/ffmpeg');

const ffmpeg = createFFmpeg({ log: true });

(async () => {
  await ffmpeg.load();
  ffmpeg.FS('writeFile', 'test.avi', await fetchFile('./test.avi'));
  await ffmpeg.run('-i', 'test.avi', 'test.mp4');
  await fs.promises.writeFile('./test.mp4', ffmpeg.FS('readFile', 'test.mp4'));
  process.exit(0);
})();

기본적인 코드 형태는 이렇다.

 

ffmpeg를 로드하고, FS을 통해 파일을 읽거나 쓴다.

 

FS는 MEMFS로 먼저 저장된 다음 Emscription의 FS METHOD을 통해 입출력한다.

 

MEMFS는 테스트할떄 사용할 수 있는 In-memory 가상 filesystem이다.

 

FS.('writeFile')을 통해 가상 파일시스템인 MEMFS에 저장을 하고 그것에서 실제 ffmpeg을 실행하고

 

저장한 결과를 FS.('readFile')을 통해서 다시 MEMFS에서 가져오는 방식인것 같다

 

 

 

COEP와 COOP

발생했던 문제는 바로 공식문서에도 쓰여있던

 

SharedArrayBuffer is only available to pages that are cross-origin isolated. So you need to host 
your own server with Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin headers to use ffmpeg.wasm.

FFMPEG.WASM에 사용되는 SharedArrayBuffer는 cross-origin isolated된 페이지에만 사용할 수 있다는 것이다.

 

Emscription에서 pthread 코드에서 SharedArrayBuffer를 사용하기 떄문에 발생하는 문제다.

 

 

필자같은 경우에는 Vercel을 통해서 deploy할 것이기 떄문에

 

vercel.json을 생성하여

{
	"headers": [
		{
			"source": "/(.*)",
			"headers": [
				{
					"key": "cross-origin-opener-policy",
					"value": "same-origin"
				},
				{
					"key": "cross-origin-embedder-policy",
					"value": "require-corp"
				}
			]
		}
	]
}

로 관련 헤더들을 설정해주었다.

 

이 헤더들은 cross-origin 문서에서 로드되도록 허락되지 않은 리소스들이나 iframe의 로딩을 막아준다. 이런 설정이 없다면 강력한 기능들을 안전하게 사용한다는 보장이 없다.

 

self.crossOriginIsolated를 통해 상태를 알 수 있다.

 

 

 

webpack

단순하게 가고 싶었기에 별도의 보일러플레이트없이 만들었기에 webpack 설정을 처음으로 시작부터 끝까지 하게 되었다.

 

const path = require('path');

module.exports = {
	entry: './src/index.js',
	output: {
		filename: 'main.js',
		path: path.resolve(__dirname, 'public'),
	},
};

entry는 번들링의 시작이 될 부분을 의미한다.

 

Mutiple entry를 가져 여러개의 번들로 분할하고 병렬, 혹은 요청마다 다른 번들들을 제공할수도 있다.

 

output은 번들의 결과를 내뱉는 곳이며 이것은 import하여 html에 불러오는 것으로 전체 자바스크립트 코드를 불러오는 것과 동일한 것이다. 리액트도 동일한 방식.

 

 

시간날때 읽어볼것들(엔트리 포인트와 코드 스플리팅)

 

https://webpack.js.org/concepts/entry-points/

 

Entry Points | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

https://webpack.kr/guides/code-splitting/

 

Code Splitting | 웹팩

웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.

webpack.kr

 

 

 

Reference

 

https://web.dev/coop-coep/

 

Making your website "cross-origin isolated" using COOP and COEP

Some web APIs increase the risk of side-channel attacks like Spectre. To mitigate that risk, browsers offer an opt-in-based isolated environment called cross-origin isolated. Use COOP and COEP to set up such an environment and enable powerful features like

web.dev

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer

 

SharedArrayBuffer - JavaScript | MDN

The SharedArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer, similar to the ArrayBuffer object, but in a way that they can be used to create views on shared memory. Unlike an ArrayBuffer, a SharedArrayBuffer cannot beco

developer.mozilla.org

 

 

https://github.com/simonc/memfs

 

GitHub - simonc/memfs: MemFs provides a fake file system that can be used for tests. Strongly inspired by FakeFS.

MemFs provides a fake file system that can be used for tests. Strongly inspired by FakeFS. - GitHub - simonc/memfs: MemFs provides a fake file system that can be used for tests. Strongly inspired b...

github.com