---
name: motion-video-production
description: Plan and assemble 30–90 second motion graphics and character videos with six production stages, media gates, and visual review. Use for video production, keyframes, character consistency, and Remotion assembly. 모션 그래픽·캐릭터 영상·오프닝 영상 제작에 사용한다.
---

# 모션 그래픽·영상 제작 스킬 (motion-video-production)

이 스킬은 모션 그래픽과 영상(예: 한 명의 캐릭터가 나오는 30~90초 영상)을 만드는 순서와 점검 기준을 제공합니다.
이 스킬을 따라가면 STORY.md, 캐릭터 시트, 키프레임, 장면 영상, 음악·목소리, 최종 mp4를 얻어가십니다.

모든 답변은 사용자의 언어(기본 한국어)로 합니다. 도구를 대신 로그인하거나 결제하지 않습니다. 로그인·결제·대용량 다운로드가 필요한 시점에서는 사용자에게 먼저 묻습니다.

## 실행 환경과 경로

이 스킬은 Agent Skills 형식의 공통 지침입니다. Codex, Claude Code 및 다른 스킬 지원 런타임에서 같은 폴더를 사용합니다. 특정 모델의 API나 생성 도구 연결을 포함하지 않습니다.

- 런타임이 알려 준 이 `SKILL.md`의 실제 경로에서 부모 폴더를 `SKILL_ROOT`로 정합니다. `~/.claude/skills` 같은 특정 설치 경로를 가정하지 않습니다. 아래 `references/`, `templates/`, `harness/`, `scripts/`는 모두 이 폴더 기준입니다.
- 산출물 폴더의 절대 경로를 `PROJECT_ROOT`로 정합니다. 두 경로를 구분하고, 스크립트는 `python3 "$SKILL_ROOT/harness/gate.py" <단계> "$PROJECT_ROOT"`처럼 절대 경로로 실행합니다. 보조 스크립트는 산출물 폴더에서 `bash "$SKILL_ROOT/scripts/<파일>.sh" ...`로 실행합니다.
- Python 3, ffmpeg, ffprobe가 필요합니다. `.sh` 스크립트에는 Bash가 필요합니다(macOS/Linux 또는 Windows의 WSL). Remotion은 Node.js와 별도 설치가 필요합니다.
- 시작할 때 실제로 제공된 파일 읽기·터미널·이미지 보기·생성 도구를 확인합니다. 생성 도구가 없으면 프롬프트와 저장 위치를 제공하고 사용자가 만든 파일을 받아 이어갑니다. 구독만으로 API 접근이나 자동 생성을 할 수 있다고 가정하지 않습니다.
- 이미지를 볼 수 없는 런타임은 사용자의 실제 눈 검수 결과를 요청합니다. 보지 않은 프레임의 검수 기록을 대신 만들지 않습니다. 검사 스크립트 실행이 불가능하면 명령을 전달하고 실제 종료 코드·보고서를 받은 뒤에만 결과를 판단합니다.
- `STORY.md`는 제공된 템플릿의 한국어 항목명과 표 구조를 유지하고, 내용은 사용자 언어로 채웁니다. 게이트가 이 항목명을 읽습니다. 한국어 외의 `character.txt`에는 색 이름과 함께 `#RRGGBB` 색상 코드를 적습니다(현재 색 검사에서 인식 가능).

## 0. 시작하기 전에 정할 것

작업을 시작할 때 아래 4가지를 사용자에게 한 번에 묻고 `STORY.md` 맨 위에 기록합니다.

1. 공개 방식: 비공개 시안인가, 상업적으로 공개하는 최종본인가. (공개 방식이 비용 규칙을 정합니다. `references/cost-rules.md`)
2. 길이와 화면비: 기본값 30~90초, 16:9.
3. 사용 가능한 도구와 구독 상태: 이미지 생성, 영상 생성, 음악, 목소리 도구 중 어떤 것을 쓸 수 있는지.
4. 금지 사항: 영상에 넣지 않을 요소(예: 로고, 실존 인물, 읽히는 글자).

## 제작 6단계

각 단계는 산출물이 있고, 아래 Harness의 게이트가 종료 코드 0으로 끝나야 다음 단계로 넘어갑니다. 작업 전에 아래 Gotchas(함정 목록)를 먼저 읽습니다.

