유튜브 숏폼 영상 업로드까지 자동화 파이프라인 구축
소개
주제만 던지면 유튜브 숏폼 영상이 자동으로 업로드되는 파이프라인을 구축해보았습니다. Claude Code로 8개 에이전트 체계(스토리 작가 → 캐릭터 디자이너 → 씬 연출가 → 이미지 생성 → 오디오 생성 → 영상 편집 → 업로드)를 구축하고, 주제 하나만 입력하면 대본 생성부터 YouTube 업로드까지 자동으로 완료되는 것을 확인했습니다.
진행 방법
🛠️ 사용한 주요 도구
Claude Code (Opus 4.6) — 전체 파이프라인 설계 및 코드 작성
Gemini API (2.5 Flash) — 대본 생성, 캐릭터 설정, 씬 연출
Gemini 이미지 생성 (gemini-3-pro-image-preview) — 장면별 2D 일러스트
edge-tts (HyunsuMultilingual) — 한국어 나레이션 (무료!)
Remotion — React 기반 프로그래매틱 영상 렌더링
YouTube Data API v3 — 자동 업로드
🏗️ 8개 에이전트 구조
핵심은 역할 분리입니다. 하나의 거대한 스크립트 대신, 각자 명확한 입출력을 가진 8개 에이전트로 나눴습니다.
왜 8개로 나눴을까?
디버깅이 쉽다 — 이미지가 맘에 안 들면 image-creator만 다시 돌리면 됨
중간 재개 가능 —
--from audio-creator처럼 특정 단계부터 이어서 실행부분 교체 가능 — TTS를 edge-tts에서 다른 서비스로 바꾸려면 audio-creator만 수정
병렬 작업 가능 — 이미지 생성과 오디오 생성을 동시에 돌릴 수 있음
에이전트 | 역할 | 기술 | 출력물 |
|---|---|---|---|
producer | 총괄 감독 | Node.js | 전체 흐름 조율 |
story-writer | 스토리 작가 | Gemini API |
|
character-designer | 캐릭터 디자이너 | Gemini API |
|
scene-director | 씬 연출가 | Gemini API |
|
image-creator | 이미지 생성 |
| 장면별 PNG 일러스트 |
audio-creator | 오디오 생성 | edge-tts | 대사별 MP3 + 타이밍 |
video-editor | 영상 편집 | Remotion | MP4 영상 |
youtube-uploader | 업로드 | YouTube API | YouTube URL |
🔧 구축 과정
Step 1: 아키텍처 설계
Claude Code에게 "8개 에이전트 구조로 숏폼 자동화 파이프라인을 만들자"고 요청했습니다. 처음에는 FFmpeg로 영상을 조립하는 구조였는데, 이미 Remotion 프로젝트가 세팅되어 있었기 때문에 video-editor는 Remotion으로 변경했습니다.
또한 TTS도 처음에는 Typecast MCP를 고려했지만, 빠른 프로토타이핑을 위해 무료인 edge-tts로 변경했습니다. 이런 의사결정을 Claude Code와 대화하면서 실시간으로 조정할 수 있었던 게 좋았습니다.
Step 2: 에이전트 파일 구조
agents/
├── producer.mjs # 오케스트레이터
├── story-writer.mjs # Gemini → 대본 JSON
├── character-designer.mjs # Gemini → 캐릭터 프로필
├── scene-director.mjs # Gemini → 씬 연출 + 이미지 프롬프트
├── image-creator.mjs # 프롬프트 준비 → /gemini-image 연동
├── audio-creator.py # edge-tts → MP3 + 프레임 타이밍
├── video-editor.mjs # Remotion 렌더링
└── youtube-uploader.mjs # YouTube API 업로드
각 에이전트는 독립 실행도 가능합니다:
# 개별 실행
node agents/story-writer.mjs workspace/ep_001
# 전체 파이프라인
node agents/producer.mjs --topic "AI시대 왜 책을 읽어야 할까?" --ep 1
Step 3: 데이터 흐름 설계
모든 에이전트는 workspace 디렉토리를 통해 데이터를 주고받습니다:
workspace/ep_001/
├── config.json ← 입력 (주제, 대상, EP 번호)
├── 01_script.json ← story-writer 출력
├── 02_characters.json ← character-designer 출력
├── 03_scenes.json ← scene-director 출력
├── image_prompts.json ← image-creator 출력
├── audio_timing.json ← audio-creator 출력
└── props.json ← video-editor (Remotion용)
에셋(이미지/오디오)은 Remotion이 접근할 수 있도록 public/ 아래에 저장:
public/episodes/ep_001/
├── images/scene_00.png ~ scene_10.png
└── audio/line_00.mp3 ~ line_10.mp3
Step 4: story-writer — 대본 자동 생성
Gemini API에 시스템 프롬프트로 캐릭터 성격, 숏폼 구조(HOOK→전개→결론→마무리), JSON 출력 형식을 상세히 지정했습니다.
{
"title": "AI 시대, 왜 책을 읽어야 할까?",
"hookTitle": "AI시대 왜 책을 읽어야 할까?",
"lines": [
{ "speaker": "글쌤", "text": "책쌤, 요즘 AI가 소설도 써주고...", "emotion": "curious" },
{ "speaker": "책쌤", "text": "글쌤, 그렇다고 네 머릿속 생각까지...", "emotion": "explaining" }
],
"ending": { "mainText": "...", "subText": "..." },
"youtube": { "title": "...", "description": "...", "tags": [...] }
}
핵심: 대본에 emotion 필드를 넣어서, 이후 character-designer와 scene-director가 감정에 맞는 표정/구도를 설계할 수 있게 했습니다.
Step 5: image-creator + /gemini-image — 장면별 일러스트
scene-director가 만든 영어 프롬프트를 기반으로 Gemini 이미지 생성(gemini-3-pro-image-preview)으로 11개 장면을 생성했습니다.
image-creator 에이전트 자체는 프롬프트 준비만 하고, 실제 생성은 /gemini-image 스킬로 수행하는 구조입니다. 파이프라인이 image-creator 단계에서 자동으로 일시정지하고, 이미지 생성 후 재개하는 방식이죠.
# image-creator 완료 후 자동 멈춤 → /gemini-image로 이미지 생성
# 이미지 생성 완료 후 재개:
node agents/producer.mjs workspace/ep_001 --from audio-creator
Step 6: audio-creator — edge-tts 나레이션
edge-tts의 ko-KR-HyunsuMultilingualNeural 음성을 사용했습니다. 무료라서 품질은 아쉽지만, 테스트용으로 만들기에는 부담이 없어서 선택했습니다. 채널에 업로드 할 영상이면 바꾸어서 진행할 수 있습니다.
화자별로 약간의 톤 차이를 줬습니다: (전부 자동화 과정으로, 제가 개입하지 않고 AI가 판단해서 진행했습니다)
화자 | rate | pitch | 느낌 |
|---|---|---|---|
책쌤 | +5% | -2Hz | 차분한 선생님 |
글쌤 | +10% | +5Hz | 밝고 활발한 학생 |
함께 | +0% | +3Hz | 힘 있는 마무리 |
핵심 기능: 오디오 생성 후 mutagen으로 각 MP3의 정확한 길이를 측정하고, 프레임 단위 타이밍 데이터를 자동 계산합니다. 이 데이터가 Remotion에서 오디오-자막 싱크의 기반이 됩니다.
Step 7: video-editor — Remotion 렌더링
SceneShorts라는 React 컴포넌트를 만들어서:
장면 이미지를 Ken Burns 효과(미세 줌+패닝)로 표시
대사별 오디오 재생
하단 자막 (화자 뱃지 + 대사 텍스트)
배경 그라디언트 + 파티클 효과
엔딩 카드
모든 데이터를 inputProps로 받기 때문에, 같은 컴포넌트로 무한히 다른 에피소드를 렌더링할 수 있습니다.
Step 8: youtube-uploader — 원클릭 업로드
대본의 youtube 필드에서 제목/설명/태그를 자동 추출하고, YouTube Data API로 업로드합니다. 기본은 비공개(private)로 올라가서 확인 후 공개 전환하는 안전한 워크플로우입니다.
🎬 실제 실행 결과
터미널에서 명령어 하나로 전체 파이프라인을 실행했습니다:
npm run produce -- --topic "AI시대 왜 책을 읽어야 할까?" --ep 1
실행 로그 (요약)
╔══════════════════════════════════════════════════╗
║ 🎬 질문연구소 숏폼 자동화 파이프라인 ║
╚══════════════════════════════════════════════════╝
에피소드: ep_001
주제: AI시대 왜 책을 읽어야 할까?
대상: 초등 3~6학년
STEP 1/6: 스토리 작가 ............ ✓ 대본 11줄 생성
STEP 2/6: 캐릭터 디자이너 ........ ✓ 책쌤/글쌤 프로필 완료
STEP 3/6: 씬 연출가 .............. ✓ 11개 씬 연출 완료
STEP 4/6: 이미지 생성 ............ ⏸️ /gemini-image로 11개 생성
STEP 5/6: 오디오 생성 ............ ✓ edge-tts 11개 나레이션
STEP 6/6: 영상 편집 .............. ✓ Remotion 렌더링 (66.7MB)
업로드: YouTube 비공개 ........... ✓ 완료
결과물
영상 길이: 83.5초 (대사 11줄 기준)
파일 크기: 66.7MB
총 소요 시간: 파이프라인 자체 ~2분 + 이미지 생성 ~5분
YouTube URL: 비공개로 업로드 완료 / 사례 발표를 위해 일부 공개로 변경했습니다.
✅ Before vs After
항목 | Before (수작업) | After (8에이전트 파이프라인) |
|---|---|---|
대본 작성 | 직접 구상 ~30분 | Gemini 자동 생성 ~10초 |
캐릭터 설정 | 매번 수동 | 자동 프로필 + 표정 매핑 |
이미지 | 하나씩 프롬프트 | 11개 일괄 생성 ~5분 |
나레이션 | 녹음 또는 수동 TTS | edge-tts 자동 ~15초 |
영상 편집 | 편집 프로그램 ~1시간 | Remotion 자동 렌더 ~2분 |
업로드 | YouTube 수동 | API 자동 (제목/태그 포함) |
총 소요 | 반나절 | ~10분 |
💡 핵심 학습 포인트
효과적이었던 것
역할 분리 (8에이전트) — 한 덩어리로 만들면 디버깅이 지옥. 에이전트별로 나누니 문제가 생겨도 해당 단계만 다시 돌리면 됩니다.
중간 재개 (
--from플래그) — 이미지가 맘에 안 들어서 다시 생성했을 때,--from audio-creator로 오디오부터 이어서 실행. 처음부터 다시 돌릴 필요 없습니다.edge-tts = 무료인데 충분 — 유료 TTS 고민할 시간에 edge-tts로 프로토타입 먼저 만들고, 품질을 올리는 건 나중에. "빨리 만들고 → 보고 → 바꾸기" 전략이 유효했습니다.
workspace 패턴 — 모든 중간 산출물이 JSON으로 남아서 추적 가능. 뭐가 잘못됐는지 파일 열어보면 바로 알 수 있습니다.
개선이 필요한 것
영상 길이 — 현재 83초로 Shorts 60초 제한 초과. 대사 수를 8~10개로 조정 필요
캐릭터 일관성 — Gemini 이미지 생성 시 매번 캐릭터가 조금씩 다름. 레퍼런스 이미지 체이닝 필요
완전 자동화가 된다는 것은 확인했지만, 구체적으로 원하는 결과물을 만들기 위해 대본 작성에 미리 개입할 수 있는 단계를 설정하고 싶습니다.
🚀 추후 계획
캐릭터 레퍼런스 체이닝 — 첫 이미지를 레퍼런스로 넣어 일관성 유지
BGM 에이전트 추가 — 배경음악 자동 선택/삽입
시리즈 자동 생성 — EP.1~5까지 한 번에 생성하는 배치 모드
TTS 업그레이드 — 품질 확인 후 Supertone 등으로 교체 검토
cron 스케줄링 — 주 3회 자동 발행
📋 재사용 가능한 명령어
전체 파이프라인 실행
npm run produce -- --topic "주제" --ep 1
중간부터 재개
node agents/producer.mjs workspace/ep_001 --from audio-creator
업로드만
node agents/producer.mjs workspace/ep_001 --from youtube-uploader --upload
개별 에이전트 실행
node agents/story-writer.mjs workspace/ep_001
python3 agents/audio-creator.py workspace/ep_001
🔗 기술 스택 정리
레이어 | 기술 | 용도 |
|---|---|---|
오케스트레이션 | Node.js (producer.mjs) | 에이전트 순서 관리 |
대본/설정 | Gemini 2.5 Flash | 스크립트, 캐릭터, 씬 연출 |
이미지 | Gemini 3 Pro Image | 장면별 2D 일러스트 |
음성 | edge-tts (HyunsuMultilingual) | 한국어 나레이션 (무료) |
영상 | Remotion (React) | 프로그래매틱 영상 렌더링 |
업로드 | YouTube Data API v3 | 자동 업로드 |
개발 | Claude Code (Opus 4.6) | 전체 코드 작성 |
한 줄 회고: 에이전트를 잘게 나누면 복잡한 파이프라인도 관리할 수 있게 됩니다. 완벽한 영상을 한 번에 만들려 하지 말고, 돌아가는 파이프라인을 먼저 만들고 부품을 하나씩 교체하는 게 핵심이었습니다.
댓글 0개
로그인하고 댓글을 작성하세요