151 lines
3.8 KiB
Markdown
151 lines
3.8 KiB
Markdown
# Media Storage Architecture
|
|
|
|
## Overview
|
|
|
|
MPR separates media into **input** and **output** paths, each independently configurable. File paths are stored **relative to their respective root** to ensure portability between local development and cloud deployments (AWS S3, etc.).
|
|
|
|
## Storage Strategy
|
|
|
|
### Input / Output Separation
|
|
|
|
| Path | Env Var | Purpose |
|
|
|------|---------|---------|
|
|
| `MEDIA_IN` | `/app/media/in` | Source media files to process |
|
|
| `MEDIA_OUT` | `/app/media/out` | Transcoded/trimmed output files |
|
|
|
|
These can point to different locations or even different servers/buckets in production.
|
|
|
|
### File Path Storage
|
|
- **Database**: Stores only the relative path (e.g., `videos/sample.mp4`)
|
|
- **Input Root**: Configurable via `MEDIA_IN` env var
|
|
- **Output Root**: Configurable via `MEDIA_OUT` env var
|
|
- **Serving**: Base URL configurable via `MEDIA_BASE_URL` env var
|
|
|
|
### Why Relative Paths?
|
|
1. **Portability**: Same database works locally and in cloud
|
|
2. **Flexibility**: Easy to switch between storage backends
|
|
3. **Simplicity**: No need to update paths when migrating
|
|
|
|
## Local Development
|
|
|
|
### Configuration
|
|
```bash
|
|
MEDIA_IN=/app/media/in
|
|
MEDIA_OUT=/app/media/out
|
|
```
|
|
|
|
### File Structure
|
|
```
|
|
/app/media/
|
|
├── in/ # Source files
|
|
│ ├── video1.mp4
|
|
│ ├── video2.mp4
|
|
│ └── subfolder/
|
|
│ └── video3.mp4
|
|
└── out/ # Transcoded output
|
|
├── video1_h264.mp4
|
|
└── video2_trimmed.mp4
|
|
```
|
|
|
|
### Database Storage
|
|
```
|
|
# Source assets (scanned from media/in)
|
|
filename: video1.mp4
|
|
file_path: video1.mp4
|
|
|
|
filename: video3.mp4
|
|
file_path: subfolder/video3.mp4
|
|
```
|
|
|
|
### URL Serving
|
|
- Nginx serves input via `location /media/in { alias /app/media/in; }`
|
|
- Nginx serves output via `location /media/out { alias /app/media/out; }`
|
|
- Frontend accesses: `http://mpr.local.ar/media/in/video1.mp4`
|
|
- Video player: `<video src="/media/in/video1.mp4" />`
|
|
|
|
## AWS/Cloud Deployment
|
|
|
|
### S3 Configuration
|
|
```bash
|
|
# Input and output can be different buckets/paths
|
|
MEDIA_IN=s3://source-bucket/media/
|
|
MEDIA_OUT=s3://output-bucket/transcoded/
|
|
MEDIA_BASE_URL=https://source-bucket.s3.amazonaws.com/media/
|
|
```
|
|
|
|
### S3 Structure
|
|
```
|
|
s3://source-bucket/media/
|
|
├── video1.mp4
|
|
└── subfolder/
|
|
└── video3.mp4
|
|
|
|
s3://output-bucket/transcoded/
|
|
├── video1_h264.mp4
|
|
└── video2_trimmed.mp4
|
|
```
|
|
|
|
### Database Storage (Same!)
|
|
```
|
|
filename: video1.mp4
|
|
file_path: video1.mp4
|
|
|
|
filename: video3.mp4
|
|
file_path: subfolder/video3.mp4
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### Scan Media Folder
|
|
```http
|
|
POST /api/assets/scan
|
|
```
|
|
|
|
**Behavior:**
|
|
1. Recursively scans `MEDIA_IN` directory
|
|
2. Finds all video/audio files (mp4, mkv, avi, mov, mp3, wav, etc.)
|
|
3. Stores paths **relative to MEDIA_IN**
|
|
4. Skips already-registered files (by filename)
|
|
5. Returns summary: `{ found, registered, skipped, files }`
|
|
|
|
### Create Job
|
|
```http
|
|
POST /api/jobs/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"source_asset_id": "uuid",
|
|
"preset_id": "uuid",
|
|
"trim_start": 10.0,
|
|
"trim_end": 30.0
|
|
}
|
|
```
|
|
|
|
**Behavior:**
|
|
- Server sets `output_path` using `MEDIA_OUT` + generated filename
|
|
- Output goes to the output directory, not alongside source files
|
|
|
|
## Migration Guide
|
|
|
|
### Moving from Local to S3
|
|
|
|
1. **Upload source files to S3:**
|
|
```bash
|
|
aws s3 sync /app/media/in/ s3://source-bucket/media/
|
|
aws s3 sync /app/media/out/ s3://output-bucket/transcoded/
|
|
```
|
|
|
|
2. **Update environment variables:**
|
|
```bash
|
|
MEDIA_IN=s3://source-bucket/media/
|
|
MEDIA_OUT=s3://output-bucket/transcoded/
|
|
MEDIA_BASE_URL=https://source-bucket.s3.amazonaws.com/media/
|
|
```
|
|
|
|
3. **Database paths remain unchanged** (already relative)
|
|
|
|
## Supported File Types
|
|
|
|
**Video:** `.mp4`, `.mkv`, `.avi`, `.mov`, `.webm`, `.flv`, `.wmv`, `.m4v`
|
|
**Audio:** `.mp3`, `.wav`, `.flac`, `.aac`, `.ogg`, `.m4a`
|