Files
web-page-backend/docs/superpowers/specs/2026-05-01-music-lab-youtube-monetization-design.md
gahusb 54d67f892c docs(spec): music-lab YouTube 수익화 고도화 설계 문서 추가
시장 조사 자동화 + 영상 제작 파이프라인 + 수익화 추적 전체 설계.
Phase 1(영상 제작) → Phase 2(시장 조사) → Phase 3(YouTube API) 로드맵 포함.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 11:14:25 +09:00

360 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# music-lab YouTube 수익화 고도화 설계
> 작성일: 2026-05-01
> 범위: music-lab + agent-office 확장
---
## 1. 개요
Suno API로 생성한 음악을 YouTube 업로드 가능한 완성 영상으로 만들고, 시장 수요 분석을 통해 수익이 나는 콘텐츠를 정기적으로 생산하는 파이프라인 구축.
**핵심 목표:**
- 시장 조사 자동화 → 만들 만한 장르/스타일 추천
- 음악 + 영상 합성 → YouTube 업로드 패키지(MP4 + 메타데이터) 자동 생성
- 수익 추적 → 채널별·장르별·국가별 RPM 분석
- **Phase 1**: 파일 내보내기(수동 업로드) → **Phase 3**: YouTube API 자동 업로드
---
## 2. 결정 사항 요약
| 항목 | 결정 |
|------|------|
| 자동화 수준 | 반자동 — 수집·추천 자동, 생성·업로드 수동 트리거 |
| 업로드 방식 | Phase 1: 파일 내보내기, Phase 3: YouTube API |
| 영상 포맷 | 오디오 비주얼라이저 + AI 이미지 슬라이드쇼 |
| 시장 조사 데이터 | YouTube 트렌드 + Google Trends + Billboard (해외 시장 포함) |
| 음악 언어 전략 | 인스트루멘탈 + 영어 가사 혼합 |
| 이미지 소스 | Suno 커버이미지 + Pexels/Unsplash (추후 Stable Diffusion) |
| 주력 해외 시장 | 브라질, 인도네시아, 멕시코, 글로벌 |
---
## 3. 아키텍처
```
[외부 데이터 소스]
YouTube Data API v3 · Google Trends · Billboard · Pexels/Unsplash
↓ 매일 09:00 스케줄
[agent-office :18900]
YouTubeResearchAgent (신규)
- 국가별 트렌딩 수집·분석
- POST /api/music/market/ingest → music-lab push
- 매주 월요일 08:00 텔레그램 인사이트 리포트
[music-lab :18600]
기존: 음악 생성 · 라이브러리
신규: 시장 데이터 저장 · 영상 제작 파이프라인 · 수익화 추적
[내보내기 패키지]
output.mp4 + thumbnail.jpg + metadata.json
(Phase 3: YouTube API 자동 업로드)
```
**변경 없는 것:** 컨테이너 수, 포트 배정, Nginx 라우팅 (경로 1개 추가 제외)
---
## 4. DB 스키마 (신규)
### 4-1. music.db 신규 테이블
#### `market_trends`
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | INTEGER PK | |
| source | TEXT | `'youtube'` \| `'google_trends'` \| `'billboard'` |
| country | TEXT | `'BR'` \| `'ID'` \| `'MX'` \| `'US'` \| `'KR'` … |
| genre | TEXT | 장르 문자열 |
| keyword | TEXT | 검색 키워드 |
| score | REAL | 정규화 인기도 (0.0~1.0) |
| rank | INTEGER | 차트 순위 (nullable) |
| metadata | TEXT | JSON — 추가 원본 데이터 |
| collected_at | TEXT | ISO8601 |
인덱스: `(country, source, collected_at DESC)`
#### `trend_reports`
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | INTEGER PK | |
| report_date | TEXT UNIQUE | YYYY-MM-DD |
| top_genres | TEXT | JSON 배열 `[{genre, score, countries}]` |
| top_keywords | TEXT | JSON 배열 |
| recommended_styles | TEXT | JSON `[{genre, prompt, countries, reason}]` |
| insights | TEXT | AI 분석 텍스트 |
| created_at | TEXT | ISO8601 |
#### `video_projects`
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | INTEGER PK | |
| track_id | INTEGER FK | → music_library.id |
| format | TEXT | `'visualizer'` \| `'slideshow'` |
| status | TEXT | `'pending'` \| `'rendering'` \| `'done'` \| `'failed'` |
| output_path | TEXT | MP4 로컬 경로 |
| output_url | TEXT | `/media/videos/…` 서빙 URL |
| thumbnail_path | TEXT | JPG 로컬 경로 |
| target_countries | TEXT | JSON 배열 `['BR', 'ID']` |
| yt_title | TEXT | Claude API 생성 제목 (최대 100자) |
| yt_description | TEXT | Claude API 생성 설명 (해시태그 포함) |
| yt_tags | TEXT | JSON 배열 (10-15개, 국가별 현지화) |
| render_params | TEXT | JSON — 렌더링 파라미터 (색상, 전환 효과 등) |
| error | TEXT | 실패 시 에러 메시지 |
| created_at | TEXT | ISO8601 |
| completed_at | TEXT | ISO8601 (nullable) |
#### `revenue_records`
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | INTEGER PK | |
| video_project_id | INTEGER FK | → video_projects.id (nullable) |
| yt_video_id | TEXT | YouTube 영상 ID |
| record_month | TEXT | YYYY-MM |
| views | INTEGER | 조회수 |
| watch_hours | REAL | 시청 시간 (시간 단위) |
| revenue_usd | REAL | 수익 (USD) |
| rpm_usd | REAL | revenue / views * 1000 |
| country | TEXT | 국가별 분석용 (nullable) |
| source | TEXT | `'manual'` \| `'youtube_api'` |
| created_at | TEXT | ISO8601 |
### 4-2. agent_office.db 신규 테이블
#### `youtube_research_jobs`
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | INTEGER PK | |
| status | TEXT | `'running'` \| `'completed'` \| `'failed'` |
| countries | TEXT | JSON 배열 — 수집 대상 국가 |
| trends_collected | INTEGER | 수집된 트렌드 건수 |
| report_id | INTEGER | 생성된 trend_reports.id (nullable) |
| error | TEXT | 실패 시 에러 |
| started_at | TEXT | ISO8601 |
| completed_at | TEXT | ISO8601 (nullable) |
---
## 5. 신규 API 엔드포인트
### 5-1. music-lab — 시장 조사
| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | `/api/music/market/trends` | 트렌드 목록 (`country`, `genre`, `source`, `days` 필터) |
| GET | `/api/music/market/report/latest` | 최신 분석 리포트 + 추천 스타일 |
| GET | `/api/music/market/report` | 리포트 이력 |
| POST | `/api/music/market/ingest` | agent-office → 트렌드 데이터 수신 |
| GET | `/api/music/market/suggest` | 트렌드 기반 제작 아이디어 추천 |
### 5-2. music-lab — 영상 제작
| 메서드 | 경로 | 설명 |
|--------|------|------|
| POST | `/api/music/video-project` | 프로젝트 생성 (`track_id`, `format`, `target_countries`) |
| GET | `/api/music/video-projects` | 프로젝트 목록 |
| GET | `/api/music/video-project/{id}` | 프로젝트 상세 + 렌더링 상태 |
| POST | `/api/music/video-project/{id}/render` | 렌더링 시작 (BackgroundTask) |
| GET | `/api/music/video-project/{id}/export` | 내보내기 패키지 (MP4 URL + metadata JSON) |
| DELETE | `/api/music/video-project/{id}` | 프로젝트 삭제 |
### 5-3. music-lab — 수익화 추적
| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | `/api/music/revenue` | 수익 기록 (`yt_video_id`, `year_month` 필터) |
| POST | `/api/music/revenue` | 수익 기록 추가 |
| PUT | `/api/music/revenue/{id}` | 수익 기록 수정 |
| DELETE | `/api/music/revenue/{id}` | 수익 기록 삭제 |
| GET | `/api/music/revenue/dashboard` | 총수익·RPM·장르별·국가별 집계 |
### 5-4. agent-office — YouTube 리서치
| 메서드 | 경로 | 설명 |
|--------|------|------|
| POST | `/api/agent-office/youtube/research` | 수동 리서치 트리거 (`countries` 지정 가능) |
| GET | `/api/agent-office/youtube/research/status` | 마지막 실행 상태 + 수집 건수 |
---
## 6. 영상 제작 파이프라인
### 6-1. 오디오 비주얼라이저 (`format: 'visualizer'`)
```
MP3 (file_path) + 배경 이미지 (cover_images[0] 우선, 없으면 장르별 그라디언트 기본 배경)
→ FFmpeg showwaves 필터 (1920×1080, 음파 오버레이)
→ H.264 + AAC MP4
→ 썸네일 추출 (5초 지점 프레임)
→ Claude API 메타데이터 생성
```
핵심 FFmpeg 명령:
```bash
ffmpeg -loop 1 -i cover.jpg -i audio.mp3 \
-filter_complex \
"[1:a]showwaves=s=1920x200:mode=cline:colors=0xFF4444[wave]; \
[0:v][wave]overlay=0:880[out]" \
-map "[out]" -map 1:a \
-c:v libx264 -c:a aac -shortest output.mp4
```
적합 장르: Lo-fi, Ambient, Study Music, Phonk
### 6-2. AI 이미지 슬라이드쇼 (`format: 'slideshow'`)
```
① 키워드 추출 (genre + moods + prompt → 검색어)
② 이미지 수집
- Pexels API: 키워드 검색 4-6장 (무료 200req/시간)
- Suno 커버이미지: cover_images 필드에서 1-2장
③ 이미지당 표시 시간 = track.duration_sec / 이미지 수
④ FFmpeg xfade 전환 (fade, 1초)
⑤ H.264 + AAC MP4 출력
⑥ 썸네일 추출 + Claude API 메타데이터 생성
```
### 6-3. 공통 후처리
**Claude API 메타데이터 생성:**
- 입력: `genre`, `moods`, `lyrics`, `target_countries`
- 출력:
- `yt_title`: 최대 100자, SEO 최적화, 국가 감안
- `yt_description`: 해시태그 + 타임스탬프 + 링크 플레이스홀더
- `yt_tags`: 10-15개, 현지어 포함 (예: 브라질 타겟 → `"música relaxante"`, `"estudo música"`)
**내보내기 패키지:**
```
/data/videos/{project_id}/
output.mp4 ← 최종 영상
thumbnail.jpg ← 썸네일
metadata.json ← {title, description, tags, target_countries, category}
```
---
## 7. YouTubeResearchAgent (agent-office)
**파일:** `agents/youtube.py`
**데이터 수집 (매일 09:00):**
1. YouTube Data API v3 — 국가별 (`BR`, `ID`, `MX`, `US`, `KR`) 트렌딩 음악 카테고리 50개
2. pytrends — 장르별 Google Trends 점수 (최근 7일)
3. Billboard Hot 100 스크래핑 — 글로벌 차트 상위 20
**분석 → trend_reports 생성:**
- 소스별 score 정규화 후 장르 클러스터링
- `recommended_styles` 생성: `{genre, suno_prompt, target_countries, reason}`
- Claude API로 `insights` 텍스트 생성
**push → music-lab:**
```
POST http://music-lab:8000/api/music/market/ingest
body: {trends: [...], report: {...}}
```
**스케줄러:**
- 매일 09:00 — `youtube_research_job`
- 매주 월요일 08:00 — 주간 인사이트 텔레그램 발송
---
## 8. 인프라 변경사항
| 대상 | 변경 내용 |
|------|-----------|
| `music-lab/Dockerfile` | `RUN apt-get install -y ffmpeg` 추가 |
| `nginx/default.conf` | `/media/videos/``/data/videos/` 경로 추가 |
| `music-lab/requirements.txt` | `anthropic`, `Pillow` 추가 |
| `agent-office/requirements.txt` | `google-api-python-client`, `pytrends` 추가 |
| `.env` | `PEXELS_API_KEY`, `YOUTUBE_DATA_API_KEY` 추가 |
| `docker-compose.yml` | music-lab volume에 `/data/videos` 마운트 추가 |
**CLAUDE.md 업데이트 필요:**
- Nginx: `/media/videos/` 경로 추가
- music-lab API 목록에 신규 16개 추가 (시장조사 5 + 영상제작 6 + 수익화 5), agent-office 2개 추가
- agent-office 스케줄러에 youtube_research_job 추가
---
## 9. 수익화 전략
### 9-1. YouTube 광고 수익 (CPM 기준)
| 국가 | CPM 범위 |
|------|---------|
| 브라질 | $1.5 ~ $4 |
| 인도네시아 | $1.0 ~ $2.5 |
| 미국 | $3.0 ~ $8.0 |
| 한국 | $2.0 ~ $5.0 |
Lo-fi / Ambient은 긴 시청 시간 유도 → RPM 유리. 인스트루멘탈은 언어 장벽 없음.
### 9-2. 국가별 장르 전략
| 국가 | 주력 장르 |
|------|-----------|
| 브라질 | Funk, Phonk, Lo-fi |
| 인도네시아 | Pop, Study Music, Lo-fi |
| 멕시코 | Latin Pop, Reggaeton |
| 글로벌 | Ambient, Cinematic |
### 9-3. 업로드 목표
- **주 3-5개** 영상 업로드 (시스템 안정화 후 일 1개 목표)
- 영상 **50개** 누적 → 수익 활성화 (구독자 1,000 + 시청 4,000시간)
- 영상 **200개** 누적 → 월 $100+ 수동 수익 목표
---
## 10. 구현 로드맵
### Phase 1 — 영상 제작 파이프라인 (약 2-3주)
**music-lab 백엔드:**
- `video_producer.py` — FFmpeg 래퍼 (비주얼라이저 + 슬라이드쇼)
- `market.py` — 트렌드 데이터 수신·저장·조회·추천
- `monetization.py` — 수익화 추적 CRUD
- DB 마이그레이션: `video_projects`, `revenue_records`
- 신규 API 12개 (영상 제작 6 + 수익화 5 + market ingest 1)
- Dockerfile `ffmpeg` 추가
- Nginx `/media/videos/` 경로 추가
### Phase 2 — 시장 조사 자동화 (약 1-2주)
**agent-office:**
- `agents/youtube.py` (YouTubeResearchAgent)
- YouTube Data API v3 연동
- pytrends 연동
- Billboard 스크래핑
- 스케줄러 등록 (매일 09:00, 매주 월요일 08:00)
- `youtube_research_jobs` DB 테이블
- 신규 API 2개 + agent-office API 2개
**music-lab:**
- DB 마이그레이션: `market_trends`, `trend_reports`
- 신규 API 4개 (트렌드 조회 3 + 추천 1)
### Phase 3 — YouTube API 자동 업로드 (채널 안정화 후)
- YouTube Data API OAuth 2.0 인증
- 동영상 업로드·썸네일 설정 자동화
- YouTube Studio 수익 데이터 자동 수집 (`source: 'youtube_api'`)
- 텔레그램 업로드 완료 알림
---
## 11. 신규 파일 목록
### music-lab/app/
- `video_producer.py` — FFmpeg 비주얼라이저·슬라이드쇼 렌더링
- `market.py` — 시장 트렌드 수신·저장·조회·추천
- `monetization.py` — 수익 기록 CRUD·대시보드
### agent-office/app/agents/
- `youtube.py` — YouTubeResearchAgent
### agent-office/app/
- `youtube_researcher.py` — YouTube/Trends/Billboard 데이터 수집 로직