# AAA 공유회 영상 제작기

> Remotion으로 30분 만에 두 개의 영상을 만든 과정.
> 1,000명이 시청한 셀피쉬클럽 AAA 공유회를 위한 대기 영상 + 후기 회상 영상.

---

## TL;DR

| 영상 | 길이 | 용도 | 파일 |
|------|------|------|------|
| **대기 영상** | 60초 루프 | 라이브 시작 30분 전 OBS에서 무한 반복 송출 | `out/waiting.mp4` |
| **후기 영상** | 30초 + BGM | 행사 후 SNS 공유용 회상 영상 | `out/recap.mp4` |

**기술 스택**: Remotion 4 (React 기반 비디오 프레임워크) · TypeScript · Pretendard + Manrope 폰트 · Pixabay 무료 음원

**핵심 인사이트**: PPT나 영상 편집 툴 없이, 코드로 영상 만들면 데이터/카피 바뀔 때마다 한 줄 고치고 재렌더만 하면 끝.

---

## 0. 시작 — "8시 30분 라이브 대기 화면 만들고 싶어"

### 원래 요청
- 8:30 시작 라이브, 8:00부터 30분간 대기 영상 틀고 싶음
- "방송 대기중 8시 30분에 시작합니다" + 발표자 라인업
- 무한 반복 영상으로 만들고 싶음 → 어떻게?

### 결정 사항 정리
1. **루프 방법**: 30분짜리 통영상 X → 짧은 60초 루프 + OBS의 "반복 재생" 옵션
2. **위치**: `tools/remotion-waiting/` (Obsidian vault 내)
3. **폰트**: 브랜드 가이드 그대로 — Pretendard (한글) + Manrope (영문)
4. **컬러**: 메인 옐로 #FBE830 + 블랙

### 발표자 정보 수집
- 사이트(`new.selfishclub.xyz/sharing/aaa`)에서 8명 정보 추출
- 사용자가 보내준 디자인 에셋 5장으로 비주얼 톤 확정 (이게 ground truth)
- 이미지 어젠다 기준으로 정리:
  - **PART 1 (20:30)** 나를·팀을 위한 OS — 다니 / 흐민 / 다다
  - **PART 2 (21:30)** 유저를 위한 Product — 오웬 / 띵크 / 비비안 / 에밀리
  - **Q&A (22:30)** 공유자 8명 전원

---

## 1. 대기 영상 (waiting.mp4)

### 구성 (60s @ 30fps · 1920×1080)

| 시간 | 화면 | 길이 |
|------|------|------|
| 0-6s | `방송 대기중 / 8:30에 시작합니다` 노란 hero | 6s |
| 6-12s | 행사 타이틀 — `AI, '딸-깍'이 가능할까요?` | 6s |
| 12-19s | `오늘 진행 순서` (PART 1·2·Q&A) | 7s |
| 19-22s | PART 01 인트로 | 3.3s |
| 22-33s | 다니·흐민·다다 (각 ~3.7s) | 11s |
| 33-36s | PART 02 인트로 | 3.3s |
| 36-52s | 오웬·띵크·비비안·에밀리 | 16s |
| 52-55s | Q&A 클로징 | 4s |
| 55-60s | 다시 hero (루프 매끄럽게) | 4.7s |

### 디자인 시그니처
- 노란 배경 + 검정 텍스트 (또는 반대)
- 키워드는 형광 노란 박스로 강조 (`[키워드]` 대괄호 → 자동 변환)
- 발표자 카드는 흑/백 교차로 시각 리듬
- 진행 인디케이터 (점 + `01 / 07`) 하단 배치

### 코드 구조
```
tools/remotion-waiting/
  src/
    constants.ts          # 데이터 (발표자, 컬러, 시간)
    fonts.ts              # Pretendard CDN 로더
    Root.tsx              # 컴포지션 등록
    Waiting.tsx           # Series로 씬 시퀀싱
    components/
      BrandLabel.tsx      # 좌상단 브랜드 라벨
      Highlight.tsx       # 노란 형광 박스 (대괄호 파싱)
    scenes/
      Hero.tsx            # 방송 대기중
      Title.tsx           # AI 딸-깍이 가능할까요?
      Agenda.tsx          # 오늘 진행 순서
      PartIntro.tsx       # PART 01/02 인트로 (재사용)
      Speaker.tsx         # 발표자 카드 (재사용)
      QnA.tsx             # Q&A 클로징
```

### 송출 방법 (OBS)
1. OBS → 소스 추가 → **미디어 소스**
2. 로컬 파일: `out/waiting.mp4`
3. **☑️ 반복** 체크 → 끝

8:00에 송출 시작 → 8:30 되면 끄고 본방송 전환.

---

## 2. 후기 영상 v1 — 카톡 채팅 스타일 (폐기)

