본문으로 건너뛰기

HTML로 영상을 만든다 — HeyGen HyperFrames 써 보기

리액트 없이 index.html 하나로 MP4를 뽑는 오픈소스. 설치부터 최소 예제, Remotion과의 갈림길, 그리고 조용히 깨지는 지점까지.

영상 자동 생성 도구는 그동안 대부분 리액트를 요구했다. Remotion이 대표적이다. 강의 슬라이드를 이미 HTML로 만들어 둔 입장에서는 그걸 다시 컴포넌트로 옮기는 게 일이었다.

HeyGen이 3월에 공개한 HyperFrames는 그 전제를 바꿨다. index.html 하나를 그대로 MP4로 렌더한다. Apache-2.0이고, 9월 17일 기준 스타 5만 1천 개에 최신 버전은 v0.8.46이다.

직접 렌더해 봤다

먼저 결과부터. 아래 8초 영상은 index.html 한 장을 이 도구로 렌더한 것이다. 1920×1080, 30fps, 240프레임, 파일 크기 359KB, 렌더에 걸린 시간 7.5초.

렌더된 영상에서 뽑은 네 프레임
같은 영상에서 20·100·170·230번 프레임을 뽑은 것. GSAP 타임라인을 프레임 단위로 seek 해서 캡처하므로 몇 번 돌려도 같은 그림이 나온다.

환경은 macOS, Node 25.8, ffmpeg 8.1이었다. 설치부터 첫 렌더까지 명령 세 줄이면 됐다.

무엇을 하는가

입력은 HTML 한 장이다. 루트 <div>에 컴포지션 id와 해상도를 달고, 안의 요소에 시작 시각과 길이를 적는다. <video>, <audio>, <h1> 같은 평범한 태그가 그대로 클립이 된다.

렌더러는 헤드리스 크롬에서 타임라인을 프레임 단위로 옮겨 가며 화면을 캡처하고 FFmpeg로 묶는다. 벽시계를 따라가지 않고 프레임을 직접 움직이기 때문에 같은 입력이면 항상 같은 영상이 나온다. 공식 문서가 결정적(deterministic)이라고 부르는 지점이고, CI에서 영상 회귀 테스트를 돌릴 수 있다는 뜻이다.

출력은 MP4, MOV(ProRes 4444), WebM, GIF, PNG 시퀀스, HLS 여섯 가지다. 기본 30fps.

설치와 실행

Node.js 22 이상과 FFmpeg가 필요하다. FFmpeg는 직접 깔아야 하고, 브라우저는 CLI가 관리한다.

npx hyperframes init my-video
cd my-video
npx hyperframes preview   # 브라우저 라이브 프리뷰
npx hyperframes render    # MP4 출력

렌더 전에 점검 두 개를 먼저 돌리는 편이 낫다.

npx hyperframes lint     # 프로젝트 구조
npx hyperframes check     # 런타임·레이아웃·모션·미디어 문제 탐지
npx hyperframes doctor    # 런타임, 브라우저, FFmpeg 설치 상태

로컬 외에 Docker, AWS Lambda, Google Cloud Run, HeyGen 호스팅 렌더를 고를 수 있다. 로컬 렌더는 HeyGen 크레딧을 쓰지 않는다.

최소 예제

README에 있는 예제가 이 도구의 계약을 그대로 보여 준다.

<div id="stage" data-composition-id="launch" data-start="0" data-width="1920" data-height="1080">
  <video class="clip" data-start="0" data-duration="6" data-track-index="0" src="intro.mp4" muted playsinline></video>

  <h1 id="title" class="clip" data-start="1" data-duration="4" data-track-index="1">Launch day</h1>

  <audio data-start="0" data-duration="6" data-track-index="2" data-volume="0.5" src="music.wav"></audio>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
  <script>
    const tl = gsap.timeline({ paused: true });
    tl.from("#title", { opacity: 0, y: 40, duration: 0.8 }, 1);
    window.__timelines = window.__timelines || {};
    window.__timelines.launch = tl;
  </script>
</div>

지켜야 할 것이 두 개 보인다. 타임라인을 paused로 만들고, 컴포지션 id와 같은 키로 window.__timelines에 등록한다. 렌더러가 프레임을 직접 옮기려면 이 두 개가 전제다.

Remotion과 갈리는 지점

README가 Remotion을 직접 언급한다. 둘 다 헤드리스 크롬과 FFmpeg로 렌더하고, 다른 건 저작 방식이다. Remotion은 리액트 컴포넌트에 걸었고 HyperFrames는 순수 HTML에 걸었다.

기준은 "우리 팀이 리액트를 쓰는가"가 아니다. 소재가 이미 HTML인가다. 웹사이트, 슬라이드, 피그마에서 내보낸 마크업이 있으면 전환 비용이 거의 없다. 반대로 이미 리액트 디자인 시스템과 차트 라이브러리를 쓰고 있으면 Remotion에서 그걸 공짜로 가져간다.

공식 비교 문서가 Remotion이 나은 점도 스스로 적어 뒀다. 더 오래됐고 자료가 많고 Lambda 렌더가 성숙하다는 것, 그리고 모델이 머릿속에 담기 더 쉽다는 것이다. Remotion은 프레임 번호를 받는 순수 함수 하나지만, HyperFrames는 위의 계약을 지켜야 하고 어기면 에러가 아니라 조용히 잘못 렌더된다. 벽시계를 쓰거나 시드 없는 난수를 쓰면 그렇게 된다.

