내레이션 비디오
사용자가 스토리보드에 맞춰 말하는 한 번의 테이크를 녹화합니다. 에이전트는 테이크를 편집하고 제품의 실제 스크린샷을 애니메이션으로 추가합니다. 각 장면은 해당 단어가 나오는 순간에 시작되고, 각 클릭은 해당 단어에 맞춰 떨어지며, 각 검색어는 해당 단어가 발화될 때 입력됩니다. 전체 비디오는 코드(HyperFrames 컴포지션과 편집 리스트)로 구성되므로, 새 테이크, 변경된 화면, 다른 순서는 재편집이 아니라 재실행만 하면 됩니다.
비디오는 항상 내레이션에 맞춰지며, 그 반대는 없습니다. 사용자는 취향을 지시하고, 에이전트는 컷을 생성하고, 프레임을 보여주며 질문합니다.
설정
ffmpeg가 PATH에 있어야 하며,uv, Node 20+ (npx포함, HyperFrames 0.8.62는 npx를 통해 실행), 캡처를 위한 Playwright(Chromium 포함)가 필요합니다. macOS, Linux, Windows에서 작동합니다.- Whisper는 로컬에서 실행됩니다: Apple Silicon에서는 mlx-whisper, 그 외에서는 faster-whisper.
uv run이 올바른 것을 설치합니다. SK=<이 스킬의 디렉토리>/scripts. 모든 도구는uv run $SK/<tool>.py로 실행되며, 각 도구는 자체 종속성을 선언합니다.- 리포지토리의 추적 파일이 없는 폴더(gitignored된
.logs/<video>/또는 임시 폴더)에서 작업합니다:
<work>/
assets/ 캡처, 배경, 엔드 카드
storyboard.json 장면 -> storyboard/index.html
takes/<name>/ 녹화된 각 테이크 폴더: 프로브 출력, 트랜스크립트, edit.json, 편집된 내레이션 및 웹캠
video.py 컴포지션 스크립트 -> comp/ (index.html, renders/)
NOTES.md 모든 결정 사항: 컷과 그 이유, 장면 시작 시간, 재빌드 명령어
1. 브리프
한 번의 짧은 교환으로 확인하며, 기본값을 제시합니다:
- 형식: 런칭 비디오, 기능 데모 또는 튜토리얼 (references/formats.md). 런칭 비디오는 엔드 카드를 포함하여 2:00 이내여야 합니다.
- 대상 청중, 비디오가 전달해야 할 세 가지 또는 네 가지 핵심 포인트, 그리고 클릭 유도 문구.
- 데모에 적합한 예시 데이터: 이 청중이 한눈에 이해할 수 있는 예시 비즈니스 또는 검색어.
- 브랜드: 배경 이미지(또는 기본 그라데이션), 엔드 카드(제품의 OG 이미지가 좋음), 창 제목 표시줄에 표시될 URL.
2. 캡처
$SK/capture.mjs를 기반으로 한 Playwright 스크립트를 통해 실행 중인 제품의 실제 스크린샷을 1440x900, 2배율로 캡처합니다. 화면에 입력되는 모든 내용에 대해 키 입력별 프레임, 클릭되는 모든 항목에 대해 전후 상태, 스크롤되는 항목에 대해 긴 샷, 포인터를 위한 측정된 클릭 대상을 포함합니다. 앱에 로그인이 필요한 경우 login 플래그를 전달하면 첫 실행 시 브라우저 창이 열려 사용자가 한 번 로그인할 수 있습니다. 절대 UI를 그리거나 픽셀을 편집하지 마십시오. 각 캡처를 사용하기 전에 확인하십시오. 자세한 내용 및 개인정보 보호 정책: references/capture.md.
3. 스토리보드
storyboard.json을 작성합니다. 각 장면당 하나의 카드: 스크린샷, 화면에 표시되는 내용, 말할 내용의 세 가지에서 여섯 가지 포인트(짧은 메모, 문장 아님), 그리고 대략적인 시간(초). 이를 빌드하고 보여줍니다:
uv run $SK/storyboard.py storyboard.json storyboard/
일반 페이지이며, 장면당 하나의 섹션으로 구성됩니다. 하네스가 페이지를 게시할 수 있으면 storyboard/ (index.html 및 frames/)를 게시하고, 그렇지 않으면 로컬에서 엽니다. 사용자가 녹화할 준비가 될 때까지 반복한 후, references/storyboard-and-recording.md의 녹화 노트를 전달합니다. 사용자가 이를 바탕으로 녹화를 시작하면, 허락 없이 스토리보드를 변경하지 마십시오.
4. 녹화
사용자가 한 번의 테이크를 녹화합니다. 웹캠과 음성을 하나의 파일로 (QuickTime, Photo Booth, Windows Camera, OBS 등 어떤 웹캠 녹화기든 사용 가능) 장면을 따라 말합니다. 실수는 괜찮습니다: 문장을 다시 시작하고 계속 진행합니다. 여러 테이크도 괜찮습니다. 각 테이크는 별도의 테이크 폴더를 얻습니다.
5. 테이크 편집
uv run $SK/probe.py <recording> takes/<name> # take.wav, cam.mp4, take.json; still.jpg 확인, 필요한 경우 --crop으로 재실행
uv run $SK/transcribe.py takes/<name> # 두 번 실행: 일반, 필러를 기록하는 패스
uv run $SK/analyze.py takes/<name> # 후보: 긴 멈춤(컷 포함), 필러, 재시작, 잡음
uv run $SK/trace.py takes/<name> <a>:<b> # 에너지 트레이스에 각 컷 배치(--fine으로 5ms 행)
uv run $SK/splicetest.py takes/<name> c1=<a>:<cut start>,<cut end>:<b> # 컷 청취: 의도한 문장으로 읽혀야 함
uv run $SK/jump.py takes/<name> <cut start>:<cut end> --slide 0.3 # 웹캠 버블에서 컷이 얼마나 보이는지 확인
# takes/<name>/edit.json 작성 후:
uv run $SK/edit.py takes/<name> # edl.json; 편집된 내레이션과 유지된 필러 출력: 전체 읽기
uv run $SK/build.py takes/<name> # narration-edit.wav, cam-edit.mp4 (각 컷에서 크로스페이드 및 웹캠 디졸브)
uv run $SK/master.py takes/<name> # -16 LUFS의 narration.wav
두 가지 편집 수준 (references/editing.md):
- 가벼운 편집(기본값): 재시작 및 잘못된 시작 제거, 무음 트림(약 1.1초 이상의 멈춤은 0.7초 유지, 장면 전환 시 0.9초). 모든 음 및 짧은 망설임은 유지합니다.
- 필러 감소(요청 시): 구 사이에 단독으로 있는 대부분의 음을 제거하고, 약 0.8초 이상의 멈춤을 약 0.55초로 줄입니다. 인접 단어에 붙어 있는 필러는 그대로 둡니다.
- 각 컷은 트레이스에서 룸 톤 내에 위치하며, 적용 전에 스플라이스 테스트를 통과해야 합니다. 재시작 컷은 가능하면 장면 변경 시점에 배치하여 화면 컷이 버블에서의 점프를 숨깁니다.
6. 단어에 맞춰 컴포지션
uv run $SK/cues.py takes/<name> # words.json, 큐 시트 (최종 내레이션의 클립 수준 트랜스크립트)
NV_SCRIPTS=$SK ASSETS=assets uv run --with numpy python video.py # 컴포지션 스크립트 -> comp/; 각 큐를 컨텍스트와 함께 출력
uv run $SK/render.py comp lint
uv run $SK/render.py comp snapshot 1,14.2,22.5,40.1
작업 예제인 examples/openseo-launch/video.py를 바탕으로 video.py를 작성합니다. 큐 시트에서 장면 시작 시간과 큐 시간을 가져오고, 캡처 위에 카메라 레이어를 배치하며, 단어에 맞춰진 안무를 구성합니다. 예제의 큐 위치는 자체 편집에만 맞습니다: 모든 큐를 다시 앵커링하고, 편집 변경 후 출력되는 큐 테이블을 읽습니다. 타이밍 규칙은 references/composition.md에 있습니다. 가장 중요한 규칙:
- 장면은 첫 단어보다 0.3초 먼저 시작하거나, 그 앞의 멈춤 구간의 컷과 정확히 일치해야 합니다.
- 각 동작은 해당 단어에 맞춰 실행됩니다: 클릭은 "복사" 단어에 맞춰, 타이핑은 검색어가 발화될 때, 줌은 숫자가 말해질 때, 포인터는 각 항목이 언급될 때.
- 첫 프레임은 포스터: 전체 앱, 페이드 인 없음. 모든 프레임에서 무언가 움직여야 합니다.
- 각 비트당 하나의 짧은 레이블. 모든 장면 시작, 클릭 및 레이블을 스냅샷으로 찍고 렌더링 전에 확인합니다.
7. 렌더링 및 검증
uv run $SK/render.py comp render
uv run $SK/composite.py comp takes/<name> comp/renders/<video>-1080p.mp4
uv run $SK/check.py comp/renders/<video>-1080p.mp4 comp takes/<name>
uv run $SK/filmstrip.py comp/renders/<video>-1080p.mp4 comp/renders/filmstrip.png
검사 결과 모든 프레임에 창이 있고, 모든 웹캠 포인트가 프레임 오프셋 0에 있으며, 오디오 중간값이 0ms이고, 약 -16 LUFS이며, 트랜스크립트를 읽고 필름스트립을 확인하기 전까지는 아무것도 사용자에게 제공하지 마십시오 (references/verification.md).
8. 검토 및 반복
- 사용자에게 mp4 경로, 무엇이 잘렸는지, 그리고 주의해서 들어야 할 사항을 알려줍니다.
NOTES.md를 최신으로 유지합니다: 각 컷과 그 이유, 장면 시작 시간, 재빌드 명령어. 여러 번의 라운드가 예상됩니다.- 변형은 저렴합니다: 다른 테이크, 가벼운 편집과 필러 감소 편집, 다른 장면 순서. 각각은 테이크 폴더 또는 컴포지션 스크립트입니다. 서브에이전트를 사용하는 경우, 충돌을 방지하기 위해 별도의 파일 이름으로 병렬로 빌드합니다.
엄격한 규칙
- 실제 화면만 사용합니다. 스토리와 관련 없는 요소(배너, 쿠키 알림)는 숨기고, 픽셀 위에 절대 칠하지 마십시오.
- 렌더링 전에 캡처와 녹화에서 비밀 정보 및 개인 데이터(API 키, 다른 사람의 이메일 및 이름, 고객 데이터, localhost URL)를 확인하고, 해당 부분을 프레임 밖으로 처리하거나 다시 캡처하며, 화면에 나타난 키는 모두 폐기합니다. 사용자가 확인한 경우 앱 내 사용자 이름이나 이메일은 괜찮습니다.
- 사용자의 녹화 및 로그인 세션은 해당 기기에 남아 있습니다. 요청하지 않고 아무것도 게시하지 마십시오.
사람들이 자주 실수하는 부분: references/gotchas.md.