MPR - Media Processor
A web-based media transcoding tool with Django admin, FastAPI backend, and React timeline UI.
Architecture
Browser (mpr.local.ar)
│
nginx:80
│
┌────┴────┐
│ │
/admin /api, /ui
│ │
Django FastAPI ◄── Timeline UI
│ │
│ ┌────┘
│ │
└───►│ (job operations)
│
gRPC Server
│
Celery Worker
- Django (
/admin): Admin interface for data management - FastAPI (
/api): REST API and gRPC client - Timeline UI (
/ui): React app for video editing - gRPC Server: Worker communication with progress streaming
- Celery: Job execution via FFmpeg
Prerequisites
- Docker & Docker Compose
Quick Start
# Add to /etc/hosts
echo "127.0.0.1 mpr.local.ar" | sudo tee -a /etc/hosts
# Start all services
cd ctrl
cp .env.template .env
docker compose up -d
Access Points
| URL | Description |
|---|---|
| http://mpr.local.ar/admin | Django Admin |
| http://mpr.local.ar/api/docs | FastAPI Swagger |
| http://mpr.local.ar/ui | Timeline UI |
Commands
cd ctrl
# Start/stop
docker compose up -d
docker compose down
# Rebuild after code changes
docker compose up -d --build
# View logs
docker compose logs -f
docker compose logs -f celery
# Create admin user
docker compose exec django python manage.py createsuperuser
Code Generation
Models are defined as dataclasses in schema/models/ and generated via modelgen:
- Django ORM models (
--include dataclasses,enums) - Pydantic schemas (
--include dataclasses,enums) - TypeScript types (
--include dataclasses,enums,api) - Protobuf definitions (
--include grpc)
Each target only gets the model groups it needs via the --include flag.
# Regenerate all targets
bash ctrl/generate.sh
Media Storage
MPR separates media into input (MEDIA_IN) and output (MEDIA_OUT) paths, each independently configurable. File paths are stored relative for cloud portability.
Local Development
- Source files:
/app/media/in/video.mp4 - Output files:
/app/media/out/video_h264.mp4 - Served via:
http://mpr.local.ar/media/in/video.mp4(nginx alias)
AWS/Cloud Deployment
Input and output can be different buckets/locations:
MEDIA_IN=s3://source-bucket/media/
MEDIA_OUT=s3://output-bucket/transcoded/
Scan Endpoint: POST /api/assets/scan recursively scans MEDIA_IN and registers new files with relative paths.
See docs/media-storage.md for full details.
Project Structure
mpr/
├── api/ # FastAPI application
│ ├── routes/ # API endpoints
│ └── schemas/ # Pydantic models (generated)
├── core/ # Core utilities
│ └── ffmpeg/ # FFmpeg wrappers
├── ctrl/ # Docker & deployment
│ ├── docker-compose.yml
│ └── nginx.conf
├── media/
│ ├── in/ # Source media files
│ └── out/ # Transcoded output
├── rpc/ # gRPC server & client
│ └── protos/ # Protobuf definitions (generated)
├── mpr/ # Django project
│ └── media_assets/ # Django app
├── schema/ # Source of truth
│ └── models/ # Dataclass definitions
├── task/ # Celery job execution
│ ├── executor.py # Executor abstraction
│ └── tasks.py # Celery tasks
└── ui/ # Frontend
└── timeline/ # React app
Environment Variables
See ctrl/.env.template for all configuration options.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
sqlite | PostgreSQL connection string |
REDIS_URL |
redis://localhost:6379 | Redis for Celery |
GRPC_HOST |
grpc | gRPC server hostname |
GRPC_PORT |
50051 | gRPC server port |
MPR_EXECUTOR |
local | Executor type (local/lambda) |
MEDIA_IN |
/app/media/in | Source media files directory |
MEDIA_OUT |
/app/media/out | Transcoded output directory |
MEDIA_BASE_URL |
/media/ | Base URL for serving media (use S3 URL for cloud) |
VITE_ALLOWED_HOSTS |
- | Comma-separated allowed hosts for Vite dev server |
License
MIT
Description
Languages
Python
83.1%
TypeScript
8.3%
Shell
5.3%
CSS
2.8%
Dockerfile
0.4%
Other
0.1%