### 발단
대기 영상 만든 다음 날, 사용자가 카톡방 후기들 보고 회상 영상 추가 요청.
- 1,000명 동시 시청한 행사라는 강조
- 카톡 후기들을 영상에 자연스럽게 녹여서
- 좋았다는 메시지 + Remotion으로 만들었다는 마무리

### 카카오톡 통계 분석 (Python으로)

```python
# CSV 파싱 → AAA 후기만 필터링 → 통계
- 고유 후기 작성자: 201명
- 총 메시지 수: 235개  
- 기간: 4/28 23:15 ~ 4/30 09:48 (약 35시간)
- 평균 후기 길이: 201자
- 최장 후기: 798자
```

### 키워드 빈도 TOP 20 (감정 위주로 픽)
| 키워드 | 횟수 |
|--------|------|
| 감사 | 175 |
| 클로드/클로드코드 | 145 |
| AI | 140 |
| 활용 | 121 |
| 인사이트 | 63 |
| 사례 | 61 |
| 도전·자극·영감 | 46 |
| 혼자·함께 | 34 |
| 용기·동기 | 24 |

### v1 구성 (만들었지만 사용자가 거절)
- Hero (5s): 1,000명이 동시에 시청한 / 셀피쉬클럽 AAA 공유회
- ChatStream (17s): 카톡 다크 UI에서 후기 7개가 위로 흐름
- Stats (4s): 키워드 클라우드
- Outro (4s): Remotion으로 만들었다

### 사용자 피드백
> "속도감이 너무 없고, 후기는 찬찬히 올라오는 것 좋은데 뭔가 저렇게 대화형으로 올라오는 것 보다 사방에서 튀어나면서 집중되게 해주고, 그래서 사람들이 말한 이 공유회가 좋았던 이유를 3가지로 탁 탁 탁 정리해주면 좋겠는데"

→ **방향 전환**: 정적 → 동적, 채팅 스크롤 → 카오스 버스트, 단순 키워드 → 3가지 이유

---

## 3. 후기 영상 v2 — 카오스 + 3가지 이유 (채택)

### 새 구성 (30s @ 30fps)

| 시간 | 씬 | 무엇 |
|------|------|------|
| 0-2s | **Hero** ⚡ | 1,000명 / 셀피쉬클럽 AAA 공유회 (빠른 진입) |
| 2-11s | **Chaos Burst** 🎆 | 후기 카드 10개가 사방에서 팡팡 |
| 11-20.5s | **3 REASONS** 🥁 | 01 혼자→함께 / 02 이론→사례 / 03 막막→자신감 |
| 20.5-23s | **요약** | "그래서 좋았다, 이 3가지" |
| 23-30s | **Outro** | 이 영상도 Remotion으로 / 누구나 만들 수 있는 세상 |

### 카오스 버스트 — 사방에서 튀어나오는 카드

```typescript
// 각 카드는 위치 + 방향 + 회전 + 크기 정보
type Quote = {
  text: string;
  author: string;
  x: number; // % of screen
  y: number;
  rot: number; // -8 ~ +8 deg
  from: "left" | "right" | "top" | "bottom";
  size: "sm" | "md" | "lg";
  accent?: boolean; // 노란 카드
};
```

**기법**:
- 각 카드 등장 간격 22프레임 (~0.73s)
- spring 애니메이션으로 튀어나오는 느낌 (damping 14, stiffness 180)
- 등장 직후 spotlight boost (잠깐 확대 후 정착)
- 등장 후 미세한 idle bob (살아있는 느낌)
- 라디얼 그라데이션 배경 펄스

### 3가지 이유 — "탁 탁 탁" 정리

후기 데이터에서 추출한 패턴:

```
01. 혼자가 아니라 [함께]였다.
    "혼자였으면 또 중간에 멈췄을텐데" — 클로드야 / 디자이너
    후기에서 '혼자' '함께' 키워드 50회+

02. 이론이 아니라 [사례]였다.
    "각자의 사례를 공유해주셔서 도움이 많이 되었어요" — 세이지
    사례 61 · 실제 55 · 직접 33

03. 막막함이 아니라 [자신감]이었다.
    "할 수 있겠다는 자신감을 얻었습니다" — 고구마 먹는 춘식이
    도전 21 · 자극 16 · 영감 9 · 용기 12
```

**디자인**: 검정 배경 + "Before(회색)" → "After(노란 박스)" 강조 + 인용구 + 데이터 근거

---

## 4. 디테일 조정

### 4-1. 헤더 영역 카드 안 가리게
사용자: *"리뷰 201 피플 요 제목 라인에는 대화 안나오게 해줘 밑에 나오게"*

→ QUOTES 배열의 모든 y 좌표를 18% 아래로 재배치 (헤더 영역 클리어)

