컷별 댓글 추천 작업을 태스크 단위로 되돌릴 수 있게 버전관리를 시작한다. .gitignore 로 영상·캐시(.downloads 2.7G, .comments 72M, .media 28M)와 비밀키(.gemini_key)를 제외했다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
85 lines
4.7 KiB
Markdown
85 lines
4.7 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## 이 프로젝트가 하는 일
|
||
|
||
유튜브 영상(URL/파일/LLM 편집안 JSON) → 다운로드·컷·자막·배경 템플릿을 자동 조립해
|
||
**편집 가능한 CapCut 드래프트**(`draft_content.json`)를 로컬 CapCut 프로젝트 폴더에 생성하는
|
||
FastAPI + 정적 HTML 로컬 웹앱. 포트 **8001** (형제 앱 v1 `../capcut`은 8000, 완전히 별개 코드베이스).
|
||
|
||
## 먼저 읽어야 할 문서
|
||
|
||
이 저장소에는 이미 깊은 명세 문서가 있다. 코드를 건드리기 전에 반드시 참고:
|
||
|
||
- **`ARCHITECTURE.md`** — 전체 구현 명세(좌표계, 파이프라인 단계별 동작, 드래프트 빌더 내부,
|
||
yt-dlp 함정, 고정값 치트시트, "하지 말 것" 목록). **가장 정확하고 깊은 문서.**
|
||
- **`README.md`** — 사용자용 요약, 붙여넣기 JSON 스키마, 다른 PC 설치법, 문제 해결표.
|
||
|
||
CLAUDE.md는 위 두 문서와 중복하지 않는다. 세부는 그쪽을 볼 것.
|
||
|
||
## 실행 / 개발 명령
|
||
|
||
```bash
|
||
# 서버 실행 (Windows 런처 — 브라우저 자동 오픈, 포트 8001)
|
||
캡컷_에이전트_구간합치기.bat
|
||
|
||
# 런처 없이 직접 실행
|
||
python -m uvicorn server.app:app --port 8001
|
||
|
||
# 의존성 설치
|
||
python -m pip install -r requirements.txt
|
||
|
||
# 파이썬 구문 검증 (수정 후 습관)
|
||
python -c "import ast; ast.parse(open('capcut_agent/pipeline.py', encoding='utf-8').read())"
|
||
python -c "from server import app" # 임포트 체인 확인
|
||
```
|
||
|
||
시스템 의존성(pip 아님, PATH 필요): **ffmpeg/ffprobe**, **Node.js 또는 deno**(yt-dlp JS 런타임),
|
||
**CapCut**(드래프트 열기 + 코트라 볼드체 폰트 캐시).
|
||
|
||
### ⚠️ 가장 중요한 규칙: 코드 수정 후 .bat 재시작 필수
|
||
|
||
파이썬 코드가 uvicorn 서버에 물려 있어 **hot-reload 안 됨**. 코드를 고쳤으면 반드시
|
||
검은 창을 닫고 `.bat`을 다시 실행해야 반영된다. 이것을 잊는 게 "안 돼요"의 가장 흔한 원인.
|
||
|
||
## 아키텍처 큰 그림
|
||
|
||
요청은 세 탭(파일 / 유튜브 구간 / 붙여넣기)에서 들어와 두 파이프라인 중 하나로 갈린다:
|
||
|
||
- **`server/app.py`** — FastAPI. 엔드포인트 4개(`/upload` `/youtube` `/paste` `/open-capcut`) +
|
||
SSE 스트림(`/stream/{job_id}`). job은 메모리 dict `JOBS[hash]`에 저장(서버 재시작 시 소실).
|
||
폼 필드 → 파이프라인 인자 변환 담당.
|
||
- **`server/static/index.html`** — UI 전체(단일 파일, 탭 3개 + 옵션 + SSE 렌더).
|
||
- **`capcut_agent/pipeline.py`** — ★ 진입점 두 개:
|
||
- `process_bg_template()` — 파일/유튜브 탭. `download → silence → asr → [scene] → draft`
|
||
- `process_paste()` — 붙여넣기 탭. `download(정밀 컷) → [remove_silence] → [asr_bottom] → [scene] → draft`
|
||
- **`capcut_agent/draft.py`** — ★ `build_bg_template_draft`. pycapcut으로 드래프트 생성 후
|
||
`draft_content.json`을 직접 후처리(폰트·그림자 주입 등).
|
||
- 나머지 `capcut_agent/*.py` — youtube(다운로드/병합), paste(관대한 JSON 파서), silence,
|
||
transcribe(faster-whisper), correct(Gemini 교정), scene, media, probe. 역할은 ARCHITECTURE.md §1.
|
||
|
||
### 절대 되돌리면 안 되는 핵심 설계 결정
|
||
|
||
- **자막 타이밍 = Whisper 단어 타임스탬프, 글자만 = Gemini 제자리 교정(시간 불변).**
|
||
과거에 Gemini 오디오 전사 타임스탬프를 직접 쓰거나 글자수 기반 정렬을 시도했다가
|
||
누적 드리프트로 자막이 밀렸다. Gemini는 글자만 1:1 교정, 줄 수·순서·시간은 절대 건드리지 않는다.
|
||
- **붙여넣기 탭은 배치 시간을 입력받지 않는다** — 컷 순서대로 누적 자동 계산(LLM이 계산하면 오타).
|
||
- **같은 텍스트 트랙에 동시간 세그먼트 2개 금지** — CapCut `SegmentOverlap` 에러.
|
||
- 정답 파일은 **`draft_content.json`** (draft_info.json 아님).
|
||
|
||
### 좌표계 (draft.py 작업 시)
|
||
|
||
`CapCut Y = transform_y × 1920` (canvas 1080×1920, 위가 +/아래가 −). 헬퍼 `_ty(y_px) = (960 - y_px)/960`.
|
||
확대(%) = scale 비율. 사용자가 "위치 −559로" 라고 하면 transform_y로 환산해 반영. 고정값은 ARCHITECTURE.md §9 치트시트.
|
||
|
||
## 검증 방식
|
||
|
||
이 프로젝트에 자동 테스트 스위트는 없다. 검증은:
|
||
1. 구문 파싱 + 임포트 체인 확인(위 명령).
|
||
2. 가능하면 실제 드래프트를 빌드해 `draft_content.json` 값을 열어 확인(테스트 드래프트는 확인 후 삭제).
|
||
3. 최종적으로 **사용자가 CapCut에서 열어 확인**.
|
||
|
||
테스트용 영상이 필요하면 `.downloads/`의 기존 mp4 재사용(네트워크 불필요).
|
||
Windows 콘솔은 cp949라 한글/특수문자 print가 깨져 보일 수 있음(로직과 무관).
|