Files
mediaproc/docs/media-storage.md
2026-02-06 09:23:36 -03:00

4.6 KiB

Media Storage Architecture

Overview

MPR stores media file paths relative to the media root to ensure portability between local development and cloud deployments (AWS S3, etc.).

Storage Strategy

File Path Storage

  • Database: Stores only the relative path (e.g., videos/sample.mp4)
  • Media Root: Configurable base directory via MEDIA_ROOT 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_ROOT=/app/media

File Structure

/app/media/
├── video1.mp4
├── video2.mp4
└── subfolder/
    └── video3.mp4

Database Storage

filename: video1.mp4
file_path: video1.mp4

filename: video3.mp4
file_path: subfolder/video3.mp4

URL Serving

  • Nginx serves via location /media { alias /app/media; }
  • Frontend accesses: http://mpr.local.ar/media/video1.mp4
  • Video player: <video src="/media/video1.mp4" />

AWS/Cloud Deployment

S3 Configuration

MEDIA_ROOT=s3://my-bucket/media/
MEDIA_BASE_URL=https://my-bucket.s3.amazonaws.com/media/

S3 Structure

s3://my-bucket/media/
├── video1.mp4
├── video2.mp4
└── subfolder/
    └── video3.mp4

Database Storage (Same!)

filename: video1.mp4
file_path: video1.mp4

filename: video3.mp4
file_path: subfolder/video3.mp4

URL Serving

  • Frontend prepends MEDIA_BASE_URL: https://my-bucket.s3.amazonaws.com/media/video1.mp4
  • Video player: <video src="https://my-bucket.s3.amazonaws.com/media/video1.mp4" />

API Endpoints

Scan Media Folder

POST /api/assets/scan

Behavior:

  1. Recursively scans MEDIA_ROOT directory
  2. Finds all video/audio files (mp4, mkv, avi, mov, mp3, wav, etc.)
  3. Stores paths relative to MEDIA_ROOT
  4. Skips already-registered files (by filename)
  5. Returns summary: { found, registered, skipped, files }

Example:

curl -X POST http://mpr.local.ar/api/assets/scan
{
  "found": 15,
  "registered": 12,
  "skipped": 3,
  "files": ["video1.mp4", "video2.mp4", ...]
}

Create Asset

POST /api/assets/
Content-Type: application/json

{
  "file_path": "/app/media/video.mp4",
  "filename": "video.mp4"
}

Behavior:

  • Validates file exists
  • Converts absolute path to relative (relative to MEDIA_ROOT)
  • Stores relative path in database

Migration Guide

Moving from Local to S3

  1. Upload files to S3:

    aws s3 sync /app/media/ s3://my-bucket/media/
    
  2. Update environment variables:

    MEDIA_ROOT=s3://my-bucket/media/
    MEDIA_BASE_URL=https://my-bucket.s3.amazonaws.com/media/
    
  3. Database paths remain unchanged (already relative)

  4. Update frontend to use MEDIA_BASE_URL from config

Moving from S3 to Local

  1. Download files from S3:

    aws s3 sync s3://my-bucket/media/ /app/media/
    
  2. Update environment variables:

    MEDIA_ROOT=/app/media
    # Remove MEDIA_BASE_URL or set to /media/
    
  3. Database paths remain unchanged (already relative)

Implementation Details

Backend (FastAPI)

File path normalization (api/routes/assets.py):

import os
from pathlib import Path

media_root = Path(os.environ.get("MEDIA_ROOT", "/app/media"))

# Convert absolute to relative
file_path = Path("/app/media/subfolder/video.mp4")
rel_path = str(file_path.relative_to(media_root))
# Result: "subfolder/video.mp4"

Frontend (React)

Current implementation:

<video src={`/media/${asset.file_path}`} />

Future cloud implementation:

const MEDIA_BASE_URL = import.meta.env.VITE_MEDIA_BASE_URL || '/media/';
<video src={`${MEDIA_BASE_URL}${asset.file_path}`} />

Supported File Types

Video formats:

  • .mp4, .mkv, .avi, .mov, .webm, .flv, .wmv, .m4v

Audio formats:

  • .mp3, .wav, .flac, .aac, .ogg, .m4a

Best Practices

  1. Always use relative paths when storing file references
  2. Use environment variables for media root and base URL
  3. Validate file existence before creating assets
  4. Scan periodically to discover new files
  5. Use presigned URLs for S3 private buckets (TODO: implement)

Future Enhancements

  • S3 presigned URL generation for private buckets
  • CloudFront CDN integration
  • Multi-region S3 replication
  • Automatic metadata extraction on upload
  • Thumbnail generation and storage