제품 데모 비디오 생성 스킬
사용자가 설명한 흐름의 데모 비디오를 만듭니다. 출력은 새 demo/vN/ 폴더에 저장됩니다.
유일하게 중요한 규칙: 모든 화면은 실제 UI의 전사본이어야 하며, 추측이 아니어야 합니다. 레이아웃, 문구 또는 컴포넌트를 추측해 만든 데모는 데모가 없는 것보다 나쁩니다. 시청자에게 존재하지 않는 제품을 가르치기 때문입니다. 각 화면의 마크업을 작성하기 전에 반드시 소스를 먼저 읽으십시오.
입력
/create-product-demo-video <어떤 일이 일어나야 하는지> — 흐름 설명입니다. 설명이 모호한 경우("제품을 보여줘"), 가시적인 가치로 끝나는 가장 좁은 완전한 흐름을 선택하고, 어떤 흐름을 선택했는지 한 줄로 말한 다음 빌드합니다. 질문으로 막히지 마십시오.
단계
-
흐름을 라우트에 매핑합니다. 프롬프트를 사용자가 실제로 통과할 실제 라우트의 순서 목록으로 변환합니다. 먼저 라우터를 찾으십시오 —
routes/디렉토리,app/트리,<Routes>블록, 라우트 매니페스트 — 존재하는 경로만 나열하십시오. 흐름에 나중 화면이 존재하기 위해 먼저 생성되어야 하는 엔티티가 필요한 경우(프로젝트 범위 보고서 전에 프로젝트), 해당 화면을 포함하거나 필요하지 않은 범위를 선택하십시오. 필요한 단계를 조용히 건너뛰지 마십시오. -
모든 화면의 소스를 읽습니다. 각 라우트에 대해: 라우트 파일, 렌더링하는 컴포넌트, 앱의 공유 레이아웃 컴포넌트(셸, 페이지 헤더, 빈 상태), 디자인 시스템 프리미티브(
components/ui/또는 해당 위치). 또한 데모에 표시되는 문자열을 생성하는 모든 항목 — 미리보기 도우미, 파생 이름, 백엔드 렌더/템플릿 서비스 — 을 읽으십시오. 문자열을 있는 그대로 복사하십시오. 제품 문구를 의역하지 마십시오. -
스캐폴드합니다.
mkdir -p demo/vN(다음 사용 가능한 N — 기존 vN을 덮어쓰지 마십시오), 그런 다음assets/skeleton.html→demo/vN/index.html및assets/record.mjs→demo/vN/record.mjs를 복사합니다.assets/는 이SKILL.md옆에, 스킬이 설치된 곳(플러그인 캐시 디렉토리,~/.claude/skills/, 또는 프로젝트의.claude/skills/)에 있습니다. 스킬 자체 디렉토리에서 확인하고, 데모 대상 리포지토리에서는 절대 확인하지 마십시오. 스켈레톤은 플레이스홀더 셸, 토큰 스케일 및 재생 엔진을 포함합니다. 점수가 있는 데모의 경우assets/music/에서 선택한 트랙을demo/vN/music.mp3로 복사합니다. — 음악 참조. 복사하는 것이(스킬 폴더를 참조하지 않고)vN/을 나중에 다시 녹화할 수 있게 유지하는 이유이며,record.mjs가 버전별로 복사되는 것과 같은 이유입니다. -
스켈레톤을 이 제품에 맞춥니다.
REPLACE:로 표시된 모든 것은 모든 화면이 상속하므로 어떤 장면을 작성하기 전에 반드시 교체해야 하는 플레이스홀더입니다:index.html에서다음으로 교체 PRODUCT앱 이름, 주소 표시줄에 표시되는 호스트 및 실제 로고 svg NAV실제 탐색에서 전사된 사이드바 — 동일한 섹션, 동일한 순서, 동일한 레이블 TOPBAR실제 상단 표시줄; 앱에 없는 컨트롤은 삭제 :root토큰앱 스타일시트의 :root블록, 색상/반경/타입이 일치하도록ICONS앱이 실제로 사용하는 아이콘 세트의 경로 데이터 흐름에서 사용하지 않는 선택적 CSS 블록(서드파티 화면, 전달 패널)을 삭제합니다. -
장면을 작성합니다. 화면당 하나씩 순서대로
<section class="scene" data-scene="N">를 작성합니다. 스켈레톤의 CSS 클래스(.pagehead,.card,.btn,.seg,.opt,.chip,.scopeid,.statusbadge,.empty,.input,.pillbar,.toast)를 재사용합니다. 이들은 Tailwind/shadcn 스타일 시스템의 출력과 유사하게 설계되었으므로 각각을 실제 컴포넌트의 클래스와 비교하고 추측하지 말고 조정하십시오. 스켈레톤에 없는 컴포넌트에 대해서만 새 CSS를 추가하고 해당 컴포넌트의 실제 클래스에서 파생하십시오. -
play()를 작성합니다. 타이틀 카드 → 화면 → 아웃트로. 각 단계의 이름을 지정하기 위해 캡션을 사용하고 스크립트 상단에CAPTIONS— 스타일 및steps= 실행이 만드는say()호출 수 — 를 설정합니다. 상호 작용은 포인터 도우미를 통해 진행되어 시청자가 클릭되는 대상을 따라갈 수 있도록 합니다. -
녹화합니다.
node demo/vN/record.mjs→demo/vN/out/product-demo.mp4. 900px gif의 경우--gif를 추가합니다.demo/vN/music.*파일이 있으면 자동으로 사용됩니다.--music <path>는 다른 곳의 파일을 가리키고,--music-db <n>은 레벨을 변경하며,--no-music은 무음을 강제합니다. -
보고 확인합니다. 프레임을 추출하고 이미지를 읽습니다 — 이것은 선택 사항이 아니며 레이아웃 버그를 잡는 방법입니다:
for t in 5 12 20 28 36 44; do ffmpeg -y -loglevel error -ss $t \ -i demo/vN/out/product-demo.mp4 -frames:v 1 /tmp/f$t.png; done확인: 아이콘이 너무 크지 않은지, 접힌 부분에서 아무것도 잘리지 않았는지, 포인터가 클릭한다고 주장하는 요소에 도달하는지, 텍스트가 한 줄로 붕괴되지 않았는지. 수정하고 다시 녹화하여 깨끗해질 때까지 반복합니다.
프레임은 오디오를 보여줄 수 없습니다. 점수 데모의 경우 스트림과 램프도 확인하십시오 —
volumedetect는 정보 레벨로 로그를 기록하므로-v error는 출력을 삼킵니다:ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,duration \ -of default=nw=1 demo/vN/out/product-demo.mp4 for w in "-ss 0 -t 0.25" "-ss 12 -t 0.5" "-sseof -0.25"; do \ ffmpeg -hide_banner -nostats $w -i demo/vN/out/product-demo.mp4 \ -af volumedetect -f null - 2>&1 | grep mean_volume; done비디오 지속 시간의 약 ±0.05초 내에
aac스트림이 있고,max_volume이 0dB 미만이며, 헤드와 테일 평균이 중간 평균보다 훨씬 낮아야 합니다. 이것이 페이드가 실행되었음을 증명합니다. -
demo/vN/README.md를 작성합니다 — 라우트, 소스 파일 매핑, 지속 시간, 버전이 녹화된CAPTIONS스타일 및 음악 트랙, 그리고 흐름이 의도적으로 건너뛰는 항목이 포함된 장면 테이블.demo/README.md를 업데이트하여 새 버전을 나열합니다.
경로, 지속 시간 및 크기를 보고한 다음 mp4를 열어 사용자가 볼 수 있도록 합니다. — macOS에서는 open, Linux에서는 xdg-open, Windows에서는 start.
엔진 API
play() 내부에서 사용 가능:
| 호출 | 효과 |
|---|---|
scene(n) | 장면 n으로 크로스페이드, 주소 표시줄을 URLS에서 업데이트 |
tap(sel, ms) | 포인터를 요소로 이동하고 클릭(리플 + 누름) |
moveTo(sel, ms) / click(sel) | 두 반쪽, 사이에 상태 변경이 필요할 때 |
hideCursor() / place(x, y, 0) | 장면에 들어갈 때 포인터 재설정 |
say(text, opts?) / hush() | 캡션 인/아웃. { at: sel }은 coach 캡션을 고정합니다. { step: n }은 인덱스를 강제합니다 |
type(el, text, ms) | <span>에 한 문자씩 입력 |
wait(ms) | 대기 |
reveal(el) | moveTo에 의해 자동 호출 — .main을 부드럽게 스크롤하여 접힌 부분 아래의 대상이 보이도록 함 |
마지막에 window.__demoDone = true를 설정합니다(스켈레톤이 이미 수행) — 레코더가 이를 기다립니다.
캡션 디자인
const CAPTIONS = { style: 'pill', steps: 6 }는 URLS와 함께 엔진 상단에 있습니다. 네 가지 스타일 모두 스켈레톤에 포함되어 있습니다. say()는 어떤 스타일이든 동일한 호출입니다. 비디오별로 선택:
style | 설명 | 언제 선택할지 |
|---|---|---|
pill (기본값) | 잉크 캡슐, 하단 중앙 | 짧고 마케팅 지향적인 모든 것. 가장 적은 폐색, 캡션당 약 10단어 |
lower-third | 단계 인덱스 + 진행 트랙이 있는 왼쪽 정렬 블록 | 시청자가 순서를 느껴야 하는 긴 흐름. gif에서 가장 읽기 쉬움 |
rail | 창 아래 68px 밴드, 챕터 점 | 문서 및 지원 클립. 아무것도 가려지지 않아야 할 때. 앱 높이를 소모함 — 아래 참조 |
coach | 플레이 중인 요소에 고정된 콜아웃, 나머지는 어두워짐 | 따라하기 연습. 모든 캡션에는 { at: sel }이 필요합니다. 없는 것은 pill로 대체됨 |
steps는 인덱스, 진행 트랙 및 레일의 점을 구동합니다. say() 호출을 세고 설정하십시오. 그렇지 않으면 실행이 05 / 06에서 끝납니다. 스타일이 확실하지 않습니까? 브라우저에서 index.html을 열고 CAPTIONS.style을 전환하십시오. 페이지는 R에서 다시 재생되므로 네 가지 모두 녹화 없이 비교할 수 있습니다.
음악
선택 사항이며 트랙이 있는 경우에만 켜집니다. 배경음은 인코딩 시에 믹스됩니다 — Playwright는 전혀 오디오를 캡처하지 않으므로 데모 페이지나 엔진에 영향을 주지 않습니다.
node demo/vN/record.mjs # demo/vN/music.*이 있으면 사용, 없으면 무음
node demo/vN/record.mjs --music ~/beds/x.mp3 # 명시적 경로가 형제 파일보다 우선
node demo/vN/record.mjs --music-db -4 # 더 조용한 배경음
node demo/vN/record.mjs --no-music # 형제 트랙이 있어도 무음
- 번들 트랙은
assets/music/에 있으며, 해당LICENSES.md의 파일당 한 행입니다. 확인 가능한 CC0/CC-BY 라인이 없는 트랙은 제공되지 않습니다. 라이선스 없는 mp3는 설치하는 모든 사람의 문제입니다. 확실하지 않습니까? 리포에서 제외하고--music <path>를 전달하십시오. - 레벨은 설정된 것이 아니라 정규화됩니다. 모든 트랙은 -1.5dB 실제 피크 한계로 -18 LUFS로 구동되므로 버전 간에 교체된 배경음을 수동 조정 없이 일치시킵니다.
--music-db는 해당 대상을 이동시킵니다. 그 위에 게인을 추가하지 않습니다. - 페이드는 자동입니다 — 1.5초 시작, 2.5초 종료, 종료는 실제 비디오 지속 시간에 맞춰집니다.
- 비디오보다 긴 트랙을 선택하십시오. 더 짧은 것은 반복되고 이음새가 들립니다. 레코더는 반복해야 할 때 경고합니다. 60초+는 일반적인 40-60초 데모를 커버합니다.
- 보컬이나 하드 드롭이 없습니다. 시청자는 동시에 캡션과 UI 사본을 읽고 있습니다.
- 오디오는 mp4에만 들어갑니다. webm은 원시 무음 캡처이고 gif에는 오디오 트랙이 전혀 없습니다. 음악만 변경된 것은
--gif출력에서 보이지 않습니다.
규칙
- 스테이지는 고정 1280×800 모의 브라우저입니다. 이 중 44px은 브라우저 크롬이며, 앱에는 1280×756이 남습니다. 스켈레톤은 48