Files
mediaproc/docs/media-storage.md

3.8 KiB

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

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

# 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

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

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:

    aws s3 sync /app/media/in/ s3://source-bucket/media/
    aws s3 sync /app/media/out/ s3://output-bucket/transcoded/
    
  2. Update environment variables:

    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