The local storage companion to SchroDrive.
Transition debrid-cached media to locally owned, hardware-optimised, and preserved local libraries.
Quick Start • Features • Architecture • Directory Structure • Encoding Defaults • Safety Checklist • Tech Stack
While SchroDrive mounts debrid-cached torrents directly as virtual FUSE directories for streaming, SchroDrive Media Manager is the local media coordinator. It runs alongside your Plex, Jellyfin, and Emby stack to discover media, download files from cloud mounts, compress them using high-speed hardware-accelerated encoding, and organise them into local folders.
It helps you selectively transition cloud-dependent media to permanent, locally stored files with minimal space consumption.
The following diagram illustrates how the SchroDrive stack automates request handling, cloud streaming, watch stats tracking, and local library preservation:
graph TD
user["User"] -->|Requests Media| overseerr["Overseerr"]
overseerr -->|Auto-Adds Magnet| sd["SchroDrive (API + FUSE)"]
sd -->|Mounts FUSE Drives| ms["Plex / Jellyfin / Emby"]
user -->|Streams Media| ms
ms -->|Logs Play Activity| tautulli["Tautulli"]
tautulli -->|Popularity Suggestions| sdmm["SchroDrive Media Manager"]
sdmm -->|Triggers Download| qbit["qBittorrent"]
qbit -->|Downloads Cloud Files| sdmm
sdmm -->|"Auto-Encodes (NVENC/x265)"| sdmm
sdmm -->|Moves to Local Storage| local["Local Media Library"]
local -->|Triggers Refresh| ms
- Browse your local library and active cloud mounts (RealDebrid / TorBox) side-by-side.
- Monitor active encoding jobs, CPU/GPU utilisation, and encoding queue tasks in real-time.
- View immediate space-saving statistics (e.g. original size vs encoded size).
- Automatic HEVC/H.265 encoding utilising either NVIDIA NVENC (hevc_nvenc) for hardware acceleration or CPU (libx265).
- Full preservation of HDR10 metadata, subtitle tracks, and audio channels during transcodes.
- Automatically compares output files to source files and skips/warns if the transcode is larger than the original.
- Seamlessly copies debrid files from read-only mounts to local storage.
- Automatically triggers a Plex library refresh upon successful local file import.
- Uses one-click "Preserve" commands in the UI to import files, whole seasons, or entire shows.
- Integrates with Tautulli to monitor user watch history.
- Automatically generates preservation suggestions based on items in your cloud libraries that have high play counts or multiple viewers.
- Minimises host storage space by only keeping popular or frequently watched items locally.
- Enforces read-only bindings on all debrid mount points to prevent accidental cloud deletions.
- Writes files to
.partialextensions first so Plex does not index half-finished transcodes. - Performs atomic renames and compares source/destination durations to ensure file integrity.
- Docker and Docker Compose installed.
- NVIDIA GPU + drivers installed (for hardware-accelerated encoding).
- NVIDIA Container Toolkit configured on host.
- An existing Plex, Jellyfin, or Emby stack.
git clone https://github.com/moderniselife/ContentManager.git
cd ContentManagercp .env.example .env
# Edit .env and customize your credentialsRequired variables:
| Variable | Description |
|---|---|
PLEX_TOKEN |
Plex authentication token (required for Plex sync) |
TAUTULLI_API_KEY |
Tautulli API key (Settings → Web Interface → API) |
QBITTORRENT_USERNAME |
qBittorrent Web UI username |
QBITTORRENT_PASSWORD |
qBittorrent Web UI password |
TMDB_API_KEY |
TMDB API key for matching movie/show poster art |
Ensure media folders exist on the host with correct permissions:
sudo mkdir -p /mnt/media/{downloads/incomplete,downloads/complete,staging,library}
sudo mkdir -p /home/joseph/schrodrive-media/config
sudo chown -R 1000:1000 /mnt/media /home/joseph/schrodrive-mediaBuild and launch the container stack using Docker Compose:
# Build the Docker image
docker compose build
# Start services in the background
docker compose up -dOpen your browser and navigate to http://<your-server-ip>:8686.
| Path (Container) | Host Path | Purpose |
|---|---|---|
/config |
/home/joseph/schrodrive-media/config |
SQLite database, logs, and app settings |
/media/downloads/incomplete |
/mnt/media/downloads/incomplete |
Temporary directory for active downloads |
/media/downloads/complete |
/mnt/media/downloads/complete |
Finished torrent downloads waiting for auto-encoding |
/media/staging |
/mnt/media/staging |
Temporary workspace for active transcodes |
/media/library |
/mnt/media/library |
Permanent, optimised local media library folder |
/cloud/ |
/home/joseph/schrodrive/ |
Root of SchroDrive FUSE mount points (Read-Only) |
Highly efficient software encoding (slow but achieves maximum compression ratios).
| Resolution | CRF | Preset | Pixel Format |
|---|---|---|---|
| 4K HDR | 19 | slow | yuv420p10le |
| 4K SDR | 21 | slow | yuv420p10le |
| 1080p | 22 | slow | yuv420p10le |
| 720p | 24 | slow | yuv420p10le |
| 480p | 25 | slow | yuv420p10le |
Hardware-accelerated encoding (extremely fast transcode speeds with low CPU overhead).
| Resolution | Target Bitrate | Max Bitrate | Preset |
|---|---|---|---|
| 4K HDR | 20 Mbps | 24 Mbps | p6 |
| 4K SDR | 15 Mbps | 18 Mbps | p6 |
| 1080p | 6 Mbps | 8 Mbps | p6 |
| 720p | 3 Mbps | 4 Mbps | p6 |
| 480p | 1.5 Mbps | 2 Mbps | p6 |
To prevent library corruption or accidental data loss, SchroDrive Media Manager enforces the following safety controls:
- Read-Only Mounts: Cloud directories under
/cloud/are mounted as:ro(read-only) inside the container. - No Cloud Auto-Processing: Debrid-cached files are never auto-encoded, moved, or deleted. All cloud preservation flows must be manually initiated in the UI.
- Partial Writes Protection: FFmpeg output files are written with a
.partial.mkvextension so Plex doesn't scan incomplete streams. - Atomic Renames: Once encoding completes successfully, files are renamed atomically to their final names.
- Duration Matching: Compares transcode duration to source duration; discards output if they differ by more than 2 seconds.
- Transcode Size Threshold: Verifies that the transcode is smaller than the original. If not, the transcode is discarded, and the original file is preserved instead to save space.
| Component | Technology |
|---|---|
| Runtime | Bun |
| Backend | Hono (TypeScript) |
| Frontend | React 19 + Vite + shadcn/ui |
| Database | SQLite (bun:sqlite with WAL mode) |
| Styling | Tailwind CSS v4 |
| Encoding Engine | FFmpeg (libx265 / hevc_nvenc) |
| Containerization | Docker + NVIDIA Container Runtime |
This project is licensed under the terms specified in the LICENCE file.