Remotion에서 옮기는 스킬도 있다. 문서는 80% 정도가 기계적으로 번역되고 나머지는 번역을 거부하고 표시한다고 말한다. 이 수치는 문서의 자체 주장이다.

진짜 노림수는 에이전트다

README의 Quick Start 첫 줄이 CLI가 아니다.

npx skills add heygen-com/hyperframes

스킬 20개가 /hyperframes 라우터 아래 붙어 있다. GitHub PR을 영상으로, 웹사이트 URL을 런치 영상으로, 음악을 비트 싱크 영상으로 만드는 워크플로가 각각 따로 있다. Claude Code, Cursor, Gemini CLI, Codex에서 돌아간다.

논리는 단순하다. 학습 데이터에 HTML은 압도적으로 많고 Remotion 코드는 극히 적다. 사람이 쓰기 쉬운 포맷을 고른 게 아니라 모델이 이미 아는 포맷을 고른 것이다. 6개월 만에 스타 5만이 붙은 이유도 기술보다 이 타이밍에 가깝다.

직접 하면서 걸린 것 세 개

1. 한글 폰트 하나에 렌더 시간이 4.5배 차이 났다. 처음에는 font-family 에 "Apple SD Gothic Neo" 만 적고 돌렸다. 렌더가 34.0초 걸렸다. 로그를 보니 시스템 폰트 52.8MB를 영상에 임베드하고 있었다.

hyperframes check 가 원인을 정확히 짚어 줬다. "@font-face 선언 없이 쓴 폰트가 있다"는 에러였고, OS 기본 폰트는 내려받을 파일이 없으니 src: local() 로 적으라고 안내했다.

@font-face {
  font-family: "Apple SD Gothic Neo";
  src: local("AppleSDGothicNeo-Regular");
}

이 다섯 줄을 넣자 같은 8초 영상 렌더가 7.6초로 떨어졌다. 화면은 똑같다.

2. 클립을 나란히 쓰면 겹친다. 제목, 막대 그래프, 설명을 각각 class="clip" 으로 만들었더니 셋이 화면에서 겹쳤다. 클립은 나란히 놓이는 블록이 아니라 트랙별로 쌓이는 레이어다. 한 화면에 여러 요소를 배치할 때는 클립 하나 안에 넣고 그 안에서 CSS 로 배치해야 한다. 이것도 check 가 "두 텍스트 블록이 겹쳐 읽을 수 없다"로 잡아 줬다.

3. check 는 프레임별로 명암비까지 본다. 막대 위 라벨을 밝은 회색으로 두자 "1:1 (need 3:1, t=0.444s)" 라는 에러가 떴다. 막대가 아직 0 높이일 때 라벨이 어두운 배경에 어두운 글자로 놓였던 것이다. 라벨을 막대가 자란 뒤에 페이드인하도록 바꾸니 24/24 text checks pass WCAG AA 로 통과했다.

영상 도구에서 접근성 검사를 프레임 단위로 돌리는 건 처음 봤다. 자동 생성 파이프라인에 넣을 거라면 이 검사가 실질적인 안전장치가 된다.

쓰기 전에 알아야 할 것

아직 1.0이 아니다. 6개월 동안 npm 버전이 399개 나왔다. 하루 두 개 이상이다. API가 흔들린다고 보는 게 맞다. 내가 돌린 버전은 v0.8.46이다.

성능 함정이 CSS에 있다. 공식 문서의 실측으로, 1080p 300프레임 렌더가 blur 계열 CSS 선언 하나 때문에 9.8초에서 25.0초로 늘어난다. 화면은 픽셀 단위로 같았다. 투명 WebM은 VP9라 MP4보다 훨씬 오래 걸린다.

포맷별 제약이 다르다. GIF는 오디오가 없고, MOV는 비트레이트 옵션을 거부하고, HLS는 클라우드 렌더에서 안 된다.

개발자용 도구다. HeyGen 본 편집기와 별개 제품이고, 결국 터미널에서 명령을 돌려야 한다.

오디오는 예상보다 본격적이다. 내레이션이 점유한 대역만 음악을 눌러 주는 보이스오버 카브, 이펙트 체인, 볼륨 오토메이션, 서브믹스 버스까지 있다.

어디에 쓸까

프로덕션 사례가 실명으로 공개돼 있다. HeyGen 본체, tldraw가 PR 워크스루 영상에, THU-MAIC가 AI 생성 교실을 원클릭 MP4로 내보내는 데 쓴다. 강의 쪽에서는 Mini Course Generator가 코스 제작 워크플로에 붙였다.

나라면 순서를 이렇게 잡는다. 슬라이드 HTML이 이미 있으면 그걸 그대로 영상으로 뽑는 것부터 해 본다. 짧은 도구 소개 영상을 파이프라인으로 자동화하는 것도 실익이 있다. 장편이나 대량 렌더 안정성이 걸린 일이라면 Remotion Lambda가 아직 성숙하다. 이건 HyperFrames 공식 문서가 인정하는 내용이다.

저장소: heygen-com/hyperframes · 문서: hyperframes.heygen.com · 이 글의 영상과 캡처는 2026-09-18에 v0.8.46으로 직접 렌더한 것이다.

15초 요약

인스타그램 릴스로도 올린 영상입니다. HeyGen HyperFrames 로 이 글에서 바로 렌더했습니다.

CONTACT

컨설팅 · 강의 문의

회사 메일로 남겨 주시면 구성과 비용을 안내드립니다.

gmail·naver 같은 개인 메일은 받지 않습니다.