Remotion 내부 아키텍처 — 프레임을 비디오로 바꾸는 파이프라인
Headless Chrome → 스크린샷 → FFmpeg 인코딩까지의 렌더링 파이프라인 해부
Remotion이 React 코드를 비디오로 변환하는 과정은 웹 기술의 창의적 활용입니다.
먼저 Webpack 또는 esbuild가 React 컴포넌트를 브라우저 실행 가능한 번들로 빌드합니다. 이 번들에는 비디오의 메타데이터(fps, 해상도, 총 프레임 수)가 포함됩니다.
다음으로 Puppeteer가 Headless Chrome을 실행하고, 번들된 페이지를 로드한 뒤, 프레임 번호를 0부터 마지막까지 순차적으로 바꾸면서 각 프레임을 PNG/JPEG로 스크린샷합니다. 이때 delayRender()/continueRender() API로 비동기 데이터 로딩(API 호출, 폰트 로드 등)이 완료될 때까지 스크린샷을 지연시킬 수 있습니다.
마지막으로 FFmpeg가 이미지 시퀀스를 받아 H.264(MP4) 또는 VP8/VP9(WebM)으로 인코딩합니다. 오디오 트랙이 있다면 함께 mux합니다.
멀티스레드 렌더링도 지원합니다. --concurrency 옵션으로 여러 Chrome 인스턴스를 동시에 실행하여 프레임을 분산 처리할 수 있습니다.
동작 흐름
Webpack/esbuild가 React 컴포넌트 + 메타데이터(fps, width, height, durationInFrames)를 번들링
Puppeteer가 Headless Chrome 인스턴스를 실행하고 번들된 HTML 페이지를 로드
프레임 0부터 N까지 순회하며 currentFrame을 주입 → React 리렌더링 → 스크린샷(PNG/JPEG)
delayRender()가 활성화된 경우 continueRender() 호출까지 스크린샷 대기 (비동기 안전)
FFmpeg가 이미지 시퀀스 + 오디오 트랙을 H.264/VP9로 인코딩하여 최종 MP4/WebM 출력
장점
- ✓ 웹 표준 기술만 사용: Chrome + FFmpeg라는 검증된 조합
- ✓ CSS/SVG/Canvas/WebGL 등 브라우저가 렌더링할 수 있는 모든 것이 비디오 프레임이 됨
- ✓ delayRender로 비동기 데이터 완료 보장 → 데이터 기반 비디오에서 빈 프레임 방지
단점
- ✗ Chrome 의존: Headless Chrome이 없는 환경에서는 렌더링 불가
- ✗ 메모리 사용량: 풀HD 프레임을 메모리에 유지하므로 긴 비디오는 RAM 소비 큼
- ✗ 디버깅 복잡: 렌더링 에러가 Puppeteer/Chrome/FFmpeg 중 어디서 발생했는지 특정 어려움