| 단계 | 하는 일 | 쓰는 도구(예시) | 산출물 |
|---|---|---|---|
| 1. 스토리·장면 기획 | 한 줄 줄거리, 장면 목록(시간·장소·행동·대사), 음악 싱크 지점 확정 | 현재 에이전트 | `STORY.md`, 장면 목록 |
| 2. 캐릭터 시트 | 정면·측면·표정·의상을 한 장에 고정한 기준 이미지 | 이미지 생성 도구 | 캐릭터 시트 PNG, 외형 고정문 |
| 3. 키프레임 | 장면마다 시작 화면 1장씩 생성 | 이미지 생성 도구 | 키프레임 PNG |
| 4. 영상 변환 | 키프레임을 시작 화면으로 고정하고 3~6초 클립 생성 | 영상 생성 도구 | 장면별 mp4 |
| 5. 음악·목소리 | 음악 1곡, 캐릭터 목소리 1개(ID 고정), 대사 음성 | 음악·음성 도구 | 음악 wav/mp3, 대사 wav |
| 6. Remotion 조립 | 박 격자에 맞춰 컷 배치, 자막·타이틀·엔드카드 모션 그래픽, 믹스, mux | Remotion, ffmpeg | 최종 mp4 |

## Gotchas (먼저 읽을 것)

자주 생기는 함정 8가지입니다. 전체 29가지(증상, 원인, 예방, 하네스 검사 ID)는 `references/gotchas.md`에 있습니다.

1. 클립은 시작 화면이 같아도 1~2초 뒤에 옷, 안경, 머리가 바뀝니다. 0초만 보고 통과시키지 말고 0, 1.0, 1.5, 2.0, 3.0초를 한 줄에 놓고 봅니다. (G01)
2. SSIM 같은 숫자로는 인물 변형을 잡을 수 없습니다. 정상 클립도 움직이면 값이 떨어집니다. 시작 화면 일치만 숫자로 막고 나머지는 눈으로 봅니다. (G02)
3. 외형 고정문은 파일에서 그대로 붙입니다. 손으로 다시 쓰면 달라집니다. 옷 색을 적습니다. (G03)
4. 컷 길이는 초가 아니라 박의 배수로 정하고, 시작 프레임은 누적 시간에서 한 번만 반올림합니다. (G11, G12)
5. 대사 길이를 먼저 재고 컷 길이를 정합니다. 대사가 컷보다 길면 입이 잘립니다. (G13)
6. 파이프(`| tail`)로 검사 출력을 자르면 종료 코드가 사라집니다. 판정은 하네스의 종료 코드와 보고서 파일로 합니다. (G21)
7. 프레임 수를 읽을 때 `ffprobe -of csv=p=0`을 쓰면 `30,`처럼 읽혀 정상 영상이 막힐 수 있습니다. `-of default=nw=1:nk=1`을 씁니다. (G27)
8. 렌더가 끝난 것은 통과의 근거가 아닙니다. 프레임 수를 세고, 컨택트 시트를 직접 봅니다. (G08, G28)

## Harness (단계 게이트)

단계의 산출물은 `harness/gate.py`가 측정해서 종료 코드로 판정합니다. 게이트가 통과(종료 코드 0)하기 전에는 다음 단계로 넘어가지 않고, 완료라고 보고하지 않습니다.

```
python3 "$SKILL_ROOT/harness/gate.py" <단계> "$PROJECT_ROOT"
```

| 제작 단계 | 게이트 | 하는 검사 |
|---|---|---|
| 1. 스토리·장면 기획 | `story` | STORY.md 빈칸, BPM, 음악 싱크 지점 표(시간이 숫자인지), 장면 표 |
| 2. 캐릭터 시트 | `character` | character.txt(1개 문단 평문, 색 표현), 시트 이미지 |
| 3. 키프레임 | `keyframes` | 중복 파일, 클립과의 화면비 |
| 4. 영상 변환 | `clips` | 길이, 프레임 수, 시작 화면 일치, 프레임 스트립 생성, 눈 검수 기록과 클립별 판정 |
| 5. 음악·목소리 | `audio` | 음성 ID 1개, 대사 파일 |
| 6. 조립 전 | `edit` | 박 격자(컷 경계), 컷 연결, 반복 컷, 대사 길이, src 클립과 사용 구간 |
| 6. 조립 후 | `final` | 프레임 수, 해상도, fps, 오디오 길이, 라우드니스, true peak, 눈 검수 기록 |

