데모 비디오은(는) 무엇을 하나요?
프로젝트의 라이브 사이트 또는 앱을 보여주는 Full HD MP4를 생성합니다: 실제 화면 녹화, 사용자 언어로 된 음성 해설, 하드코딩된 자막, 배경 음악 및 공유 가능한 링크. 모든 작업은 agent-browser, ffmpeg 및 프로젝트의 AI 프록시(프로젝트 크레딧으로 청구)를 사용하여 컨테이너 내에서 실행됩니다. 일반적인 결과: 13분, 1020MB, 약 1~2시간의 에이전트 작업. 모든 작업 파일은 video/ 디렉토리에 저장됩니다(build/ 및 out/은 git에서 제외됨).
사용 시기
- "시스템 작동 방식을 보여주는 비디오를 만들어 줘", 프로모션, 광고, 고객 데모
- 제안, 릴리스 노트 또는 랜딩 페이지를 위한 워크스루
- 사용자가 직접 녹화하는 경우는 해당하지 않음: 그런 경우
docs/demo/script.md에 촬영 스크립트(장면, 동작, 말할 텍스트)를 작성합니다.
파이프라인 (각 단계는 재개 가능: 재실행 시 완료된 출력 건너뜀)
| 단계 | 명령 | 출력 |
|---|---|---|
| 0. 설정 | bash .claude/skills/demo-video/setup.sh | ffmpeg, 자막 폰트, video/ 폴더 |
| 1. 스크립트 | video/vo/narrator.json 및 video/scenes.mjs 작성 (examples/에서 시작) | 계획 |
| 2. 음성 해설 | node .claude/skills/demo-video/tts.mjs video/vo/narrator.json video/build/vo | s01.wav… + s01.txt (말한 내용) |
| 3. 녹화 | source .claude/skills/demo-video/rec-lib.sh 그 다음 take_start, mark, take_stop | video/build/rec/<take>.mp4 + .marks |
| 4. 카드 | card_take <name> "file://$PWD/video/cards/<name>.html?…" <seconds> | video/build/rec/card-<name>.mp4 |
| 5. 사운드 | node .claude/skills/demo-video/sfx.mjs | video/build/sfx/chime.wav, click.wav |
| 6. 편집 | node .claude/skills/demo-video/compose.mjs video/scenes.mjs | video/out/<name>.mp4 (+ 음악이 없으면 자동 생성) |
| 7. QA | node .claude/skills/demo-video/listen.mjs video/out/<name>.mp4 "<질문>" 및 프레임 캡처 | 수정 후 6단계 재실행 |
| 8. 게시 | node .claude/skills/demo-video/publish.mjs video/out/<name>.mp4 --cover 16 | 프로젝트 스토리지의 키 + 표지 JPG |
(npx skills add로 설치한 경우 경로는 .agents/skills/demo-video/입니다.)
좋은 비디오를 만드는 방법
스크립트 우선. 1015개의 내레이터 라인, 각 라인에 하나의 아이디어, 815단어, 사용자 언어로 작성. 사실만 기재: 프로젝트 자체 데이터에서 확인할 수 없는 숫자, 고객 또는 수상 경력을 주장하지 마십시오. 브랜드 이름과 약어는 pronounce에 넣어 올바르게 발음되도록 합니다. 각 라인은 하나의 장면에 매핑됩니다.
음성. 프록시에 TTS 모델이 없습니다. tts.mjs는 Live 모델(gemini-3.8-live)을 사용하여 각 라인을 그대로 읽고, 모델 자체 전사본과 스크립트를 비교(80% 단어 일치)하여 3번 시도 중 최상의 결과를 유지하며 라인당 하나의 WAV 파일을 생성합니다. 음성: Kore, Charon, Puck, Fenrir, Aoede. 내레이터는 하나의 음성, "고객" 역할은 다른 음성을 사용합니다. 실행 후 s*.txt 파일을 읽고 차이가 있는 라인은 rm으로 wav를 삭제한 후 재생성합니다.
녹화. 깨끗한 상태에서 시작: 새 브라우저 컨텍스트, 빈 장바구니, 저장된 양식 초안 없음(agent-browser eval 'sessionStorage.clear()' 및 앱이 사용하는 localStorage 키도 동일하게 처리), 카메라에 비밀번호가 입력되지 않도록 녹화 전에 로그인. typeslow로 입력하고, 편집 시 잘라낼 모든 클릭 전에 mark <레이블>을 호출하고, AI 응답은 wait_gone "<검색 텍스트>"로 기다리며, 화면에 표시 중인 요소를 스크롤하지 마십시오. 레이블 텍스트가 아닌 요소 참조(snapshot의 @e12)로 클릭합니다. take_start는 뷰포트를 1600×900으로 설정합니다(기본값은 1280×720으로 1080p에 너무 작음). 장면당 하나의 테이크. 제품에 음성 에이전트가 있는 경우 자체 API(examples/voice-exchange.mjs)를 통해 실제 대화를 녹음하고 가짜 대신 카드 위에 재생합니다.
카드. examples/cards/에는 인트로(애니메이션 숫자, 로고, 필), 음성 통화 카드, 아웃트로가 있습니다. video/cards/로 복사하고 색상, 로고 및 텍스트를 브랜드에 맞게 변경합니다. URL에 타이밍을 전달(?t1=<s>)하여 애니메이션이 음성과 일치하도록 합니다.
편집 (scenes.mjs). 각 장면은 테이크의 일부 [take, in, out, speed, zoom?]와 오디오 ['vo:s01', at]로 구성됩니다. 대기 시간은 2~5배 빠르게 하고, 작은 텍스트가 있는 패널은 zoom으로 확대하고, 각 새 섹션에 chapter 칩을 추가하고, 하단 자막이 표시 중인 UI를 가릴 때 cap: 'left'를 사용하고, 성공 순간(장바구니에 추가, 주문 완료)에 sfx 차임을 추가합니다. 편집은 장면별로 캐시되며 변경된 장면만 다시 렌더링됩니다.
오디오. 배경 음악은 compose.mjs에서 합성되며(라이선스 위험 없음) 음성 아래로 덕킹됩니다. scenes.mjs에서 music: 'path/to/track.mp3'를 설정하여 사용자 자신의 트랙을 사용할 수 있습니다. 출력은 −16 LUFS로 정규화됩니다.
전달 전 QA. listen.mjs가 믹스를 Gemini로 보냅니다: 딕션, 잘못 발음된 단어, 음악-음성 균형, 결함 및 긴 침묵에 대해 질문합니다. 그런 다음 각 장면의 한 프레임을 최대 해상도로 캡처(ffmpeg -ss <t> -i out.mp4 -frames:v 1 f.png)하고 확인합니다: UI와 겹치는 자막, 잘린 텍스트, 화면의 잘못된 상태. 수정하고 6단계를 재실행합니다.
전달. 테이크가 생성한 테스트 주문/데이터를 삭제하고, agent-browser close --all을 실행하고, video/ 도구와 스크립트를 커밋합니다(build/, out/ 제외). 링크, 로컬 경로, 비디오가 보여주는 내용에 대한 간략한 목록, 그리고 촬영 중에 수정한 제품의 모든 사항을 제공합니다(엔드 투 엔드 흐름 녹화는 일반적으로 실제 버그를 찾습니다. 수정하면 실제 사용자에게 영향을 미칩니다).
게시
publish.mjs는 올바른 콘텐츠 유형으로 프로젝트 스토리지에 업로드하고(일반 스토리지 업로드는 비디오를 다운로드로 제공) 공개 URL을 출력합니다: openkbs.json에 "storage": { "cloudfront": "media" }가 있으면 파일은 openkbs deploy가 해당 경로를 설정한 후 <사이트>/media/<키>에 위치합니다. CDN에 스토리지가 없으면 파일을 site/ 아래에 넣고 배포하거나 openkbs storage download를 공유합니다. --cover <초>는 썸네일용 JPG 프레임도 업로드합니다.
요구 사항
- Studio 컨테이너:
ffmpeg(설치 스크립트가 설치),agent-browser,~/.openkbs/projectJWT의 프록시 JWT. Studio 외부에서는OPENKBS_API_KEY를 설정합니다. - 자막 폰트는
setup.sh가video/build/fonts로 다운로드합니다(Golos Text, Fira Sans Extra Condensed: 라틴 + 키릴, OFL 라이선스).