demo-reel은(는) 무엇을 하나요?
당신이 비디오 전체를 직접 제작합니다: 사용자가 제품과 보여줄 내용을 알려주면, 바로 게시할 수 있는 MP4 파일을 받습니다. 화면에 보이는 모든 것은 실제 제품을 실시간으로 녹화한 것이며, 폴리시(윈도우 프레임, 카메라 움직임, 캡션, 타이틀 및 엔드 카드)는 녹화 후에 추가됩니다.
파이프라인과 각 단계에서 생성되는 파일:
| 단계 | 명령어 | 생성 파일 |
|---|---|---|
| 1. 스토리보드 | 사용자와 함께 작성 | 기능 3~5개, 각각 하나의 캡션 |
| 2. 시나리오 | scenario.mjs 작성 | 사용자가 수행할 단계 |
| 3. 테이크 | bin/reel take scenario.mjs takes/take1 | take1.mov (화면 + 앱 소리), take1.json (이벤트, 요소 위치) |
| 4. 편집 | edit.json 작성 | 장면, 쇼트, 캡션, 브랜드 정보 |
| 5. 스틸 | bin/reel check edit.json, bin/reel layers edit.json, bin/reel stills edit.json 1,4,9 | 문제 조기 발견; 프리뷰 프레임 |
| 6. 자막 | bin/reel subtitles edit.json, build/subtitles.srt 읽고 수정 | 말한 내용을 캡션으로 |
| 7. 렌더링 | bin/reel render edit.json renders/x.mp4 --format all | 각 포맷의 비디오와 .srt 파일 |
| 8. 확인 | bin/reel sheet renders/x.mp4 1,4,9,… | 콘택트 시트, 길이, 음량 |
examples/sawt/는 완전한 작업 예제입니다(Chrome 확장 프로그램으로 글을 읽어주는 앱). 직접 작성하기 전에 scenario.mjs와 edit.json을 열어보세요. docs/edit-format.md는 편집 파일 레퍼런스이고, docs/lessons.md는 처음에 실수했던 점들을 정리해두었으니 녹화 전에 읽어보세요.
0. 초기 설정 (한 번만)
먼저 bin/reel doctor를 실행하세요: 모든 도구와 권한을 확인하고 수정해야 할 사항을 알려줍니다. bin/reel setup은 레코더(Swift, ScreenCaptureKit)를 빌드하고 playwright-core와 Chrome for Testing을 설치합니다. 추가로 필요: ffmpeg, uv, Google Chrome (오버레이 레이어 렌더링용). 당신을 실행하는 터미널은 화면 및 시스템 오디오 녹화 권한이 필요합니다(시스템 설정 → 개인정보 보호 및 보안). 레코더가 권한이 없다고 보고하면, 사용자에게 권한을 부여하고 터미널을 다시 시작하도록 요청하세요.
1. 스토리보드
녹화하기 전에 몇 줄로 다음을 합의하세요:
- 기능을 순서대로, 각각 하나의 캡션으로: 짧은 키커("Word zoom")와 최대 두 줄의 헤드라인, 핵심 혜택은
<b>로 강조("Follow along. Each wordgrows as it's spoken."); - 데모할 실제 콘텐츠: 공개 페이지, 샘플 계정, 시드 데이터. 기능이 가장 잘 보이는 콘텐츠를 선택하고 실제로 확인하세요(Sawt의 경우: 어려운 단어에 카드가 뜨는 기사, 사이트에서 카드가 열 옆에 공간이 있는 경우);
- 브랜드: 액센트 컬러, 밝은 변형, 배경 색조, 로고; 타이틀 및 엔드 카드 텍스트.
기본 포맷: 1080×1350 (4:5), 25~35초 — 모바일 피드를 가장 많이 채우며, 대부분의 사용자가 음소거로 시청하므로 캡션이 스토리를 전달해야 합니다. 게시할 위치를 물어보세요: 1:1, 9:16, 16:9는 동일한 편집에서 생성됩니다(--format). 각 포맷의 스틸을 확인하세요: 4:5에서 잘 맞는 쇼트가 1:1에서는 헤딩이 잘릴 수 있습니다. 포맷별로 위치를 조정하세요("1:1": {"dy": 20}).
제품에 음성이 있는 경우(또는 테이크에 내레이션이 있는 경우) 자막을 만드세요: reel subtitles를 실행한 후 .srt 파일을 읽고 이름과 전문 용어를 수정한 후 렌더링하세요. 전사는 좋지만 완벽하지 않습니다. subtitles.words에 어려운 단어를 넣어 전사를 개선하세요.
2. 시나리오
시나리오는 ES 모듈입니다(drive/take.mjs에서 전체 API 참조):
export const config = { url: "https://…", width: 1700, height: 1090, extension: "./ext" };
export async function setup(api) { /* 설정, 로그인; 카메라 타겟용 api.rect("title", "h1") */ }
export async function run(api) { /* 데모; 컷할 모든 순간에 api.mark("step") */ }
export async function after(api) { /* 이미지 장면으로 표시할 스틸, 예: 3x 팝업 */ }
- 컷하거나 카메라를 움직일 모든 순간을 표시하세요 (
api.mark("sentence", {n})). 편집은 이 마커를 기준으로 하므로, 테이크가 빠르거나 느리게 실행되어도 올바른 위치에서 컷됩니다. - 카메라 타겟을
api.rect(name, selector | fn, arg)로 기록하세요 (뷰포트 픽셀 단위). 닫힌 섀도우 루트 내의 요소는 측정할 수 없습니다: 위치를 계산하세요(Sawt 카드 참조). - 클릭 기반 제품은 보이는 포인터가 필요합니다. 자동화는 실제 커서를 움직이지 않으므로, 모양이 나타나고 버튼이 스스로 눌러집니다.
setup에서api.pointer.show()를 호출하고,api.pointer.click(selector | [x, y]),.drag(from, to),.move(x, y),.type(text),.key(k)로 제어하세요: 페이지에 화살표가 따라오고, 클릭 시 물결 효과가 나타나며, 이동은 부드럽게, 타이핑은 사람의 리듬을 따릅니다. 셀렉터로 클릭을 제어하면(title이나aria-label이 일반적으로 안정적) 위치가 페이지에서 계산됩니다. - 캔버스 콘텐츠(그림, 차트, 지도)는 측정할 요소가 없습니다: CSS px 단위로
api.rect(name, {x, y, width, height})로 그린 박스를 기록하세요. - Chrome 확장 프로그램:
api.inWorker(fn)으로 확장 프로그램의 자체 코드를 통해 액션을 실행하세요.activeTab에 의존하는 확장 프로그램은 호스트 접근 권한이 있는 녹화용 복사본이 필요합니다. 자동화가 브라우저 단축키를 누를 수 없기 때문입니다(examples/sawt/prepare.sh참조). 시청자가 보는 것을 변경하지 마세요. - 팝업 및 기타 작은 UI:
after()에서deviceScaleFactor3으로 CDP를 사용해 캡처하고(예제 참조), 이미지 장면으로 표시하세요. 토글의 두 상태를 같은 순간에 캡처하려면 리로드하지 않고 실제 컨트롤을 클릭하세요.
실행한 후 편집하기 전에 테이크를 살펴보세요: ffmpeg -ss 6 -i takes/take1.mov -frames:v 1 x.png로 PNG를 읽으세요. 페이지 스타일이 적용되었는지, 기능이 실행되었는지, 아무것도 가리지 않는지 확인하세요. 자유롭게 재녹화하세요 — 테이크 하나는 1분이면 됩니다.
3. 편집
edit.json을 작성하세요(레퍼런스: docs/edit-format.md). 녹화된 것이 아니라 제작된 것처럼 보이게 하는 규칙:
- 일시 정지에서 컷하세요.
bin/reel speech take1.mov는 소리가 있는 위치를 알려줍니다; 조각은 단계 직전에 시작하여 다음 단계가 시작되기 전에 끝납니다. 마커에 고정하세요:"sentence#5-0.15". - 나란히 콘텐츠는 좁은 창에 맞지 않습니다. 왼쪽 도구 모음과 오른쪽 다이어그램은 4:5 창이 보여주는 것보다 더 많은 너비가 필요할 수 있습니다.
reel check가 포맷별로 맞춤 쇼트가 얼마나 잘릴지 경고합니다. 더 적은 것을 맞추거나 해당 포맷에 맞게 쇼트를 조정하세요. - rect에서 쇼트를 만듭니다.
{"fit": ["title", {"rect": "card1", "dh": 330}], "pad": 60}. 하나의 와이드 확립 쇼트 후 캡션이 말하는 부분으로 확대합니다. 출력에서 텍스트는 약 20px 이상의 높이를 유지하세요; 와이드 쇼트는 잠시 더 작아질 수 있지만, 오래 지속되지 않아야 합니다. - 장면당 하나의 캡션, 장면 전체에 표시되며, 카메라 움직임에서만 캡션을 전환하세요.
- 움직임에 숨을 쉬게 하세요: 카메라 움직임당 1.0~1.5초, 도착 후 최소 1.5초 유지.
- 타이틀 카드 2
2.5초, 엔드 카드 33.5초. 이미지 장면(팝업, 설정 패널) 3~4초.
속도
30초 4:5 렌더링은 6코어 노트북에서 약 3분이 소요됩니다: 프레임은 병렬 청크로 렌더링되고(기본 4개, --jobs N으로 변경), 재인코딩 없이 결합되며, 변경되지 않은 레이어는 재사용됩니다. 편집이 아직 진행 중일 때는 reel render … --draft(15fps, 빠른 인코더, 약 절반 시간)와 reel stills를 사용하세요. 스틸이 올바르게 보이면 실제 렌더링을 진행하세요.
4. 매번 확인
bin/reel layers와bin/reel stills를 모든 장면의 시작, 중간, 끝 및 각 카메라 움직임에서 실행하세요. 모든 PNG를 읽으세요. 확인할 것: 프레임 가장자리에서 잘린 텍스트나 UI, 상단에 반쯤 보이는 헤딩, 중요한 내용 위에 있는 캡션, 빈 페이지만 가득한 프레임.- 렌더링 후
bin/reel sheet를 전체 비디오에 대해 실행하고 읽으세요. - 길이는 계획한 대로여야 하며, 제품이 소리를 낼 때 음량은 약 -16 LUFS여야 합니다.
- 동기화: 단계가 화면에 나타나는 순간과 소리가 시작되는 순간이 테이크와 일치해야 합니다.
그런 다음 MP4를 사용자에게 보여주고, 썸네일(build/layers/title.png)과 함께 실제로 무엇이 진짜이고 녹화를 위해 변경된 것인지 명확히 말하세요.
음악
기본적으로 시스템은 비디오에 맞는 배경 음악을 선택합니다(docs/music.md 참조): 비디오(길이, 음성, 템포, 캡션 단어)를 프로파일링하고, 라이선스된 악기 후보(사용자 자신의 music/ 폴더, 그 다음 번들 CC0 라이브러리 library/, 마지막으로 로컬에 맞는 것이 없으면 온라인)를 측정된 템포, 에너지 및 안정성으로 순위를 매기고 가장 좋은 것을 선택합니다. reel music auto edit.json --audition renders/x.mp4를 실행하여 순위를 확인하고 상위 트랙의 미리보기를 들어보세요. 당신은 들을 수 없으므로, 비디오 완료 전에 미리보기를 사용자에게 전달하세요. 최상의 트랙이 링크 전용인 경우(사이트가 스크립트 다운로드를 차단하는 경우), 사용자에게 링크를 제공하세요. 사용자가 하나를 다운로드하고 reel music add <file> --candidate N을 실행합니다. 사용자가 자체 트랙을 가져오는 경우, reel music add로 라이선스를 기록하고 편집에 포함시키세요. 항상 렌더링 옆에 .credits.txt 파일을 제공하고, 라이선스에 게시된 크레딧이 필요한 경우 알려주세요.
제한 사항
- 녹화는 macOS 전용입니다(ScreenCaptureKit). 합성 및 레이어는 모든 플랫폼에서 실행됩니다.
- 현재는 브라우저 기반 제품만 지원합니다. 데스크탑 앱은 자체 드라이버(접근성 스크립팅)가 필요하지만, 레코더(
--app <bundle id>)와 그 이후 단계는 이미 모든 앱에서 작동합니다. - 음악 생성(
reel music generate)은 로컬 모델이 연결되어 있어야 합니다. ACE-Step이 제안되었지만 아직 demo-reel에서 테스트되지 않았습니다.