Content
# VGA - Video Generation App
Generate animated "noodle-style" explainer videos from a storyboard, complete with neural TTS voiceover, royalty-free background music, and ffmpeg encoding. Drive it from a **Web UI**, a **CLI**, or as an **MCP server** for Claude Desktop and other agents.
## Features
- **Storyboard-driven rendering** - JSON storyboards become animated scenes via a Jinja2 + Playwright HTML renderer.
- **Neural voiceover** - piper-TTS (ONNX) with auto-downloaded models on first use.
- **Music & SFX** - drop royalty-free tracks into `assets/music/` and `assets/sfx/`.
- **Three interfaces** - Web UI, Typer CLI, and FastMCP server (SSE transport).
- **Self-contained** - looks for `ffmpeg.exe` in the project's `bin/` folder before falling back to system PATH.
## Requirements
- Python **3.12+**
- [`uv`](https://docs.astral.sh/uv/) (recommended) or `pip`
- `ffmpeg` - placed in `bin/ffmpeg.exe` (Windows) or available on PATH. See [bin/README.md](bin/README.md).
- Playwright browsers (installed once after dependencies)
## Installation
```bash
git clone https://github.com/kamal-manick/video-generator.git
cd video-generator
# Resolve deps from pyproject.toml, create .venv/, generate uv.lock,
# and install runtime + dev extras in one step
uv sync --extra dev
# Install the headless browser used by the renderer
uv run playwright install chromium
```
Drop `ffmpeg.exe` into [bin/](bin/) (see [bin/README.md](bin/README.md)).
> Prefer plain `pip`? `python -m venv .venv && .venv\Scripts\activate && pip install -e ".[dev]"` is equivalent.
## Usage
### Web UI + MCP server (default)
```bash
uv run python -m vga serve
```
Then open:
- Web UI → http://127.0.0.1:8765/
- MCP SSE endpoint → http://127.0.0.1:8765/mcp/sse
### CLI
```bash
uv run python -m vga --help
uv run python -m vga list-projects
```
### MCP only (stdio for Claude Desktop)
```bash
uv run python -m vga serve --transport stdio --no-web
```
Or connect Claude Desktop to the SSE endpoint above:
```json
{ "mcpServers": { "vga": { "url": "http://127.0.0.1:8765/mcp/sse" } } }
```
## Configuration
All settings can be overridden with environment variables prefixed `VGA_`, or via a `.env` file in the project root.
| Variable | Default | Description |
|----------|---------|-------------|
| `VGA_PORT` | `8765` | HTTP/SSE port |
| `VGA_HOST` | `127.0.0.1` | Bind address |
| `VGA_TRANSPORT` | `sse` | `sse` or `stdio` |
| `VGA_DEFAULT_FPS` | `30` | Render frame rate |
| `VGA_KEEP_TEMP` | `false` | Keep intermediate frames |
## Project layout
```
src/vga/
__main__.py Typer CLI + server entry
config.py Pydantic settings
web/ FastAPI routes + SPA at static/index.html
server/ FastMCP server + tool handlers
pipeline/ Render orchestration
renderer/ HTML build + Playwright frame capture + ffmpeg encoder
audio/ piper-TTS wrapper
music/ Background music library
models/ Pydantic storyboard / job models
storage/ Project store
templates/ Jinja2 noodle scene + stepper.js
assets/ music/ and sfx/
models/tts/piper/ Auto-downloaded TTS weights (gitignored)
bin/ ffmpeg.exe (user-supplied, gitignored)
output/ Rendered videos (gitignored)
projects/ Saved storyboards (gitignored)
```
## Development
The test suite lives under [tests/](tests/) (`test_models.py`, `test_music_library.py`, `test_project_store.py`). [pyproject.toml](pyproject.toml) already sets `testpaths = ["tests"]` and `asyncio_mode = "auto"`, so bare `pytest` discovers and runs everything:
```bash
uv run pytest # run the full suite
uv run pytest -k music # run only tests matching "music"
uv run pytest -v # verbose output
```
## License
[MIT](LICENSE)