- 프로젝트 폴더 규칙은 `harness/gate.py` 첫머리에 있습니다. (`STORY.md`, `character.txt`, `voices.json`, `edit.json`, `sheet/`, `key/`, `clip/`, `out/final.mp4`, `qa/`) 클립 이름, 키프레임 이름, `edit.json`의 `clip:<이름>@<시작초>`는 같은 이름을 씁니다.
- 게이트는 `qa/gate-<단계>.txt`에 보고서를 남깁니다. 보고할 때는 이 파일의 `BLOCK`, `WARN` 줄을 그대로 인용합니다.
- 눈으로 봐야 하는 검사는 기록 파일을 요구합니다. 에이전트가 프레임 스트립과 컨택트 시트를 실제로 보거나 사용자의 실제 검수 결과를 받은 뒤에만 아래 줄을 씁니다.
  - `qa/clips-review.md`: `REVIEWED: <이름> <YYYY-MM-DD>` 줄과, 클립마다 `<클립 이름>: ok|trim|redo|replace` 줄. `redo`, `replace`가 남아 있으면 통과하지 못합니다. 키프레임이 없는 클립은 `nokey: <클립 이름>` 줄로 허용합니다.
  - `qa/review.md`: `REVIEWED: <이름> <YYYY-MM-DD>` 줄과, 본 결과를 적은 줄. 최종본(`out/final.mp4`)보다 나중에 작성해야 합니다.
- 임계값은 환경 변수로 바꿉니다. (`GATE_SSIM_START`, `GATE_LUFS`, `GATE_LUFS_TOL`, `GATE_TP_MAX`)
- 게이트를 고치거나 새 검사를 더하면 `bash "$SKILL_ROOT/harness/selftest.sh"`가 종료 코드 0으로 끝나야 합니다. 막아야 할 사례를 합성 프로젝트로 실제로 막는지 확인하는 셀프테스트이고, 새 검사에는 막아야 할 사례를 함께 추가합니다.

## 단계별 상세

### 1단계. 스토리·장면 기획
- `templates/STORY.md`를 복사해 채웁니다. 장면마다 시간대, 장소, 캐릭터 행동 1개, 감정 1개를 적습니다.
- 한 장면에는 행동을 1개만 넣습니다. 영상 생성 모델은 한 클립에 여러 행동이 있으면 손·소품이 변형됩니다.
- 시간대와 장소가 논리적으로 이어지는지 확인합니다. 아침 출근 장면 뒤에 일출 장면이 오면 시간이 거꾸로 갑니다.
- 음악 싱크 지점(드롭, 마지막 히트)은 기획 단계에서 초 단위로 정하고 이후 바꾸지 않습니다.

### 2단계. 캐릭터 시트
- `templates/CHARACTER_SHEET.md`로 시트를 점검합니다. 시트·키프레임·클립 프롬프트 틀은 `templates/PROMPTS.md`에 있습니다.
- 시트가 확정되면 **외형 고정문**(머리, 안경, 의상, 색상을 한 문단으로 쓴 문장)을 `character.txt` 파일로 저장합니다. 이후 모든 프롬프트에 이 파일의 문장을 그대로 붙입니다.

### 3단계. 키프레임
- 모든 키프레임 생성에 같은 캐릭터 시트를 참조 이미지로 넣고, 외형 고정문을 그대로 붙입니다.
- 생성한 이미지는 시트와 나란히 놓고 얼굴·머리·안경·의상을 대조한 뒤 통과한 것만 사용합니다.
- 이미지 생성 도구가 같은 이미지를 두 번 저장하는 경우가 있으므로(G09) 해시(md5)로 중복 파일을 거릅니다.

### 4단계. 영상 변환
- 키프레임을 영상의 **시작 화면**으로 고정하고, 캐릭터 시트를 참조 이미지로 함께 넣습니다.
- 클립 길이는 3~6초로 짧게 잡습니다. 길수록 뒤쪽에서 얼굴이 녹거나 소품이 사라집니다.
- 생성한 클립은 `scripts/clipsheet.sh`로 프레임 시트(클립의 모든 프레임)를 만들어 눈으로 확인하고, 결함이 있는 구간은 잘라 내고 쓸 수 있는 구간만 사용합니다. (`templates/SCENE_AUDIT.md`에 기록)
- 초록 배경으로 생성한 클립에서 캐릭터만 떼어 합성하는 경우 `scripts/key-plate.sh`를 사용합니다.

