4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# Start dev server (serves both API and frontend at http://localhost:8000)
python -m backend.main
# Install dependencies
pip install -r backend/requirements.txt
# Test MiniMax API connectivity
python backend/test_minimax.py
# Docker
docker compose up # requires .env with MINIMAX_API_KEY
# Required system dependency
# ffmpeg must be installed (brew install ffmpeg / apt install ffmpeg libass-dev)
# libass is needed for subtitle burn-in; videos still work without it
No build step, no linting, no test suite. Frontend is a single HTML file served via FastAPI StaticFiles.
Architecture
Multi-agent video production pipeline. User prompt goes through 6 sequential agents, producing a final MP4.
POST /api/create --> background thread runs pipeline --> SSE via GET /api/stream/{job_id}
Pipeline stages (sequential):
Director (MiniMax M1 LLM) -> shot outline JSON
Script (MiniMax M1 LLM) -> production script with video_prompt, narration, subtitle per shot
Visual (Hailuo 2.3 video) -> parallel video clips (ThreadPoolExecutor, max_workers=3)
Voice (Speech-2.6-HD TTS) -> sequential narration audio per shot
Music (Music-2.0) -> single background track (optional)
Editor (ffmpeg) -> concat videos, mix audio, burn subtitles -> final.mp4
Key data flow: Each agent's run() returns structured data consumed by the next agent. Director outputs {title, style, total_duration, shots[]}. Script enriches each shot with video_prompt (optimized for Hailuo), polished narration, and subtitle. Visual/Voice/Music produce file paths. Editor composites everything via ffmpeg subprocess calls.
Parallelism model: pipeline.py runs Visual, Voice, Music in a ThreadPoolExecutor(max_workers=3). Visual agent internally uses another ThreadPoolExecutor(max_workers=3) to generate individual shots concurrently. Voice generates shots sequentially within its thread.
Hailuo video generation is async (3-step): visual.py must POST to create a task -> poll query/video_generation every 10s (up to 5 min timeout) -> download via files/retrieve. Never try to get video results directly from the creation call.
Shared HTTP session: config.py creates a single api_session (requests.Session) with auth headers and 120s default timeout. All agents import and use this session. If you need different timeout for a specific call, pass timeout= to the individual request, not to the session.
Job lifecycle: main.py stores jobs in an in-memory dict. Pipeline runs in run_in_executor (background thread). Progress events accumulate in jobs[job_id]["events"] list, polled by SSE endpoint every 1s.
Frontend-backend coupling: Frontend JS references stages by name (director, script, visual, voice, music, editor) in stageMap to highlight corresponding UI cards. These stage names must match pipeline.py emit calls.
Key Conventions
- Every agent module in
backend/agents/exposes arun()function as its sole public interface - All MiniMax API calls must check
data["base_resp"]["status_code"] != 0before accessing response payload -- API returns HTTP 200 even on business errors (insufficient balance, rate limit, etc.) - LLM agents (director, script) strip markdown code fences from responses before JSON parsing
- Frontend uses relative API paths (
/api/...). FastAPIapp.mount("/", StaticFiles(...))must be registered after all API routes - Generated media files go to
backend/output/(gitignored). Config auto-creates this directory on import - Environment: single
.envfile at project root withMINIMAX_API_KEY - Editor agent uses
-t(not-shortest) to set output duration, preventing early video truncation
Mistakes Log
| Mistake | Fix |
|---|---|
MiniMax API 余额不足时 choices 为空,取值抛 NoneType |
先检查 base_resp.status_code != 0 再取 choices |
app.mount("/", StaticFiles(...)) 拦截 API 路由 |
必须放在所有 @app 路由注册之后 |
| Hailuo video generation 是异步的,直接取结果会失败 | 必须 POST 创建任务 -> 轮询 query 接口 -> 下载文件,三步走 |