아이돌을 인물로 추적해봤더니 안 먹힌다는 걸 실측으로 확인했다. - 박지원 → 상위 3건이 전부 정치인 박지원(위대한 이슈 12.9만, KBC/JTV 뉴스). 동명이인 때문에 이름만으로는 못 쓴다. - 송하영·오해원·프로미스나인 → 잡히는 게 전부 음악방송 직캠·무대·팬캠. 예능 출연분이 직캠에 묻힌다. 배우·코미디언(윤경호·소지섭·딘딘)은 예능/드라마 클립이 상위에 오는데 아이돌은 검색 자체가 직캠 판이라 구조가 다르다. 그래서 두 가지를 했다. 1) 제목에 직캠·페이스캠·풀캠·교차편집·음중·PERFORMANCE VIDEO·커버 등이 들어가면 버린다. 말로 터지는 순간이 소재라 무대 영상은 소용없다. 적용 후 이채영 결과가 예능만 남았다(공포체험 4.9만, 고부갈등, 아이돌 인간극장). 2) 아이돌 소재는 인물이 아니라 채널로 잡는 게 맞다. fromis_9 공식채널을 SOURCE 시드로 추가 — 자체 예능 롱폼이 나온다([FM_1.24] 31분, Answer ME! 고민상담소 15분). 테스트 2건 추가 — 총 94건 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| docs | ||
| gradle/wrapper | ||
| src | ||
| .gitignore | ||
| build_log_final.txt | ||
| build_log.txt | ||
| build.gradle | ||
| CLAUDE.md | ||
| dashboard.png | ||
| gradlew | ||
| gradlew.bat | ||
| Jenkinsfile | ||
| README.md | ||
| settings.gradle | ||
| 영상테스트2.mp4 | ||
| 영상테스트.mp4 | ||
📖 개요
h-lab(아티팩트명 yanalyst)은 유튜브 Shorts 데이터를 수집·분석해 떡상(구독자 대비 조회수 폭발) 후보를 골라내고, 자막을 추출·재가공한 뒤 발행까지 추적하는 개인용 SSR 웹 서비스입니다. Spring Boot 백엔드에 Thymeleaf 서버 사이드 렌더링 UI를 사용하며, 모든 화면이 동일한 앱에서 제공됩니다.
라이트/다크 테마 토글을 지원하는 정제된 SaaS UI로, 사이드바 한 곳에서 전체 테마가 전환됩니다.
✨ 주요 기능
| 단계 | 설명 |
|---|---|
| 🛰️ 수집 (Collection) | 등록 채널 동기화 + 조회수 검색 수집. 정기 자동 수집 스케줄러. |
| 🔍 발굴 (Discovery) | 조회수 ÷ 구독자 배율로 떡상 후보 자동 선별. 카테고리·북마크·필터. |
| 🗂️ 큐레이션 (Curation) | 관심 상태(NEW→REVIEWING→TARGET→DONE/EXCLUDED) 칸반 보드 + 드래그 이동. |
| ✂️ 재가공 (Rework) | 영상 업로드 → Whisper 시간싱크 자막 추출 → 말 없는 구간 제거·배속 → SRT+영상 내보내기(CapCut import). 재작성 에디터. |
| 📤 발행 (Publish) | 제목·설명·해시태그·예약 패키지 관리, 발행 추적(업로드는 수동). |
🔁 콘텐츠 파이프라인
수집 발굴/큐레이션 재가공 발행
┌────────┐ ┌────────────┐ ┌──────────────┐ ┌──────────┐
│ CHANNEL│ ──▶ │ 배율 정렬 │ ──▶ │ 자막추출·컷 │ ──▶ │ 제목/태그 │
│ SEARCH │ │ 칸반 보드 │ │ SRT·영상 출력 │ │ 발행 추적 │
└────────┘ └────────────┘ └──────────────┘ └──────────┘
\______________ ChannelVideo (단일 마스터) ______________/
모든 단계는 domain/channel/ChannelVideo 엔티티 하나를 중심으로 돕니다.
🛠 기술 스택
Backend · Spring Boot 3.4.0 / Java 21 · Spring Data JPA · Validation
View · Thymeleaf + Layout Dialect (SSR) · Inter · Lucide Icons · Light/Dark CSS 변수 테마
DB · PostgreSQL (ddl-auto: update) · p6spy · Hypersistence Utils
Docs · SpringDoc OpenAPI (Swagger UI)
Build/Tools · Gradle Wrapper · Lombok · JUnit 5
AI/미디어 엔진(별도 Python 마이크로서비스) · faster-whisper(전사) · ffmpeg(컷·배속·렌더)
🚀 시작하기
요구사항: JDK 21, PostgreSQL 접근 정보. 서버 포트는 8088.
# 실행 (UI + API 모두 http://localhost:8088 에서 제공)
./gradlew bootRun # Windows: gradlew.bat bootRun
# 빌드 / 테스트
./gradlew build
./gradlew test
# 단일 테스트
./gradlew test --tests "com.hlab.yanalyst.domain.channel.SrtFormatterTest"
| 경로 | 설명 |
|---|---|
http://localhost:8088/ |
대시보드 |
http://localhost:8088/collection · /board · /discover |
수집함 · 칸반 · 발굴 |
http://localhost:8088/rework/{id} · /publish |
재가공 · 발행 큐 |
http://localhost:8088/swagger-ui.html |
Swagger UI |
🔐 환경 변수
시크릿은 환경 변수 또는 git-ignored application-local.yml로 주입합니다 (예시: application-local.yml.example).
| 변수 | 용도 |
|---|---|
DB_URL · DB_USERNAME · DB_PASSWORD |
PostgreSQL 접속 |
YOUTUBE_API_KEY |
YouTube Data API |
PYTHON_BASE_URL |
자막/전사/렌더 마이크로서비스 (기본 http://h-python.tolag.shop) |
UPLOAD_MAX_FILE_SIZE |
업로드 영상 최대 크기 (기본 200MB) |
📂 프로젝트 구조
h-lab/
├── src/main/java/com/hlab/yanalyst/
│ ├── domain/ # DDD 스타일 — Entity+Repository+Service+RestController
│ │ ├── channel/ # ChannelVideo(단일 마스터)·수집·큐레이션·재가공·SRT/컷 로직
│ │ ├── category/ publish/ # 분류 · 발행 패키지
│ │ └── production/ # n8n 크롤 랭킹 스냅샷
│ ├── web/ # Thymeleaf 페이지 컨트롤러 + 추가 JSON API
│ ├── service/ # 횡단 서비스 (YouTube 검색 등)
│ └── global/ # config · 공통 응답 · 예외 · 스케줄러
└── src/main/resources/
├── static/css/ # variables.css(테마 토큰) · style.css(컴포넌트)
├── static/js/ # common.js(사이드바·테마 토글)
└── templates/ # layout/base·sidebar + 페이지 HTML
🔌 외부 연동
- Python 마이크로서비스 — YouTube 자막(
/transcript), Whisper 전사(/transcribe), ffmpeg 렌더(/render). - YouTube Data API — 채널·영상 메타 수집 및 조회수 검색 (일일 쿼터 가드).
- n8n Webhook —
production도메인의 랭킹/크롤 데이터 연동.
📝 라이선스
개인용 프로젝트입니다.