130 lines
4.9 KiB
Markdown
130 lines
4.9 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Anime Quiz Video Generator - A full-stack web application that generates "Guess the Anime Opening" videos for YouTube Shorts and TikTok. Combines a Python FastAPI backend for video processing with a Vue 3 frontend.
|
|
|
|
## Commands
|
|
|
|
### Docker (primary development method)
|
|
```bash
|
|
docker-compose up --build # Build and start all services
|
|
docker-compose up # Start existing containers
|
|
docker-compose down # Stop containers
|
|
```
|
|
|
|
### Frontend (from /frontend directory)
|
|
```bash
|
|
npm run dev # Start Vite dev server (port 5173)
|
|
npm run build # Build for production
|
|
npm run preview # Preview production build
|
|
```
|
|
|
|
### Backend (from /backend directory)
|
|
```bash
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Backend (FastAPI + MoviePy)
|
|
- `backend/app/main.py` - FastAPI application with REST endpoints
|
|
- `backend/app/video_generator.py` - Core `VideoGenerator` class handling all video composition
|
|
- `backend/app/models.py` - Pydantic models (VideoMode, Difficulty, QuizItem, GenerateRequest)
|
|
- `backend/app/config.py` - Settings via Pydantic BaseSettings with `QUIZ_` env prefix
|
|
|
|
**Video generation runs in ThreadPoolExecutor (max_workers=1) to avoid blocking the async event loop.**
|
|
|
|
### Frontend (Vue 3 + Vite)
|
|
- `frontend/src/App.vue` - Main component handling quiz UI, form state, and API calls
|
|
- `frontend/src/components/OpeningsDownloader.vue` - Anime openings downloader UI
|
|
- `frontend/src/components/DownloadQueue.vue` - Download queue status component
|
|
- Uses Vue 3 Composition API (`ref`, `reactive`, `computed`)
|
|
- Vite proxies `/api`, `/videos`, `/download` to backend at `http://backend:8000`
|
|
|
|
### Openings Downloader Module
|
|
Located in `backend/app/openings_downloader/`:
|
|
- `router.py` - FastAPI router with `/api/downloader/*` endpoints
|
|
- `db_models.py` - SQLAlchemy models (Anime, AnimeTheme, DownloadTask)
|
|
- `schemas.py` - Pydantic schemas for API requests/responses
|
|
- `config.py` - Module settings with `DOWNLOADER_` env prefix
|
|
- `services/shikimori.py` - Shikimori GraphQL API client (anime search)
|
|
- `services/animethemes.py` - AnimeThemes API client (theme videos)
|
|
- `services/downloader.py` - Download queue processing, WebM→MP3 conversion
|
|
- `services/storage_tracker.py` - S3 storage usage tracking
|
|
|
|
**Download flow:**
|
|
1. Search anime via Shikimori API
|
|
2. Fetch available themes from AnimeThemes API
|
|
3. Add themes to download queue
|
|
4. Background worker downloads WebM, converts to MP3 via FFmpeg, uploads to S3
|
|
5. Creates Opening entity in main table for use in quiz generation
|
|
|
|
### Media Organization
|
|
```
|
|
media/
|
|
├── audio/ # MP3 anime openings
|
|
├── backgrounds/ # MP4 looping videos (5-10 sec recommended)
|
|
└── posters/ # Anime poster images (JPG/PNG/WebP)
|
|
|
|
output/videos/ # Generated MP4 files
|
|
```
|
|
|
|
## Video Generation Flow
|
|
|
|
1. Frontend POSTs to `/generate` with quiz configuration
|
|
2. `VideoGenerator.generate()` creates scenes in sequence:
|
|
- **Question scene**: background + countdown timer + difficulty badge + audio track
|
|
- **Answer scene**: anime title + poster image with fade-in
|
|
3. For "full" mode, adds final CTA screen
|
|
4. Concatenates all scenes → writes MP4 (H.264/AAC)
|
|
5. Returns video URL for download
|
|
|
|
**Video dimensions:**
|
|
- `shorts`: 1080x1920 (9:16) for TikTok/Shorts
|
|
- `full`: 1920x1080 (16:9) for YouTube
|
|
|
|
## API Endpoints
|
|
|
|
### Core Endpoints
|
|
| Method | Endpoint | Purpose |
|
|
|--------|----------|---------|
|
|
| GET | `/health` | Health check with FFmpeg status |
|
|
| GET | `/content` | List available audio, backgrounds, posters |
|
|
| POST | `/generate` | Generate video (returns video URL) |
|
|
| GET | `/download/{filename}` | Download generated video |
|
|
| DELETE | `/videos/{filename}` | Delete video |
|
|
| GET | `/videos-list` | List generated videos |
|
|
|
|
### Openings Downloader Endpoints (`/api/downloader`)
|
|
| Method | Endpoint | Purpose |
|
|
|--------|----------|---------|
|
|
| GET | `/search` | Search anime via Shikimori (query, year, status params) |
|
|
| GET | `/anime/{shikimori_id}` | Get anime details with available themes |
|
|
| POST | `/queue/add` | Add specific themes to download queue |
|
|
| POST | `/queue/add-all` | Add all themes from anime to queue |
|
|
| GET | `/queue` | Get queue status (includes `worker_running` flag) |
|
|
| DELETE | `/queue/{task_id}` | Cancel a queued task |
|
|
| POST | `/queue/{task_id}/retry` | Retry a failed task |
|
|
| DELETE | `/queue/clear` | Clear completed/failed tasks (`include_failed` param) |
|
|
| GET | `/storage` | Get S3 storage usage stats |
|
|
|
|
## Environment Variables
|
|
|
|
### Core Settings
|
|
```
|
|
QUIZ_MEDIA_PATH=/app/media
|
|
QUIZ_OUTPUT_PATH=/app/output/videos
|
|
VITE_API_URL=http://backend:8000
|
|
```
|
|
|
|
### Downloader Settings
|
|
```
|
|
DOWNLOADER_SHIKIMORI_USER_AGENT=AnimeQuiz/1.0
|
|
DOWNLOADER_SHIKIMORI_TOKEN= # Optional OAuth token for higher rate limits
|
|
DOWNLOADER_S3_STORAGE_LIMIT_BYTES=107374182400 # 100 GB default
|
|
DOWNLOADER_DOWNLOAD_TIMEOUT_SECONDS=300
|
|
```
|