### 4-2. 음악 — Pixabay에서 직접 픽
- 사이트: https://pixabay.com/music/search/vlog/
- 곡: **Watermello — Vlog Vlogs**
- 적용: `public/recap-music.mp3` 로 mp3 옮기고 `MUSIC_FILE` 한 줄 변경

```typescript
// src/Recap.tsx
const MUSIC_FILE: string | null = "recap-music.mp3";
const MUSIC_VOLUME = 0.55; // 0~1 사이, 본문 대화 안 묻히게

return (
  <AbsoluteFill>
    <Series>...</Series>
    {MUSIC_FILE && <Audio src={staticFile(MUSIC_FILE)} volume={MUSIC_VOLUME} />}
  </AbsoluteFill>
);
```

---

## 5. 결과물

### 두 개의 mp4
```
tools/remotion-waiting/
  out/
    waiting.mp4    5.5MB   60초 루프 (대기영상)
    recap.mp4      6.3MB   30초 + BGM (후기영상)
```

### 누구나 영상도 만들 수 있는 세상

이 영상의 마지막 메시지가 곧 이 프로젝트의 결론.

- 디자이너 없어도 → 코드로 디자인 일관성 유지
- 영상 편집자 없어도 → 데이터 바뀌면 한 줄 수정 + 재렌더
- 비싼 라이센스 없어도 → Pretendard, Manrope, Pixabay 모두 무료

---

## 6. 다음 행사에 재사용하는 법

### 발표자 / 후기만 갈아끼우기

```typescript
// src/constants.ts
export const PART1: Speaker[] = [
  { nick: "새 발표자", title: "주제 [강조워드]...", ... },
  // ...
];

export const QUOTES: Quote[] = [
  { text: "후기 한 줄", author: "닉네임", x: 4, y: 22, ... },
  // ...
];

export const REASONS: Reason[] = [
  { number: "01", beforeWord: "X", afterWord: "Y", ... },
  // ...
];
```

### 명령어
```bash
cd tools/remotion-waiting

# 미리보기 (브라우저에서 인터랙티브 편집)
npx remotion studio

# 영상 렌더
npx remotion render Waiting out/waiting.mp4
npx remotion render Recap out/recap.mp4
```

### 컬러/폰트 바꾸기
- 컬러: `src/constants.ts` → `COLORS` 객체
- 폰트: `src/fonts.ts` → CSS URL 교체

### 음악 바꾸기
- `public/recap-music.mp3` 파일 교체
- 또는 `src/Recap.tsx` 의 `MUSIC_FILE` 변수에 새 파일명

---

## 7. 배운 점

### Remotion이 잘 한 것
- **선언적 비디오** — React 컴포넌트로 씬 짜기 → 디자인 시스템 그대로 활용
- **타이포 자유도** — Pretendard 같은 한글 폰트 CDN 바로 쓸 수 있음
- **데이터 기반** — `constants.ts` 한 파일만 바꾸면 영상 전체가 갱신됨
- **빠른 반복** — 60초짜리 1080p 풀 렌더가 ~50초

### 주의할 점
- `delayRender` 폰트 로딩이 가끔 timeout → 8초 hard cap + 시스템 폰트 fallback 처리
- `Audio` 컴포넌트는 mp3 파일 없으면 에러 → null 체크 패턴
- 동시성 4로 렌더하면 빠르지만, 폰트 CDN을 4번 동시 호출 → 안정성 위해 onerror 처리 필수

### 사용자 피드백 루프
1. v1 만들고 → "속도감 없다, 너무 정적이다" 피드백
2. 완전히 갈아엎어서 v2 (카오스 + 3가지 이유) 제작
3. 디테일 조정 (헤더 안 가리기)
4. 음악 추가 → 완성

> 정적인 정보 전달 → 감정과 핵심을 전하는 30초.
> 같은 데이터로도 구성에 따라 영상 톤이 완전히 달라짐.

---

## 부록: 카카오톡 후기 키워드 분석 코드

```python
import csv, re
from collections import Counter

path = ".../KakaoTalk_Chat.csv"
rows = []
with open(path, encoding="utf-8-sig") as f:
    reader = csv.reader(f)
    next(reader)  # skip header
    for row in reader:
        if len(row) >= 3:
            rows.append(row)

pat = re.compile(r"AAA\s*공유회\s*후기|AAA\s*후기")
reviews = [r for r in rows if pat.search(r[2]) and r[0].startswith("2026-04-2")]

# 키워드 빈도
keywords = ["클로드", "AI", "활용", "인사이트", "사례", "도전", "영감", ...]
all_text = "\n".join(m for _,_,m in reviews)
counts = Counter({kw: all_text.count(kw) for kw in keywords})

print(f"고유 작성자: {len(set(u for _,u,_ in reviews))}명")
print(f"총 메시지: {len(reviews)}개")
print(counts.most_common(20))
```

---

*Made with Remotion + Claude Code · 2026.04.30*
