FrameVOX: 에이전트가 만든 소셜 비디오용 영상 제작 CLI
출처: Dev.to
FrameVOX: 에이전트가 만든 소셜 비디오용 비디오 제작 CLI
FrameVOX는 제가 새로 만든 비디오 제작 프로젝트입니다.
레포지토리:
https://github.com/tecnomanu/framevox
짧게 말하면: FrameVOX는 HTML 구성, 음성 생성, 템플릿, 렌더링을 활용해 바로 배포 가능한 비디오를 만들 수 있는 CLI입니다.
보다 정확히 말하면: FrameVOX는 HyperFrames와 TTS 제공자를 감싸는 얇은 실용 레이어입니다. HyperFrames 자체를 대체하는 것이 아니라, 에이전트와 사람이 비디오 아이디어를 실제 MP4 파일로 바꿀 때 흔히 겪는 여러 번거로운 과정을 한데 묶어줍니다.
문제점
HTML‑to‑video 도구는 강력하지만, 제작 워크플로에는 작은 실패 지점이 많이 존재합니다.
수작업으로 진행한다면 전형적인 흐름은 다음과 같습니다:
mkdir my-promo
cd my-promo
# index.html, style.css, assets, timing, scenes, voice script 만들기
# data‑attribute를 올바르게 연결하기
# 음성 생성 또는 녹음하기
# 제공자가 raw audio를 반환하면 PCM을 MP3로 변환하기
# 음성 파일이 정상인지 확인하기
# lint 실행하기
# headless Chrome으로 렌더링하기
# 타이밍 수정하기
# 다시 렌더링하기
이 단계들이 불가능한 것은 아니지만, 모두 합쳐지면 워크플로에 마찰이 생겨 특히 AI 에이전트가 작업을 수행할 때 흐트러지기 쉽습니다.
에이전트는 파일을 만드는 데는 능숙하지만, 숨겨진 설정이 필요하거나 키가 누락되었거나 템플릿이 불분명하거나, 음성 변환을 수동으로 해야 하거나, 렌더링이 늦게 실패하는 상황에서는 약합니다.
FrameVOX는 이 과정을 명시적으로 만들어 줍니다:
npx framevox init my-promo --template minimal-mobile
npx framevox add-key gemini YOUR_GEMINI_KEY
npx framevox voice
npx framevox render
이렇게 하면 하나의 프로젝트 폴더, 하나의 음성 파일, 하나의 렌더링된 MP4가 생성됩니다.
FrameVOX가 감싸는 것
FrameVOX는 HTML‑to‑video 레이어로 HyperFrames를 사용합니다.
HyperFrames는 여전히 렌더링 엔진이며, 구성 모델, 프리뷰, lint, 검사, 렌더링 파이프라인을 제공합니다. FrameVOX는 그 위에 다음과 같은 제작용 래퍼를 추가합니다:
- 템플릿 기반 프로젝트 스캐폴딩
- TTS 키 저장
- Gemini, Piper, ElevenLabs 음성 생성
- 생성된 오디오에 대한 MD5 무결성 검사
- 렌더링 전 lint 기본값
- 템플릿 탐색
- 자동 생성 레시피와 프로젝트 문서
- 에이전트 스킬 설정
- 업데이트 및 상태 명령
이 구분은 중요합니다. FrameVOX는 전체 디자인 앱이 되려는 것이 아니라, 실제 렌더러를 중심으로 반복 가능한 프로젝트 워크플로를 만들고자 합니다.
요구 사항
현재 FrameVOX가 필요로 하는 환경은 다음과 같습니다:
Node.js >= 22
ffmpeg
Chrome 또는 Chromium
piper 바이너리 (Piper를 사용할 경우에만)
패키지는 다음과 같이 노출됩니다:
{
"name": "framevox",
"version": "0.2.0",
"bin": {
"framevox": "bin/framevox.js"
}
}
HyperFrames는 의존성으로 번들되어 있기 때문에, 일반적인 렌더 경로에서는 별도로 설치할 필요가 없습니다.
프로젝트 구조
init 명령을 실행하면 프로젝트는 다음과 같은 형태가 됩니다:
my-promo/
├── index.html
├── voice.json
├── DESIGN.md
├── assets/
├── voice.mp3
├── output.mp4
├── RECIPE.md
└── .framevox/
└── config.json
각 파일의 역할은 다음과 같습니다:
index.html– 실제 비디오 구성 파일voice.json– 음성 스크립트DESIGN.md– 제품, 브랜드, 색상, 카피 등을 편집 전에 정리하는 곳assets/– 로고 및 기타 미디어 파일.framevox/config.json– 제공자와 렌더 메타데이터 저장RECIPE.md– 프로젝트 제작 과정을 문서화
에이전트 기반 워크플로에서는 이러한 구조가 중요합니다. 에이전트는 DESIGN.md를 검토하고, 구성 파일을 수정하고, voice.json을 조정하고, 오디오를 재생성한 뒤, 어디에 무엇이 있는지 추측하지 않고 다시 렌더링할 수 있습니다.
템플릿
FrameVOX는 패밀리별로 묶인 템플릿을 제공합니다. 현재 내장된 패밀리는 다음과 같습니다:
minimal
promo
studio
immersive
각 패밀리는 모바일과 데스크톱 변형을 가질 수 있습니다. 예시:
templates/promo/
├── style.css
├── family.json
├── mobile/
└── desktop/
이를 통해 하나의 패밀리가 시각적 아이덴티티를 공유하면서도 여러 출력 포맷을 지원할 수 있습니다.
유용한 명령들:
framevox templates
framevox templates --json
framevox templates add promo
framevox templates install promo
framevox init my-reel --template promo-mobile
템플릿 검색 순서는 다음과 같습니다:
project .framevox/templates/
user ~/.framevox/templates/
builtin templates
즉, 실험 단계에서 재사용 가능한 브랜드 템플릿까지 깔끔한 경로를 제공합니다. 기본 패밀리로 시작하고, 프로젝트에 복사한 뒤 브랜드에 맞게 커스터마이징하고, 재사용 가능해지면 전역에 설치하면 됩니다.
음성 생성
FrameVOX는 여러 TTS 경로를 지원합니다:
framevox add-key gemini YOUR_GEMINI_KEY
framevox add-key elevenlabs YOUR_ELEVENLABS_KEY
framevox add-key piper-voice en_US-lessac-medium
framevox keys
키는 ~/.framevox/.env에 저장되며 절대 커밋해서는 안 됩니다.
음성 파일은 간단합니다:
{
"prompt": "따뜻하고 대화체 톤으로 읽어 주세요:",
"text": "Meet Crewdesk... 현장 팀을 정렬해 주는 스케줄링 툴입니다."
}
긴 영상의 경우 씬을 활용할 수 있습니다:
{
"prompt": "에너지 넘치는 제품 출시 톤으로 읽어 주세요:",
"gap": 0.3,
"scenes": [
{ "id": "hook", "text": "팀 일정이 또 바뀌었어요." },
{ "id": "problem", "text": "이제 세 명이 서로 다른 플랜을 보고 있습니다." },
{ "id": "solution", "text": "Crewdesk는 모든 교대, 경로, 업데이트를 한 곳에 모아 줍니다." },
{ "id": "cta", "text": "오늘 첫 스케줄을 시작해 보세요." }
]
}
특정 파트를 재생성할 수도 있습니다:
framevox voice --scene hook
framevox voice --scene 2
생성 후 FrameVOX는 음성 타임라인을 기록합니다. 이는 비디오 타이밍을 텍스트 길이 추측이 아니라 실제 오디오 길이에 기반해 맞출 수 있게 해 주기 때문에 중요합니다.
Gemini용 감정 태그
Gemini TTS는 인라인 태그를 통해 전달 방식을 바꿀 수 있습니다:
{
"prompt": "스페인어 리오플라텐세, 따뜻하고 대화체로 읽어 주세요:",
"text": "Bueno che, mirá esto... [excited]Esto acelera todo.[/excited] ... [whisper]Y no tenés que tocar ffmpeg a mano.[/whisper]"
}
태그는 말해야 할 단어가 아니라 전달 지시입니다.
예시:
[eloquent]...[/eloquent]– 연극적인 강조 강화[sad]...[/sad]– 차분한 전달[whisper]...[/whisper]– 낮은 목소리[excited]...[/excited]– 높은 에너지
짧은 프로모션에서는 여러 API 호출보다 text 필드 하나에 일시정지를 넣는 것이 더 효율적일 수 있습니다. 긴 스크립트에서는 씬을 활용하면 제어가 쉬워지고 재생성도 간편합니다.
렌더 워크플로
주된 렌더 경로는 의도적으로 단순합니다:
framevox lint
framevox preview
framevox render
렌더 명령은 옵션을 받을 수 있습니다:
framevox render --out 