### 5단계. 음악·목소리
- 음악 BPM을 먼저 확정하고 `references/beat-grid.md`의 계산으로 컷 길이를 박 단위로 맞춥니다.
- 목소리는 도구에서 음성 1개를 골라 그 ID만 모든 대사에 씁니다. 대사를 합성한 뒤 받아쓰기(whisper)로 대본과 일치하는지 확인합니다.
- 유명인·정치인·저작물 캐릭터의 목소리 복제 모델은 사용하지 않습니다.

### 6단계. Remotion 조립
모션 그래픽(자막, 타이틀, 엔드카드, 화면 효과)과 최종 조립은 Remotion으로 합니다. 아래는 Remotion 공식 구성요소(`Composition`, `Sequence`, `OffthreadVideo`, `Audio`, `useCurrentFrame`, `staticFile`)를 쓰는 구조입니다.

- 프로젝트는 `npx create-video@latest`로 직접 만듭니다. 이 스킬은 Remotion 코드를 포함하지 않습니다. (라이선스는 `references/licensing.md`)
- 컷 목록을 JSON(`edit.json`)으로 두고, 각 컷을 `<Sequence from={시작프레임} durationInFrames={길이}>` 안에 `<OffthreadVideo src={staticFile(...)} />`로 배치합니다.
- 컷의 시작 프레임은 박 격자(박 길이 x 정수)에 맞춥니다.
- 자막·타이틀은 `useCurrentFrame()` 값에서 계산하는 순수 함수로 작성합니다. 같은 프레임을 다시 렌더해도 같은 결과가 나옵니다.
- 렌더는 `npx remotion render <컴포지션ID> out/picture.mp4`로 하고, 렌더 후 `scripts/mix-mux.sh`로 음악·대사를 섞어 입힙니다.
- 최종 확인은 `scripts/verify.sh`로 하고, 생성된 컨택트 시트를 직접 봅니다.

## 캐릭터 일관성 7가지

캐릭터 시트, 외형 고정문, 키프레임 시작 화면, 목소리 고정(같은 음성 ID), 대사와 입 모양 타이밍, 음악 박자, 품질 검수가 모두 맞물려야 장면이 바뀌어도 얼굴과 목소리가 같습니다. 항목별 문제와 맞추는 방법은 `references/consistency-7.md`에 있습니다.

## 비용 분기 규칙

무료 플랜으로 시안을 만들고, 상업 공개용 최종본의 음악·목소리만 유료 플랜에서 다시 생성합니다. 유료 대량 생성 전에는 예상 크레딧을 알리고 승인을 받습니다. 전체 규칙은 `references/cost-rules.md`, 현재 약관은 `references/licensing.md`에 있습니다.

## 검수 원칙

- 눈으로 보지 않은 것을 통과로 보고하지 않습니다. "렌더가 끝났다"는 통과의 근거가 아닙니다.
- 측정할 수 있는 것은 측정합니다: 프레임 수, 길이, 라우드니스(LUFS), true peak, 받아쓰기 일치 여부. 하네스가 있는 단계는 하네스의 종료 코드로 판정합니다.
- 직접 들어 보지 않은 오디오를 들었다고 보고하지 않습니다. 받아쓰기와 라우드니스로 확인했다고 보고합니다.
- 결과 보고에는 측정 수치, 고친 것, 남은 결함, 산출물 위치를 포함합니다.

하네스 검사가 없는 실수는 `references/pitfalls.md`, 도구별 사용법은 `references/providers.md`를 참고합니다.

## 스크립트 (모두 `scripts/` 아래, 프로젝트 폴더에서 실행)

| 파일 | 용도 |
|---|---|
| `dupcheck.py` | 같은 키프레임을 쓰는 반복 컷 검출 |
| `clipsheet.sh` | 프레임 시트(클립의 모든 프레임을 6x5 칸으로 배치) |
| `key-plate.sh` | 초록 배경 -> 투명 PNG |
| `mix-mux.sh` | 음악·대사 믹스와 프레임 수 게이트 mux |
| `verify.sh` | 영상 측정과 컨택트 시트 (받아쓰기 연동은 미검증) |
| `beat-grid.py` | BPM 기준 박 길이·스냅 계산 |
| `../harness/gate.py` | 단계별 통과 여부를 종료 코드로 판정 |
