세로(9:16) 설명 쇼츠를 만드는 흐름 — 건축·과학·사건의 "왜?"를 3D 모형 장면 + 내레이션 + 2~3단어 말 자막 + 큰 숫자 카드로 30초~3분에 설명한다. 사용자가 "쇼츠 만들어", "세로 영상", "설명 쇼츠", "이 채널 쇼츠 스타일로", "3D로 설명하는 영상"이라고 하거나 참고 채널의 세로 영상 스타일을 따라 하고 싶다고 할 때 쓴다. 가로 영상은 real-ui-design 스킬과 templates/video.
Installs into .claude/skills of the current project.
Are you the author of Shorts Explainer?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ssap-pa-shorts-explainer)
---
name: shorts-explainer
description: 세로(9:16) 설명 쇼츠를 만드는 흐름 — 건축·과학·사건의 "왜?"를 3D 모형 장면 + 내레이션 + 2~3단어 말 자막 + 큰 숫자 카드로 30초~3분에 설명한다. 사용자가 "쇼츠 만들어", "세로 영상", "설명 쇼츠", "이 채널 쇼츠 스타일로", "3D로 설명하는 영상"이라고 하거나 참고 채널의 세로 영상 스타일을 따라 하고 싶다고 할 때 쓴다. 가로 영상은 real-ui-design 스킬과 templates/video.
---
# 세로 설명 쇼츠
새 쇼츠는 `python tools/new_video.py --shorts <slug>`로 시작한다 — 빈 틀(`templates/shorts-blank`: 3D 장면 하나 + 빌더 뼈대)이 복사된다. 완성 예제를 먼저 보고 싶으면 `python tools/new_video.py --shorts --example <slug>`(「부르즈 할리파는 왜 계단처럼 깎였을까」 40초 — 장면 6개, three.js 3D, 말 자막, 숫자 카드). 예제 파일을 새 주제에 고쳐 쓰지 말고, 빈 틀에서 시작해 필요한 부분만 예제에서 가져온다.
**목소리부터 확인.** 영상 폴더 `script.json`의 `settings.voice.voice_id`가 비어 있으면 대본보다 먼저 고르게 한다(`python tools/voice.py --voices` — 내 목소리 + 기본 제공 목소리). 비어 있으면 `voice.py`가 멈춘다. 데모 음성(`--demo`)은 시험용이지 업로드용이 아니다.
## 0. 참고 채널이 있으면 — 스타일을 규칙으로 먼저 저장
사용자가 참고 채널·영상을 주면 만들기 전에 분석해 `memory/rules`에 남긴다(feedback-loop 스킬). 다음 쇼츠부터 묻지 않고 적용된다.
- 조회수가 높은 영상 2~3편의 프레임 시트(2~3초 간격)와 자막을 본다. 받기: `python -m yt_dlp -f "bv*[width<=720]+ba/b[width<=720]" --write-auto-subs --sub-langs ko <URL>`(분석용, 영상·장면을 그대로 쓰지 않는다). 세로 영상은 높이가 1280이라 `height<=720`이면 받을 게 없다고 멈춘다 — 너비로 거른다(사고: 2026-11-02 참고 채널 분석에서 3편 모두 실패).
- 목록·조회수: `python -m yt_dlp --flat-playlist --print "%(id)s|%(view_count)s|%(title)s" <채널URL>/shorts`. 제목이 영어로 나오면 자동 번역이니 `--write-info-json`의 원제를 본다. PowerShell에서 출력을 `>`로 받으면 한글이 깨진다 — 파이썬이 직접 UTF-8 파일로 쓴다.
- 뽑을 것: 길이, 컷 간격, 화면 재료(실사·3D·그림), 자막 위치·크기·단어 수, 숫자 카드 쓰는 법, **대본 뼈대**(첫 문장 형식, 갈등 문장, 반전 문장, 마무리), 숫자 비유 방식, 말투.
- 남기지 않을 것: 그 채널의 고유 문구를 그대로 베끼기, 영상·장면 재사용, 같은 주제 그대로 따라 하기.
## 1. 주제 제안 (주제가 없거나 "제안해 줘"일 때) ✋
**후보 3개**를 표로 보여 주고 사용자가 고른다. 두 갈래를 섞는다.
- **시의성 주제:** 최근 24시간 이내 보도가 기본값. 보도 시각을 한국 시간으로 환산해 확인하고, 24시간 밖이면 뺀다. 후속 보도만 새로우면 "후속 보도 기준"이라고 밝힌다. 2차 보도는 "원문 확인 전"이라고 적는다.
- **상시 "왜?" 설명 주제:** 날짜와 상관없이 늘 궁금한 것 — 유명 건축물·자연 현상·기계·사건의 "왜 ~일까?"(예: 피사의 사탑은 왜 아직 안 쓰러질까, 비행기는 왜 그렇게 높이 날까). 3D 모형으로 원리를 보여 줄 수 있는 것을 고른다.
- 후보마다: 질문형 한 줄, 숨길 답, 가장 센 숫자(체감 비교 가능?), 3D로 보여 줄 원리, 출처 후보, 채널 주제(사용자에게 물어 memory 규칙으로 남긴 값)와의 연결. 직전 영상과 겹치면 빼고 이유를 적는다.
## 2. 스타일 고르기 ✋ (장면을 만들기 전에)
두 스타일을 2~3줄씩 설명하고 고르게 한다. 기본은 로우폴리. 고른 것은 영상 폴더 `SYNOPSIS.md`의 "스타일" 줄에 적는다.
- **로우폴리 3D (기본, 무료)** — three.js 코드로 그린 건축 모형 느낌. 평면 음영(flat shading), 베이지·회색 위주 색, 따뜻한 오후 빛. 숫자·위치가 정확한 도식이라 원리 설명에 강하다. 비용 0, 고치기는 코드 한 줄.
- **실사 스타일 (전체 키트)** — 시선을 잡는 컷(첫 장면·장면 전환·반전)을 AI 실사 영상(Gemini, 컷당 약 $1)으로 만들고 원리 설명 컷만 3D 도식으로 잇는 방식. AI 영상 생성 연결은 전체 키트에 있다(https://ssapable.com/courses/youtube-automation-kit). 무료 키트에서 고르면 한 줄로 알리고, 로우폴리로 가거나 직접 찍었거나 저작권 문제없는 실제 영상을 같은 자리에 쓴다. 없는 도구를 지어내지 않는다.
## 3. 대본 ✋
- 한 편 = 질문 하나("왜 ~일까?"). 답은 끝에서 공개한다(제목·오프닝에 답을 넣지 않는다 — START-HERE 3번에서 직접 가르쳐 보는 규칙).
- 예제 뼈대: ① "여기 ~이 있습니다" + 가장 센 숫자 → ② 배경 → ③ "진짜 문제는 ~" → ④ "그래서 ~하기로 합니다" → ⑤ 원리 → ⑥ 결과 숫자 + 체감 비교.
- 사실은 원문 출처로 확인하고 `RESEARCH.md`에 적는다(no-invented-facts). 숫자는 대본에 한글로, 자막엔 `SUB`로 숫자로(빌더 상단).
- **큰 수치는 반드시 체감 비교와 같이**(big-numbers-relatable): 828m → "아파트 이백팔십 층", 435m → "축구장 네 개". 화면 카드도 비교를 크게, 원래 수치를 작게("아파트 280층 / 828m"). 환산 근거는 RESEARCH에. `check_script.py`가 비교 없는 큰 수치를 막는다(사고: 예제 첫 문장 '팔백이십팔 미터짜리 건물').
- 한 장면 = 한 문장. 장면 6~12개(30~60초) 또는 20~30개(2~3분).
## 4. 음성
`python tools/voice.py videos/<slug>` — 첫 장면은 `"tone": "hype"`. 쇼츠는 `speed` 1.05~1.1이 잘 맞는다.
## 5. 장면
- 장면 HTML 하나 = 문장 1~2개, 그 안에서도 카메라를 바꿔 **2~4초마다 그림이 바뀌게** 한다(`if (t < c.다음) S.orbit(...) else S.orbit(...)`). 빈 틀의 `clips/v1/a.html`을 복사해 `b.html`…로 늘리고 빌더 `shots()`에 한 줄씩 더한다.
- 도구: `tools/realkit/scene3d.js`.
- 바닥과 도시: `S.ground`
- 상자와 Y자 평면 블록: `S.box`·`S.yBlock`
- 땅속 단면(지층 + 묻힌 기초): `S.section({layers, found})` — 탑이 왜 기우는지·버티는지처럼 땅 밑을 보여 줄 때. `S.ground`와 같이 쓰지 않는다.
- 바람과 흐름: `S.trails`(굵은 점 꼬리, 휴대폰에서 잘 보임)·`S.streaks`(선)
- 카메라: `S.orbit`
- 3D 위치 꼬리표: `S.tag`(움직이는 물체는 위치 대신 함수 `() => [x, y, z]`)
- 잘라 보이기: `S.renderer.clippingPlanes`
- 계속 쓸 모형은 `clips/<clip>/<모형>.js`로 따로 둔다(예제: `burj.js`).
- 화면 신호는 대사 단어에서: `V.T('v1-s3', '오백십팔', base='v1-s3')` → HTML `data-anim="pop@m518"`, JS `RK.cues.m518`.
- 큰 숫자·낱말 카드 `.kw`(위쪽 1/3), 3D 꼬리표 `.tag3d`, 말 자막은 빌더가 `V.captions(...)`로 자동.
- 숫자 세기 `data-count`는 천 단위 쉼표를 넣는다. **연도는 `data-year`**(쉼표 없음, 1,178 → 1178), 다른 숫자도 끄려면 `data-sep="none"`.
- 자막 숫자 바꾸기 `SUB`는 낱말 전체가 같을 때만 바뀐다('사'→4를 넣어도 피사·공사는 그대로). 한 글자 key는 조사가 붙으면 안 바뀌니 `'사십': '40'`처럼 두 글자 이상으로 적는다. 숫자 뒤 단위는 자막에서 붙는다('19층', `'센티미터': 'cm'`이면 '40cm').
- **세로 안전 영역:** 위 220px·아래 380px엔 글자를 두지 않는다(쇼츠 화면 버튼·제목이 덮음). 말 자막 띠는 1100~1260px.
- `S.tag`는 세로 화면에서 꼬리표를 이 안전 영역 안(좌우 40px 여백)에 붙잡고, 자막 띠에 걸리면 위·아래로 비킨다. 끄기 `{safe: false}`, 자막 피하기만 끄기 `{avoid: false}`.
- **좌우가 좁다:** 화면 반폭 = 카메라 거리 × 약 0.22(fov 42 기준, `S.viewHalf(거리).w`). 거리 900이면 좌우 ±약 200단위가 화면 끝이다. 꼬리표 붙일 점은 그 70% 안쪽(거리 900에서 ±140)에 두고, 넓은 단면은 카메라를 뒤로 빼거나 비스듬히 본다.
- 꼬리표는 붙잡혀도 3D 점과 떨어져 보일 수 있으니 프레임 시트로 확인하고, 어긋나면 점을 옮긴다.
- 정지 시안 먼저: `RK_FORMAT=vertical python tools/realkit/realkit.py still videos/<slug>/clips/v1/a.html 2.0 a.png` → 사용자 확인 ✋ (Windows PowerShell은 `$env:RK_FORMAT="vertical"`).
### 실제 영상 컷 + 3D 잇기 (AI 컷 생성은 전체 키트)
무료 키트에서는 AI 컷 자리에 직접 찍었거나 저작권 문제없는 실제 영상을 깐다. 깔고 잇는 방식은 같다.
- **장면마다 첫 문장은 실제 영상 컷**을 전체 화면으로 깔고, 두 번째 문장 신호에서 사라지게(fadeout) 한 뒤 땅속 단면·수치 설명은 3D로 잇는다.
- 영상 파일은 `videos/<slug>/gen/g1.mp4`처럼 영상 폴더에 두고 출처를 RESEARCH.md에 적는다.
- HTML: `<div id="ai" data-anim="fadeout@s2"><img data-seq="src/g1" data-t0="0"></div>`, CSS `#ai{position:absolute;inset:0;z-index:30;background:#000}`, `#ai img{width:100%;height:100%;object-fit:cover}`, `#ai::after`에 위아래 어두운 그라데이션(자막·카드가 잘 읽히게). 숫자 카드(z 55)·말 자막(z 60)은 그 위.
- 빌더: `rk.seq(HERE / 'gen' / 'g1.mp4', S / 'src' / 'g1', t0=0, dur=V.dur('v1-s1') + .6, size=(1080, 1920))` 다음 `shot('a.html', [...], a, [...], seqs=['src/g1'])`(빈 틀의 `shot()`).
- AI 컷이 덮는 동안엔 3D 모형 위치에 붙는 `.tag3d` 꼬리표를 띄우지 않는다(엉뚱한 곳에 뜸) — 꼬리표의 `pop@`은 `s2` 이후 신호로.
- 남의 영상은 쓰지 않는다(저작권). 직접 찍었거나 사용 허락이 확인된 것만.
## 6. 렌더·합본·검수
```bash
python videos/<slug>/build_v1.py # renders/v1-vN.mp4 + 프레임 시트(1초 간격)
python tools/make_final.py videos/<slug> final-v1
python tools/qa.py videos/<slug> final-v1 # 싱크·발음·배경음·재발
```
프레임 시트를 직접 본다. 실제로 났던 사고는 이렇다.
- 카메라가 건물 속을 지나가 화면이 회색으로 가려짐 → `cityMin`으로 막는다.
- 바람 입자가 밝은 배경에 묻힘 → 진한 색 `S.trails`로 그린다.
- 자막과 숫자 카드가 겹침, 꼬리표가 화면 밖·자막 위에 걸림 → 안전 영역 안내대로.
- 배경음이 데모 합성음이면 업로드 전에 저작권 문제없는 곡으로 바꾼다(영상 폴더 `bgm.json`).
## 7. 업로드 준비 ✋
제목은 질문형, 답을 넣지 않는다. 쇼츠는 60초를 넘으면(최대 3분) 길이에 맞게 끝까지 볼 이유를 중간에 한 번 더 건다. 업로드는 사용자 확인 뒤.