프로젝트 개발 환경 셋업
react와 typescript를 사용해서 개발했으며 번들링은 webpack과 esbuild(esbuild-loader)를 사용했습니다. 배포는 Vercel를 사용했습니다.
webpack 설정 및 리액트 환경 설정에 대한 설명은 생략하겠습니다.
Node 패키지 추가
$ npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin esbuild esbuild-loader typescript$ npm i react react-dom react-dropzone react-feather @ffmpeg/core @ffmpeg/ffmpeg @types/react @types/react-dom @emotion/react @emotion/styled
SharedArrayBuffer
ffmpeg.wasm 깃헙 리드미에도 나와있지만 SharedArrayBuffer는 교차 출처가 격리된 페이지(cross-origin isolation)에서만 사용할 수 있습니다. 그래서 사용하기 위해서는 서버 헤더에 Cross-Origin-Embedder-Policy
과 Cross-Origin-Opener-Policy
를 추가해줘야 합니다.
Vercel에서는 vercel.json을 통해서 헤더를 설정해 줄 수 있다 보니 데모 배포를 Vercel로 사용한 이유이기도 합니다.
Webpack Dev Server 헤더 설정 추가
Vercel 배포 서버 헤더 설정 추가
FFmpeg 로드
ffmpeg를 불러와 주는 작업을 해줍니다.
처음에는 App.tsx에서 ffmpeg를 생성하였으나, 이후 Logger 컴포넌트 등 다른 곳에서도 생성된 ffmpeg를 호출해야 해서 ffmpeg.ts 파일을 분리 후 싱글톤 객체로 만들어 주었습니다.
ffmpeg.ts
App.tsx
파일업로드 추가
react-dropzone을 사용해서 간단하게 구현
불러온 파일 미리보기 기능 추가
App.tsx
PreviousConvertStep.tsx
useBlobUrl.ts
FileCard.tsx
변환 코드 호출
useFFmpegConvert 커스텀 훅에 convert 함수를 추가 후 변환된 값을 return 하도록 구현
no such file or directory 이슈
개발 도중 변환 과정에서 no such file or directory 이슈가 발생해서 확인해보니 인코딩 이슈가 있어 convert 코드 쪽에 EncodeURI를 추가하여 변환하여 해결하였습니다.
컨버팅 로딩추가
App.tsx에 컨버팅 되는 동안 보여 줄 프로그래스 바를 추가해줍니다.
변환된 파일 원본이랑 비교 및 다운로드 기능 추가
ConvertResultContainer.tsx
App.tsx
file이 있고 isDone이 true면 보여주도록 App.tsx도 수정해줍니다.
마치며
아쉬웠던건 아직 제대로 지원하는 브라우저가 Chrome밖에 없어서 Firefox나 다른 브라우저에서도 지원이 됐으면 했었네요..
(글쓴 시점 기준: 2021–08–16)
읽어주셔서 감사합니다. 🙏
참고
- https://github.com/ffmpegwasm/ffmpeg.wasm
- https://web.dev/cross-origin-isolation-guide/
- https://fireship.io/lessons/wasm-video-to-gif/
- https://blog.chosunghyun.com/ffmpeg-wasm-gif-converter-study/
- https://marshall-ku.com/web/tips/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%97%90%EC%84%9C-gif-mp4-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0