한눈에 — 명령 다섯 개
처음 한 번만 npm install 을 해 둔다. 그 뒤로는 아래 다섯 개만 쓴다. ep01 자리에 편 번호를 넣는다.
| 명령 | 하는 일 | 언제 |
|---|---|---|
npm run prompts | Gemini 프롬프트 문서를 만든다 (이미 있는 그림은 ✅ 표시) | 그림 뽑기 전, 진행 상황 볼 때 |
npm run art -- ep01 | 그림을 처리하고 빠진 그림 목록을 보여준다 | 그림을 넣을 때마다 |
npm run studio | 브라우저에서 미리보기 | 연출을 고치며 확인할 때 |
npm run voice -- ep01 | 녹음 파일 길이에 맞춰 컷 타이밍을 다시 잡는다 | 목소리를 바꿔 끼운 뒤 |
npm run make -- ep01 | 위 과정을 묶어 영상과 자막까지 만든다 | 완성본을 뽑을 때 |
프롬프트 문서 만들기
그림 목록(art.json)에 적어 둔 묘사에 화풍 문장과 배경색 지시를 자동으로 붙여, 그대로 붙여넣을 수 있는 문서로 만든다.
npm run prompts
문서는 두 군데에 생긴다.
| 문서 | 내용 | 횟수 |
|---|---|---|
| art/common/GEMINI_PROMPTS.md | 아빠 · 아이 표정, 리액션 컷인, 거실 · 아이 방 배경 (18장) | 한 번만. 모든 편이 같이 쓴다 |
| episodes/01-…/GEMINI_PROMPTS.md | 그 편에만 나오는 배경 · 인물 · 장면 · 소품 (1편은 9장) | 편마다 |
문구를 고치고 싶을 때. 문서를 직접 고치지 않는다. video/src/art-common.json(공통)이나 video/src/ep01/art.json(편별)의 묘사를 고치고 npm run prompts 를 다시 실행한다.
Gemini에서 그림 뽑기
사람이 하는 유일한 반복 작업이다. 문서의 블록을 위에서부터 하나씩 처리한다.
- 블록의 프롬프트를 통째로 복사해 Gemini에 붙여넣는다.
- 블록의 첨부 이미지를 같이 올린다. ①은 화풍 앵커(
art/anchor/style-cutin.png), ②는 같은 사람을 유지하기 위한 기준 그림이다. 순서를 지킨다. - 결과를 블록의 저장 경로와 이름 그대로 넣는다. 배경 제거나 크기 조절은 하지 않는다.
- 한 사람은 한 대화창에서 끝내고, 다음 사람이나 배경은 새 대화창에서 시작한다. 대화가 길어지면 화풍이 흐려진다.
저장 위치
| 종류 | 저장 경로 | 뽑는 모양 |
|---|---|---|
| 아빠 · 아이 전신 | art/common/dad/panic.png | 초록 배경, 2:3 세로 |
| 리액션 컷인 | art/common/cutin/dad-panic.png | 초록 배경, 1:1, 가슴 위 |
| 공통 배경 | art/common/bg/living-room.png | 사람 없음, 16:9 |
| 편별 배경 | episodes/01-…/art/bg/motel-counter.png | 사람 없음, 16:9 |
| 편별 인물 | episodes/01-…/art/char/dad-young.png | 초록 배경, 2:3 세로 |
| 한 장짜리 장면 | episodes/01-…/art/full/hotel-mansion.png | 완성된 그림, 16:9 |
| 소품 | episodes/01-…/art/prop/hotel.png | 초록 배경, 1:1 |
1편에서 실제로 생긴 문제.
- 컷인을 다른 폴더에 저장.
art/common/dad/dad-panic.png가 아니라art/common/cutin/dad-panic.png다. 폴더가 다르면 그림이 없는 것으로 처리된다. - 한 장짜리 장면의 하늘이 초록으로 나옴. 초록 배경은 인물 · 컷인 · 소품에만 쓴다. 장면 그림에 초록이 넓게 남으면 하늘색으로 채워 주지만 가장자리가 지저분해질 수 있으니 다시 뽑는 편이 낫다.
- 그림에 글자가 들어감 (웃는 아이 옆에 일본어 의성어). 글자는 전부 코드가 얹으므로 그림에는 없어야 한다.
- 그림 둘레에 흰 테두리. 그 그림의
art.json항목에"inset": 0.025를 넣으면 테두리만큼 잘라낸다.
다시 뽑을 때 이어서 보내는 문장
| 문제 | 문장 |
|---|---|
| 배경이 단색 초록이 아님 | Redo it with a perfectly flat pure green #00FF00 background, no shadow, no floor. |
| 몸이 잘림 | Zoom out so the whole body fits with empty margin on every side. |
| 다른 사람처럼 나옴 | Keep the exact same face, hair and clothes as attached image 2. Only change the pose. |
| 글자가 들어감 | Remove all text and letters; leave signs blank. |
| 장면 하늘이 초록임 | This is a finished scene, not a cutout: paint a real sky, no green screen anywhere. |
| 배경에 사람이 있음 | Remove every person. Background only. |
그림 처리
원본은 건드리지 않고, 영상이 읽을 사본을 만든다. 새로 넣었거나 바뀐 그림만 처리한다.
npm run art -- ep01
- 인물 · 컷인 · 소품: 초록 배경을 지우고, 여백을 자르고, 크기를 맞춘다.
- 배경 · 장면: 16:9로 맞춰 자른다.
- 끝에 아직 없는 그림 목록을 보여준다. 없는 자리는 영상에서 점선 임시 그림으로 나오므로, 한 장씩 넣어 가며 확인해도 된다.
경고가 나오면
| 경고 | 뜻과 할 일 |
|---|---|
| 테두리가 초록/마젠타 단색이 아니라… | 배경을 못 지웠다. 위 표의 문장으로 다시 뽑는다 |
| 그림이 가장자리에 닿음 | 몸이 잘렸을 수 있다. 컷인은 가슴에서 잘리는 게 정상이라 무시해도 된다 |
| 원본이 작아서 흐릴 수 있다 | 더 큰 해상도로 받거나 Upscayl(무료)로 2배 키운다 |
| 초록 배경이 남아 있어 … 로 채웠다 | 장면 그림에 초록이 있었다. art.json 의 "sky" 로 색을 정하거나 다시 뽑는다 |
| 16:9 가 아니라 … 잘린다 | Gemini에서 비율을 16:9로 골라 다시 뽑는다 |
목소리
처음에는 Windows 내장 음성으로 자동 생성된다. 흐름을 확인하는 용도이고, 올릴 때는 직접 녹음한 목소리로 바꾸는 것을 권한다. 부모가 1인칭으로 들려주는 이야기라서 실제 목소리가 가장 잘 맞는다.
직접 녹음해서 바꿔 끼우기
- 녹음 대본을 만든다. 파일 이름 · 화자 · 대사가 한 줄씩 정리된
video/out/ep01/voice-script.md가 생긴다.npm run voice -- ep01 sheet
- 한 줄을 한 파일로 녹음해
video/public/ep01/voice/에 같은 이름의 WAV로 덮어쓴다 (예:c01-0.wav). 길게 한 번에 녹음한 뒤 Audacity(무료)에서 줄마다 잘라 내보내도 된다. - 타이밍을 다시 잡는다. 각 파일의 길이를 재서 컷 길이와 자막 시각을 맞춘다.
npm run voice -- ep01
video/src/ep01/script.json맨 위"title"줄 아래에 한 줄을 추가한다. 임시 음성은 한 목소리를 아빠는 낮게, 아이는 높게 변조해서 쓰는데, 이 줄이 그 변조를 끈다. 빼먹으면 실제 목소리가 일그러진다."rawVoice": true,
- 렌더한다 (다음 장).
녹음한 뒤에는 --tts 를 붙이지 않는다. npm run make -- ep01 --tts 나 npm run tts -- ep01 은 음성 파일을 임시 음성으로 덮어쓴다. 녹음 원본은 다른 폴더에도 따로 보관해 둔다.
녹음 요령
- 스마트폰 기본 녹음 앱이면 충분하다. 입에서 한 뼘 거리, 옷장 앞이나 이불 속처럼 울림이 없는 곳에서.
- 파일 앞뒤의 무음은 0.1초 안쪽으로 자른다. 무음이 길면 컷이 늘어진다.
- WAV만 읽는다. m4a나 mp3로 녹음했으면 Audacity에서 WAV로 내보낸다.
- 아이 대사는 실제 아이가 녹음하면 가장 좋다. 어렵다면 그 줄만 AI 음성으로 섞어도 된다.
AI 음성을 쓸 때
타입캐스트 · ElevenLabs · 클로바더빙 같은 서비스에서 대사별로 파일을 내려받아, 위와 똑같이 이름을 맞춰 넣고 3~5번을 진행한다.
대사를 고쳤을 때 (임시 음성 그대로 쓰는 경우)
npm run make -- ep01 --tts
렌더
프롬프트 문서 갱신 → 그림 처리 → (음성이 없을 때만) 임시 음성 → 영상 → 자막 순서로 한 번에 돈다. 4분짜리 영상에 6~7분쯤 걸린다.
npm run make -- ep01
| 결과 | 내용 |
|---|---|
video/out/ep01/ep01.mp4 | 1920×1080 완성 영상 (자막이 화면에 들어가 있다) |
video/out/ep01/subtitles.srt | 유튜브에 따로 올리는 자막 파일 |
배경음악은 들어가지 않는다. 유튜브 오디오 보관함 곡을 편집 프로그램에서 −20dB 정도로 깔거나, 유튜브 스튜디오에서 추가한다.
렌더 전에 미리 보기
npm run studio
브라우저가 열리면 왼쪽에서 Ep01 을 고른다. 파일을 고치면 바로 반영된다.
연출 고치기
움직임은 video/src/ep01/script.json 에 글로 적혀 있다. 컷마다 무대(scene)를 정하고, 대사마다 그 순간의 연출을 붙인다.
가만히 둬도 되는 것
- 말하는 인물이 까딱거린다 (대사의
who와 인물의id가 같을 때). - 표정이 바뀌면 젤리처럼 눌렸다 튄다.
- 컷 내내 카메라가 천천히 밀고 들어간다.
- 인물 발밑에 그림자가 생기고, 가만히 있어도 숨을 쉰다.
컷의 무대 — scene
"scene": {
"bg": "common/bg/living-room",
"actors": [
{"id":"kid","art":"common/kid/normal","x":0.3,"enter":"left"},
{"id":"dad","art":"common/dad/normal","x":0.68}
]
}| 항목 | 뜻 |
|---|---|
bg | 배경 그림. 한 장짜리 장면(full/…)도 여기에 넣는다 |
tone | "flashback" 이면 빛바랜 색과 빨간 점선 테두리 |
actors 의 x · h | 발 위치(0 왼쪽 ~ 1 오른쪽)와 키(화면 높이 대비). 키를 안 쓰면 아빠 0.64, 아이 0.43 |
enter | 등장: left · right 미끄러져 들어옴, drop 위에서 떨어짐, pop 튀어나옴 |
flip | true 면 좌우 반전 (아빠는 왼쪽, 아이는 오른쪽을 보게 그려져 있다) |
at | 몇 번째 대사부터 나올지 (0부터 센다). 없으면 컷 시작부터 |
props | 소품. x · y 중심 위치, w 폭, float 둥둥 뜸, dim 흐릿하게 |
대사에 붙이는 연출
{"who":"dad","text":"어... 그게...","pose":{"dad":"common/dad/panic"},"focus":"dad","cutin":"common/cutin/dad-panic"}| 항목 | 효과 |
|---|---|
pose | 이 대사부터 그 인물의 그림(표정)을 바꾼다 |
focus | 이 대사 동안 그 인물 쪽으로 카메라를 당긴다 |
cutin | 큰 얼굴이 별 모양 폭발과 함께 옆에서 튀어나온다 (아빠는 오른쪽, 아이는 왼쪽) |
fx | shake 화면 흔들림, lines 집중선, flash 번쩍 |
pop | 큰 글자가 튀어나온다 (예: "???") |
sfx · sfxAfter | 효과음: boing 삐끗, page 책장, stinger 강조, dudung 뚜둥(대사 뒤, 화면 흔들림과 큰 글자 포함) |
tts | 임시 음성이 읽을 문장. 숫자 · 영어 · 괄호처럼 잘못 읽는 대사에만 쓴다 |
연출만 고쳤으면 음성을 다시 만들 필요가 없다. npm run studio 로 확인하고 npm run make -- ep01 로 다시 뽑는다. 대사 문장을 고쳤을 때만 음성을 다시 만든다.
새 편을 만들 때
공통 그림(가족 · 집)은 이미 있으니, 편마다 새로 필요한 것은 그 편의 그림 열 장 안팎과 파일 두 개다. 파일 두 개는 원고를 Claude에게 주고 "1편처럼 만들어 줘"라고 하면 된다.
아직 1편 전용인 부분. 2편을 만들기 전에 손봐야 한다.
- "한 문장 정리" 컷의 세 칸 그림과 문구, 끝 화면의 제목이 코드(
video/src/Episode.tsx)에 1편 내용으로 들어 있다. - 썸네일(
video/src/Thumbnail.tsx)은 예전 스토리보드 그림을 쓴다.
파일 지도
| 위치 | 무엇 | 누가 고치나 |
|---|---|---|
art/anchor/style-cutin.png | 화풍 앵커. 모든 프롬프트에 ①로 첨부 | 바꾸면 전체 화풍이 바뀐다 |
art/common/ | 공통 그림 원본 (아빠 · 아이 · 컷인 · 집) | 사람 (Gemini 결과 저장) |
episodes/NN-…/art/ | 그 편의 그림 원본 | 사람 (Gemini 결과 저장) |
video/src/art-common.json | 공통 그림 목록, 아빠 · 아이 생김새 묘사 | 생김새를 바꿀 때 |
video/src/epNN/art.json | 편별 그림 목록과 묘사 | 그림을 추가하거나 묘사를 고칠 때 |
video/src/epNN/script.json | 컷 · 대사 · 연출 | 대사나 연출을 고칠 때 |
video/public/epNN/voice/ | 대사별 음성 WAV | 녹음 파일로 덮어쓴다 |
video/public/art/ · src/assets.json | 처리된 그림과 그 목록 | 자동 생성. 손대지 않는다 |
video/out/epNN/ | 완성 영상, 자막, 녹음 대본 | 자동 생성 |