받아쓰기 후 댓글 매칭으로 바뀐 서버 흐름이 ARCHITECTURE.md에 전혀 안 남아 있어 다음 세션이 옛 단일 엔드포인트(POST /youtube 등)를 전제로 코드를 읽을 위험이 있었다. 탭별 흐름 표·cuts_from_state() 공통 조립점·두 좌표계 금기를 명시하고, SETUP.md 문제 해결표에 새 증상 3개, README.md 탭 설명에 새 흐름을 반영했다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
324 lines
16 KiB
Markdown
324 lines
16 KiB
Markdown
# SETUP.md — 다른 PC 설치 · 환경 · 버전 명세
|
||
|
||
> 이 프로젝트(캡컷 에이전트 · 구간합치기 v2)를 **다른 Windows PC에서 그대로 돌리기 위한** 전체 스펙·버전 문서.
|
||
> 구현 세부는 [ARCHITECTURE.md](ARCHITECTURE.md), 사용법은 [README.md](README.md) 참고.
|
||
> 아래 버전들은 **현재 작동 중인 PC에서 실측한 값**(2026-07 기준)이라, 이 조합이면 확실히 돕니다.
|
||
|
||
---
|
||
|
||
## 0. 30초 요약 체크리스트
|
||
|
||
다른 PC에서 이 6개만 맞추면 됩니다:
|
||
|
||
- [ ] **Windows 10/11** (64-bit)
|
||
- [ ] **Python 3.13** 설치 + PATH 등록
|
||
- [ ] **ffmpeg / ffprobe** PATH 등록 (pip 아님)
|
||
- [ ] **Node.js**(또는 deno) PATH 등록 (yt-dlp JS 런타임)
|
||
- [ ] **CapCut** 설치 + (선택) 코트라 볼드체 1회 사용해 폰트 캐시 생성
|
||
- [ ] `python -m pip install -r requirements.txt` 실행
|
||
|
||
그다음 `캡컷_에이전트_구간합치기.bat` 더블클릭 → http://127.0.0.1:8001
|
||
|
||
---
|
||
|
||
## 1. 시스템 요구사항
|
||
|
||
| 항목 | 실측 버전 | 비고 |
|
||
|---|---|---|
|
||
| OS | Windows 11 (10.0.26200) | Windows 10 64-bit 이상 권장. 콘솔 cp949라 한글 print 깨져 보여도 로직 무관 |
|
||
| Python | **3.13.0** | 3.10~3.13 범위면 대체로 OK. python.org 설치 시 "Add to PATH" 체크 |
|
||
| 아키텍처 | x64 | faster-whisper(ctranslate2)·onnxruntime가 x64 전제 |
|
||
| 디스크 여유 | 약 3~4GB | Whisper medium 모델(~1.5GB) + 패키지 + 다운로드 캐시 |
|
||
| 인터넷 | 최초 1회 필수 | 패키지·Whisper 모델·유튜브 다운로드에 필요 |
|
||
|
||
### 권장 사양 (쾌적하게 돌리려면)
|
||
|
||
병목은 **자막 받아쓰기(ASR)** 입니다. faster-whisper `medium` 모델을 **CPU(int8)** 로 돌리므로
|
||
**CPU 성능·코어 수가 속도를 좌우**합니다. (아래 GPU 항목 참고 — 현재 GPU는 안 씀.)
|
||
|
||
| 항목 | 최소 | 권장 | 비고 |
|
||
|---|---|---|---|
|
||
| **CPU** | 4코어 | **8코어 이상** (최신 Ryzen 5/7, Intel i5/i7) | ASR·ffmpeg 재인코딩이 CPU 바운드. 코어 많을수록 자막·병합 빠름 |
|
||
| **RAM** | 8GB | **16GB** | Whisper 모델 로드(~2~3GB) + ffmpeg 재인코딩 + 브라우저 동시 |
|
||
| **저장소** | HDD 가능 | **SSD(NVMe 권장)** | 영상 재인코딩·프레임 추출 I/O가 많음. SSD면 체감 큰 차이 |
|
||
| **디스크 여유** | 4GB | **10GB+** | 여러 영상 다운로드·ASR 캐시가 쌓임(`.downloads` `.cache`) |
|
||
| **GPU** | 불필요 | 불필요 | ⚠ **현재 코드는 Whisper를 `device="cpu"` 로 고정** → GPU 있어도 이득 없음. CPU에 투자할 것 |
|
||
| **네트워크** | — | 안정적 유선/와이파이 | 유튜브 다운로드용. 구간 컷 속도는 회선보다 **ffmpeg 8.0.1**(§2-1)이 핵심 |
|
||
|
||
> **속도 감각**: 붙여넣기 탭에서 ASR을 끄면 CPU 부담이 확 줄어 어떤 PC에서도 빠릅니다.
|
||
> 파일/유튜브 탭(자동 자막)은 CPU가 약하면 영상 길이에 비례해 ASR이 오래 걸립니다.
|
||
|
||
---
|
||
|
||
## 2. 시스템 의존성 (pip 아님 — 별도 설치 + PATH 필수)
|
||
|
||
이 3개는 파이썬 패키지가 아니라 **OS에 따로 깔고 PATH에 잡혀야** 합니다. 없으면 조용히 실패하거나 ffmpeg 크래시가 납니다.
|
||
|
||
### 2-1. ffmpeg / ffprobe ★필수 · ⭐버전 8.0.1 반드시 고정
|
||
|
||
| 항목 | 실측 |
|
||
|---|---|
|
||
| 버전 | **ffmpeg 8.0.1** (gyan.dev `essentials_build`) — ⭐**이 버전으로 고정** |
|
||
| 확인 | `ffmpeg -version`, `ffprobe -version` 둘 다 나와야 함 |
|
||
|
||
> ⚠️ **가장 중요 — 최신(8.1.x) 쓰지 말 것.** ffmpeg **8.1.x**는 `--download-sections`(유튜브 구간 컷)
|
||
> 경로에서 **HTTP seek 회귀**가 있어 10초 클립 다운로드가 **90초+** 로 극단적으로 느려집니다.
|
||
> **8.0.1로 내리면 12~15초로 정상화.** (전체 다운로드는 이 경로를 안 타서 멀쩡하므로,
|
||
> "일반 다운로드는 빠른데 구간 컷만 느리다"면 100% 이 문제입니다.)
|
||
|
||
- 다운로드(8.0.1 정확히): **https://github.com/GyanD/codexffmpeg/releases/tag/8.0.1** → `ffmpeg-8.0.1-essentials_build.7z`
|
||
- 압축 해제 후 `bin` 폴더(= `ffmpeg.exe`, `ffprobe.exe`)를 **시스템 PATH에 추가**. 이미 8.1.x가 잡혀 있으면 **그 경로를 지우고** 8.0.1로 교체(또는 exe 2개 덮어쓰기).
|
||
- **터미널 새로 열고** `ffmpeg -version`이 `8.0.1-essentials_build`인지 확인.
|
||
- 용도: 구간 병합·재인코딩, 무음 감지, 장면분할, 오디오 추출, 프레임 추출.
|
||
|
||
**속도 검증**(셋업 후 10초 구간 컷이 몇 초 걸리는지):
|
||
```powershell
|
||
yt-dlp --js-runtimes node --download-sections "*0:30-0:40" --force-keyframes-at-cuts -f "bv*[vcodec^=avc1]+ba[acodec^=mp4a]/b" --merge-output-format mp4 -o "%TEMP%/sec.%(ext)s" "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||
```
|
||
→ **12~15초 = ✅ 정상** / 90초+ = ffmpeg가 아직 8.1.x (터미널 새로 열었는지 재확인).
|
||
|
||
### 2-2. JS 런타임 (Node.js 또는 deno) ★필수
|
||
|
||
| 항목 | 실측 |
|
||
|---|---|
|
||
| Node.js | **v22.17.0** |
|
||
| deno | 1.3.14 (있으면 우선 사용) |
|
||
|
||
- 최신 유튜브는 JS 챌린지가 있어 **런타임이 없으면 포맷 누락 → ffmpeg 크래시**가 납니다.
|
||
- `youtube.py`가 `deno → node → bun` 순으로 자동 감지(`--js-runtimes`)하므로 **셋 중 하나만** 있으면 됨.
|
||
- 가장 쉬운 선택: **Node.js LTS** 설치 (https://nodejs.org) → `node --version` 확인.
|
||
|
||
### 2-3. CapCut ★필수
|
||
|
||
| 용도 | 필수 여부 |
|
||
|---|---|
|
||
| 드래프트 저장 위치 제공(`%LOCALAPPDATA%/CapCut/...`) | 필수 |
|
||
| 완료 후 자동 열기(`/open-capcut`) | 선택 |
|
||
| 코트라 볼드체 폰트 캐시 | 선택(없으면 기본 폰트로 안전 동작) |
|
||
|
||
- CapCut 데스크톱(Windows) 설치. 드래프트는 아래 경로에 생성됨:
|
||
`%LOCALAPPDATA%\CapCut\User Data\Projects\com.lveditor.draft\<드래프트명>\`
|
||
- 폰트 캐시는 §6 참고.
|
||
|
||
---
|
||
|
||
## 3. Python 패키지 (pip)
|
||
|
||
### 3-1. 느슨한 설치 (requirements.txt — 최신으로 받음)
|
||
|
||
```bash
|
||
python -m pip install -r requirements.txt
|
||
```
|
||
|
||
`requirements.txt` 내용:
|
||
```
|
||
fastapi
|
||
uvicorn
|
||
python-multipart
|
||
pyCapCut
|
||
Pillow
|
||
pymediainfo
|
||
yt-dlp
|
||
faster-whisper
|
||
```
|
||
|
||
### 3-2. 버전 고정 (재현성 100% — 이 조합이 실제로 도는 버전)
|
||
|
||
다른 PC에서 **최신 버전 충돌이 걱정되면** 아래를 `requirements.lock.txt`로 저장해
|
||
`python -m pip install -r requirements.lock.txt` 로 설치하세요.
|
||
|
||
```
|
||
# ── 직접 의존성 ──────────────────────────────
|
||
fastapi==0.115.14
|
||
uvicorn==0.35.0
|
||
python-multipart==0.0.20
|
||
pyCapCut==0.0.3 # import 이름은 pycapcut
|
||
Pillow==10.4.0
|
||
pymediainfo==7.0.1
|
||
yt-dlp==2026.7.4
|
||
faster-whisper==1.2.1
|
||
|
||
# ── faster-whisper / fastapi 전이 의존성(자동 설치되지만 버전 고정용) ──
|
||
av==16.0.1
|
||
ctranslate2==4.6.2
|
||
onnxruntime==1.23.2
|
||
tokenizers==0.21.2
|
||
huggingface-hub==0.33.4
|
||
numpy==2.2.0
|
||
starlette==0.46.2
|
||
pydantic==2.11.7
|
||
```
|
||
|
||
> **참고**
|
||
> - `yt-dlp`는 pip로 깔면 `yt-dlp` **콘솔 스크립트가 PATH에 생겨** 코드가 subprocess로 호출합니다. (유튜브는 자주 막히니 **주기적으로 `python -m pip install -U yt-dlp` 업데이트 권장** — 버전 고정하지 말 것.)
|
||
> - SSE(진행상황 스트림)는 FastAPI 내장 `StreamingResponse` 사용 → `sse-starlette` **불필요**.
|
||
> - Gemini 교정은 표준 라이브러리 `urllib`로 REST 직접 호출 → `google-generativeai` **패키지 불필요**.
|
||
> - `pymediainfo`는 내부적으로 **MediaInfo DLL**을 씀. 대개 wheel에 포함되나, 안 되면 https://mediaarea.net/en/MediaInfo 의 DLL을 PATH에 두면 됨.
|
||
|
||
---
|
||
|
||
## 4. 자동 다운로드되는 모델 (faster-whisper)
|
||
|
||
파일/유튜브 탭에서 **자막 받아쓰기(ASR)** 를 처음 실행할 때, HuggingFace에서 자동 다운로드됩니다.
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| 모델 | `Systran/faster-whisper-medium` |
|
||
| 크기 | 약 **1.5GB** |
|
||
| 설정 | `medium` / `compute_type=int8` / `device=cpu` / 언어 `ko` |
|
||
| 캐시 위치 | `%USERPROFILE%\.cache\huggingface\hub\models--Systran--faster-whisper-medium` |
|
||
| ASR 결과 캐시 | 프로젝트 `.cache\` (content-hash 기준) |
|
||
|
||
- **최초 1회 인터넷 필요.** 이후 오프라인 동작.
|
||
- **붙여넣기 탭만 쓰고 ASR(하단자막 자동생성)을 끄면** 이 모델은 안 받아도 됨.
|
||
- 미리 받아두려면 아무 영상이나 파일 탭에 한 번 돌리면 캐시됨. (또는 다른 PC의 위 캐시 폴더를 통째로 복사해도 됨.)
|
||
|
||
---
|
||
|
||
## 5. (선택) Gemini 자막 글자 교정
|
||
|
||
자막 **글자만** 1:1 교정(시간 불변). 키 없으면 **자동 스킵**(Whisper 원문 유지)이라 필수는 아님.
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| 모델 | `gemini-2.5-flash` (무료 티어 지원) |
|
||
| 호출 | REST(`generativelanguage.googleapis.com`) via `urllib` — 추가 패키지 없음 |
|
||
| 키 주입 방법 (둘 중 하나) | ① 프로젝트 루트에 **`.gemini_key`** 파일(키 한 줄) ② 환경변수 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY` |
|
||
|
||
- 키 발급: https://aistudio.google.com → API key
|
||
- 429(무료 한도 초과) 시 Whisper 원문으로 폴백.
|
||
|
||
---
|
||
|
||
## 6. 코트라 볼드체 폰트 (선택, 있으면 예쁨)
|
||
|
||
pycapcut FontType에 없어 **저장 후 draft_content.json에 폰트 경로를 직접 주입**합니다.
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| 캐시 경로 | `%LOCALAPPDATA%\CapCut\User Data\Cache\effect\7480846567709265157\782a91b14f1661b95e7e587be27f1af4\font.ttf` |
|
||
| 크기 | 약 642KB |
|
||
| 경로 성격 | **PC 무관**(CapCut 전역 폰트 ID라 어느 PC든 동일 경로) |
|
||
|
||
- 이 파일이 **있어야** 자막/제목이 코트라 볼드체로 나옴. 없으면 주입을 **자동 생략** → CapCut 기본 폰트로 안전 동작(에러 아님).
|
||
- 다른 PC에서 만들려면: 그 PC의 **CapCut에서 코트라 볼드체를 한 번 사용**(아무 텍스트에 적용)하면 캐시가 생성됨. 또는 위 `font.ttf`를 같은 경로에 복사.
|
||
|
||
---
|
||
|
||
## 7. 다른 PC 설치 순서 (처음부터)
|
||
|
||
```powershell
|
||
# 1) Python 3.13 설치 (python.org, "Add Python to PATH" 체크) → 확인
|
||
python --version
|
||
|
||
# 2) ffmpeg 설치 후 bin 폴더를 PATH 등록 → 확인
|
||
ffmpeg -version
|
||
ffprobe -version
|
||
|
||
# 3) Node.js LTS 설치 → 확인
|
||
node --version
|
||
|
||
# 4) CapCut 설치 (그리고 원하면 코트라 볼드체 1회 사용)
|
||
|
||
# 5) 프로젝트 폴더 통째로 복사한 뒤, 그 폴더에서:
|
||
python -m pip install -r requirements.txt
|
||
|
||
# 6) (선택) Gemini 키
|
||
# .gemini_key 파일에 키 한 줄 저장 또는 환경변수 GEMINI_API_KEY 설정
|
||
|
||
# 7) 실행
|
||
캡컷_에이전트_구간합치기.bat
|
||
```
|
||
|
||
> 폴더를 복사할 때 `.cache/`, `.downloads/` 같은 대용량 파생물은 빼도 됨(자동 재생성).
|
||
> `.gemini_key`는 개인 키라 공유 주의.
|
||
|
||
---
|
||
|
||
## 8. 실행 · 포트
|
||
|
||
| 항목 | 값 |
|
||
|---|---|
|
||
| 런처 | `캡컷_에이전트_구간합치기.bat` (브라우저 자동 오픈) |
|
||
| 직접 실행 | `python -m uvicorn server.app:app --port 8001` |
|
||
| 주소 | http://127.0.0.1:8001 |
|
||
| 포트 | **8001** (형제 앱 v1 `../capcut`은 8000 — 동시 실행 가능) |
|
||
|
||
> ⚠️ **코드 수정 후엔 반드시 검은 창 닫고 .bat 재실행.** uvicorn hot-reload 안 됨(가장 흔한 "안 돼요" 원인).
|
||
|
||
---
|
||
|
||
## 9. 설치 검증
|
||
|
||
```bash
|
||
# 파이썬 임포트 체인 확인 (에러 없이 통과해야 함)
|
||
python -c "from server import app; print('app OK')"
|
||
python -c "from capcut_agent import pipeline, draft, youtube, transcribe, correct; print('modules OK')"
|
||
|
||
# 외부 도구 확인
|
||
ffmpeg -version | head -1
|
||
node --version
|
||
yt-dlp --version
|
||
```
|
||
|
||
최종 검증은 실제로 짧은 유튜브 구간 하나를 돌려 **CapCut에서 드래프트가 열리는지** 확인.
|
||
|
||
---
|
||
|
||
## 10. 문제 해결 (다른 PC 이식 시 흔한 것)
|
||
|
||
| 증상 | 원인 | 해결 |
|
||
|---|---|---|
|
||
| `ffmpeg`/`ffprobe` not found | PATH 미등록 | ffmpeg `bin`을 시스템 PATH에 추가, 창 새로 열기 |
|
||
| 유튜브 다운로드가 ffmpeg 크래시(exit 3436169992) | JS 런타임 없음 | Node.js 또는 deno 설치 |
|
||
| "Video unavailable" | 영상 자체 없음/지역제한 | `curl "https://www.youtube.com/oembed?url=<URL>&format=json"` 404면 영상 문제 |
|
||
| 유튜브가 갑자기 다 실패 | yt-dlp 구버전 | `python -m pip install -U yt-dlp` |
|
||
| 자막이 기본 폰트로 나옴 | 코트라 볼드체 캐시 없음 | §6 — CapCut에서 1회 사용 or font.ttf 복사 (없어도 동작은 함) |
|
||
| ASR 첫 실행이 매우 느림/멈춘 듯 | Whisper medium(1.5GB) 다운로드 중 | 최초 1회. 인터넷 확인, 기다리기 |
|
||
| 자막 교정이 안 됨 | Gemini 키 없음/429 | 선택 기능. 없으면 Whisper 원문 사용(정상) |
|
||
| 병합 시 `Invalid argument`(exit 4294967274) | (해결됨) 한글 경로 concat 버그 | 최신 `youtube.py`면 ASCII 임시링크로 자동 우회 |
|
||
| 드래프트 열면 영상이 흰띠·댓글 위로 삐짐 | CapCut 편집 중 render_index 꼬임 | 최신 `draft.py`는 오버레이/제목 트랙 자동 잠금으로 예방 |
|
||
| **클립을 옮긴 뒤 확대하면 그 클립만 템플릿 밖으로 삐짐** | CapCut이 옮긴 클립에 렌더순서를 새로(맨 위로) 매김 — 잠금으로 못 막음 | **캡컷에서 그 프로젝트를 닫고** → 웹 UI 하단 **"🩹 레이어 수리"** → 드래프트 선택 → 실행 → 캡컷에서 다시 열기 |
|
||
| **영상 중간에 초록 화면이 몇 초 나옴** | yt-dlp가 키프레임 아닌 위치에서 잘라 참조 프레임이 없음 | 최신 `youtube.py`가 컷마다 자동 검증→재다운로드→정밀 재컷. 로그에 `🩹` 표시. 예전에 받은 영상은 다시 만들어야 함 |
|
||
| 컷 섹션에 🤖 배지가 하나도 없다 (⭐만 있거나 비어 있음) | Gemini 추천 실패 — 한도 초과(429)·타임아웃·응답 파싱. 컷 섹션 자체는 타임스탬프만으로 그대로 뜬다 | 분석 로그(진행 화면 아래)에 `⚠️ ID n AI 추천 실패 — 타임스탬프만으로 배정했습니다` 가 있는지 확인. 한도 초과면 잠시 뒤 재분석. `프롬프트/댓글_추천.md`를 고쳤다면 `{cuts}` `{comments}` `{k}` 가 남아 있는지 확인 |
|
||
| 컷 섹션이 아예 안 보이고 ⭐ + ➕ 두 덩어리만 뜬다 | 편집안에 컷 정보가 없어(`hl.cuts` 없음) 예전 화면으로 폴백 | 편집안 생성(Step 3)이 실패한 ID다. 로그에서 그 ID의 실패 사유 확인. 이 화면에서 고른 카드는 컷 배치 없이 전체 균등으로 깔린다 |
|
||
| 댓글이 엉뚱한 장면에 뜬다 | 컷 소속 없이 전체 균등 배치로 깔림(위 폴백 화면) 또는 추천 자체가 안 맞음 | 위 두 줄 확인. 컷 섹션이 보인다면 그 컷 섹션 안에서 카드를 갈아끼우면 그 컷 위로 옮겨진다 |
|
||
| "컷별 댓글 추천"에서 오래 멈춰 보인다 | 하이라이트마다 Gemini 를 순차로 부른다(429 회피). 최악 5×90초 | **새로고침하지 말 것** — 분석이 통째로 날아간다. 로그에 `ID n 컷별 댓글 추천 중… (i/N)` 이 올라오면 정상 진행 중 |
|
||
| 콘솔에 한글 깨짐 | Windows cp949 | 표시만 깨짐. 로직·결과와 무관 |
|
||
| 카드 고르기까지 오래 걸린다 | 받아쓰기를 먼저 돌린다(추천 정확도를 위해) | 정상. 1분 영상당 ≈30초 |
|
||
| 🤖 배지가 하나도 없다 | Gemini 실패 또는 자막 없음 | 로그의 경고 확인. 🔤·➕는 계속 동작 |
|
||
| 분석 결과가 만료됐다고 나온다 | 서버 재시작으로 메모리 상태 소실 | 분석을 다시 돌린다 |
|
||
|
||
---
|
||
|
||
## 11. 한눈에 보는 버전 표 (복붙용)
|
||
|
||
```
|
||
OS Windows 11 (10.0.26200), x64
|
||
Python 3.13.0
|
||
ffmpeg/ffprobe 8.0.1 (gyan.dev essentials)
|
||
Node.js 22.17.0 (또는 deno 1.3.14)
|
||
CapCut 데스크톱(Windows)
|
||
|
||
fastapi 0.115.14
|
||
uvicorn 0.35.0
|
||
python-multipart 0.0.20
|
||
pyCapCut 0.0.3 (import pycapcut)
|
||
Pillow 10.4.0
|
||
pymediainfo 7.0.1
|
||
yt-dlp 2026.7.4 (최신 유지 권장)
|
||
faster-whisper 1.2.1
|
||
├ av 16.0.1
|
||
├ ctranslate2 4.6.2
|
||
├ onnxruntime 1.23.2
|
||
├ tokenizers 0.21.2
|
||
├ huggingface-hub 0.33.4
|
||
└ numpy 2.2.0
|
||
starlette 0.46.2
|
||
pydantic 2.11.7
|
||
|
||
ASR 모델 Systran/faster-whisper-medium (~1.5GB, int8/cpu)
|
||
Gemini(선택) gemini-2.5-flash (REST/urllib, 키 선택)
|
||
포트 8001
|
||
```
|