All apps · 0 apps
Optimisarr
Docker app from Jellman's Repository
Overview
Readme
View on GitHub
Optimisarr
Safe, verified FFmpeg transcoding for self-hosted media libraries.
Docs • Quick Start • Hardware Acceleration
Optimisarr is a self-hosted, Docker-based FFmpeg media-library optimiser. It finds eligible video, audio, and image files, transcodes them to reduce storage use, verifies the result, and only then replaces the original.
Built for Plex, Jellyfin, Emby, Sonarr, and Radarr users, Optimisarr supports CPU, NVIDIA NVENC, Intel QSV, and VA-API transcoding. Originals are quarantined for rollback rather than deleted immediately.
Why Optimisarr?
- Reduce media-library storage without manually batch-transcoding files.
- Verify output before replacement, with configurable stream-retention, duration, and size-reduction checks.
- Run one Docker container on a homelab, Unraid-style server, or other self-hosted setup.
- Pause processing while Plex, Jellyfin, or Emby has active streams.
All media shown in screenshots is fabricated test data created for documentation; no copyrighted material is used.
Documentation
Start with the documentation index: getting started, user workflow, configuration, hardware acceleration, reverse proxy, safe replacement, integrations, troubleshooting, glossary, and API reference.
Project status
Optimisarr is early-stage software. Use it on a small test set first and keep backups of media you cannot replace. It is maintained in spare time, so there is no support SLA or promise of a release schedule.
What it does
Multiple libraries, each with its own media type (Film/TV/Music/Photo/Other) and rule profile, with a folder-picker for paths. Scanning discovers the file types that match the library (video, audio, or images).
Recursive, settling-aware scanning that builds a media inventory (idempotent), with automatic background probing of newly discovered files. Enabled libraries are rescanned on a configurable global interval (one hour by default).
ffprobe inspection (codec, resolution, duration, tracks, media kind).
Optimisation for video, audio, and still images, each through the same candidate → transcode → verify → quarantine/rollback pipeline.
FFmpeg/ffprobe tool detection, liveness, and readiness endpoints. Docker health checks verify database access, required writable paths, and media tools.
Svelte 5 + Tailwind sidebar UI (Dashboard, Libraries, Inventory, Queue, Quarantine, Schedule, Settings; Tools live under Settings). Verification reports are available from Queue and Quarantine detail sheets.
Queue resource controls: max concurrent jobs, CPU thread limits, and a free work-disk safety pause. The only global scheduling setting is the library scan interval; when work runs is set per library (see auto-optimise below).
Per-library auto-optimise windows continuously queue newly eligible files; opt-in auto-replace promotes only fully verified jobs, still quarantining the original first so rollback remains available.
Optimisation presets per library (Compatibility H.264 / Balanced HEVC / Efficiency AV1 / Remux), plus Scott's Settings — HEVC with HDR preserved and AAC 96 kbps stereo audio. Optionally re-encode oversized files already in the target codec (e.g. a huge HEVC remux) above a size you set.
Exclude files so they are never optimised again — manually from a stuck Queue job, or automatically after repeated failures — managed per library on an Excluded tab. Durable (keyed by path) and reversible; originals untouched.
A Dashboard leading with a persistent lifetime space-saved total (resettable), what's in flight, and live CPU/GPU usage while a job encodes.
Preview from Inventory or a library's Candidates tab to try the resolved settings on one file before queueing it. Long video previews encode a 60-second sample from the middle of the source, verify against a temporary clipped reference from that same window, and label the report as segment-only; audio and image previews run in full.
Video replacement verifies the resolved codec, exact resolution, pixel bit depth, chroma sampling, and encoder profile in addition to full decode, timing, HDR/colour, stream, size, and VMAF gates.
Music defaults to AAC 128 kbps in M4A, preserving common attached cover art, tags, and timed lyrics. Opus remains an efficient option for art-free libraries; incompatible artwork/lyrics combinations are rejected before queueing rather than being dropped or failing during muxing.
Hardware capability detection for FFmpeg accelerators, CPU encoders, NVIDIA NVENC, Intel QSV, VAAPI, NVIDIA runtime, and
/dev/drimapping.Global encoder mode selection for Auto, CPU, NVIDIA NVENC, Intel QSV, and VAAPI.
Configurable verification gates for duration tolerance, audio/subtitle retention, and required size reduction.
Hardware transcoding through NVIDIA NVENC, Intel QSV, and Intel/AMD VA-API, with per-encoder availability confirmed by a real test encode (not just inferred), and the encoder used shown per job (GPU/CPU) on the Queue.
GPU hardware decoding (QSV/VA-API) of the source as well as the encode, on by default, with automatic CPU-decode fallback for sources the GPU can't decode — so a large 4K encode no longer burns a CPU core just on software decode. Skipped for HDR→SDR tonemap jobs (the tonemap runs in software).
A "now encoding" hero panel with a live progress bar, fps/speed/ETA, and a live CPU/GPU usage graph while a job encodes (sampled with unprivileged reads only; no root or extra container capabilities). Click any job for a detail view showing the resolved encoder, the exact FFmpeg command, the verification report, and inline actions (retry, exclude, replace). The sidebar's Queue item throbs a GPU chip when work is hardware-accelerated or a snail when it's on the CPU, with a running-job count.
Optional service-activity pauses (Plex/Jellyfin/Emby), dry-run mode, configurable replacement/quarantine policy with a retention window, and library integrations (Plex/Jellyfin/Emby re-scan, Sonarr/Radarr import-aware exclusions, notifications, config-and-secrets backup/import).
Still planned (see the roadmap and maintained hardware validation matrix): real-hardware validation for AMD VA-API. Intel QSV has been tested on real hardware for both encoding and decoding.
Before you start
- Docker Engine with the Compose plugin.
- Read and write access to the media folders you mount into the container.
- One host storage root mounted at
/data, with media, work, and quarantine beneath it, if you want atomic replacement moves. - A backup of media that matters to you. Quarantine and rollback are useful, but they are not a backup strategy.
Quick start (Docker)
The image is published to GHCR on every push to dev:
mkdir -p ./optimisarr-config /path/to/storage/{media,.optimisarr/work,.optimisarr/trash}
sudo chown -R 1000:1000 ./optimisarr-config /path/to/storage
docker run -d --name optimisarr \
-p 8787:8787 \
-e PUID=1000 -e PGID=1000 -e TZ=Europe/London \
-e OPTIMISARR_ADMIN_TOKEN='change-this-long-random-token' \
-e OPTIMISARR_WORK_DIR=/data/.optimisarr/work \
-e OPTIMISARR_TRASH_DIR=/data/.optimisarr/trash \
-v ./optimisarr-config:/config \
-v /path/to/storage:/data \
ghcr.io/jellman86/optimisarr:dev
Wait for readiness, then open the UI:
curl http://localhost:8787/api/ready
Open http://localhost:8787. A new database opens the resumable five-step setup, verifies the
mounted paths, free space, filesystem/mount relationships, permissions, and media tools. Missing
or inaccessible storage gets concrete Docker Compose, Unraid, TrueNAS, or local recovery steps and
a real Re-test action. Setup lets you fully configure as many libraries as needed and starts in
Dry-run mode. Completing setup never starts a scan or job; review each library’s Candidates,
then scan and queue a small test set deliberately. Use Run setup again in the Settings header to
revisit the guided checks without deleting existing configuration.
Add libraries from /data/media; the hidden work and quarantine directories remain below the same
container mount boundary.
Compose examples are available for every supported runtime:
Keep media, work, and quarantine beneath one container mount boundary when possible so the
replacement pipeline can use atomic moves; separate bind mounts require the verified
cross-filesystem fallback. Do not publish 8787 directly to the
internet; use an authenticated reverse proxy for remote access. Setting
OPTIMISARR_ADMIN_TOKEN adds a built-in bearer-token backstop for the UI and API,
but a reverse proxy remains the recommended public-access boundary.
Hardware acceleration (GPU)
Transcoding runs through a bundled jellyfin-ffmpeg, which ships NVENC plus the Intel
iHD driver and oneVPL runtime — so NVIDIA, Intel (incl. iGPUs like the N100), and AMD GPUs
work without installing host driver packages. The encoder is picked by the global encoder
mode (Settings → Auto by default); the Tools page shows what each GPU actually supports
(availability is confirmed by a real test encode), and each Queue job shows whether it ran on
the GPU or CPU. Perceptual quality measurement uses a separate, pinned static FFmpeg
with libvmaf; the Tools page reports that optional capability independently. An optional
OPTIMISARR_FFMPEG_VMAF_CUDA binary enables NVIDIA libvmaf_cuda when the build and runtime GPU
support it; QSV/VA-API can offload SDR decoding while scoring remains on the CPU, and every hardware
failure retries in software. VMAF verification is off by default for video re-encodes and skipped
for remuxes; enable it per library under Libraries → Configure when the safeguard is worth the cost.
Model choice and measurement preparation are automatic: HDTV/4K selection, reference-resolution
bicubic scaling, timestamp/timebase and colour-range alignment, and like-for-like HDR→SDR reference
tone-mapping require no libvmaf expertise. Optional early/middle/late sample scoring and 1–10 frame
subsampling reduce runtime; every-frame scoring remains the safest default. VMAF-only failures get
one encoder-aware higher-quality retry, and the report records the effective quality and sampling context.
When a hardware encoder is in use the source is hardware-decoded on the GPU too
(Settings → Hardware decoding, on by default), so transcode frames stay on-device where the
encoder supports it. If the GPU can't decode a particular source, the job automatically retries with software
decode rather than failing. The Queue detail view shows a live CPU/GPU usage graph while a job
runs — GPU stats are read without any elevated privileges (per-process DRM fdinfo for
Intel/AMD, nvidia-smi for NVIDIA), so no extra container capability or compose change is
needed; hosts where no unprivileged source applies simply show "GPU stats unavailable".
NVIDIA (NVENC): install the NVIDIA Container Toolkit on the host and run with
--gpus all. You must also setNVIDIA_DRIVER_CAPABILITIES=compute,video,utility— without thevideocapability the NVENC library isn't injected and encoding fails withCannot load libnvidia-encode.so.1even thoughnvidia-smiworks.Intel (QSV / VA-API) and AMD (VA-API): map the render node and add the container to the host's
rendergroup:docker run -d --name optimisarr \ --device /dev/dri:/dev/dri \ --group-add "$(getent group render | cut -d: -f3)" \ ... ghcr.io/jellman86/optimisarr:dev
Use the matching Compose example: NVIDIA NVENC, Intel QSV, or Intel/AMD VA-API. A CPU-only file is also provided.
Development
Standards and commands live in CLAUDE.md. In short:
dotnet build Optimisarr.slnx # backend
dotnet test Optimisarr.slnx # tests
cd web && npm run check # frontend type/lint check
cd web && npm run dev # frontend dev server (proxies /api to :8787)
License
Optimisarr is licensed under the GNU General Public License v3.0. The published Docker image also bundles GPL-licensed FFmpeg distributions (jellyfin-ffmpeg and static-ffmpeg), which remain under their own licenses.
Project references
Install Optimisarr on Unraid in a few clicks.
Find Optimisarr in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/jellman86/optimisarr:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8787]/- Network
bridge- Shell
bash- Privileged
- false
Template configuration
Host port for the Optimisarr web interface (container listens on 8787).
- Target
- 8787
- Default
- 8787
- Value
- 8787
Persistent application state: SQLite database and configuration. Keep on fast storage.
- Target
- /config
- Default
- /mnt/user/appdata/optimisarr
- Value
- /mnt/user/appdata/optimisarr
One read-write root for your media, temporary output, and quarantine. Keeping them below one container mapping preserves atomic moves.
- Target
- /data
- Default
- /mnt/user/media
- Value
- /mnt/user/media
Temporary transcode output inside the storage root. A separate fast-scratch mount requires the verified cross-filesystem fallback.
- Target
- OPTIMISARR_WORK_DIR
- Default
- /data/.optimisarr/work
- Value
- /data/.optimisarr/work
Rollback originals inside the storage root so replacements can use atomic moves.
- Target
- OPTIMISARR_TRASH_DIR
- Default
- /data/.optimisarr/trash
- Value
- /data/.optimisarr/trash
Optional. When set, the administrative API and UI require this bearer token. Leave blank to rely on your network/reverse-proxy for access control.
- Target
- OPTIMISARR_ADMIN_TOKEN
Container timezone, e.g. Europe/London.
- Target
- TZ
- Default
- Europe/London
- Value
- Europe/London
User ID the app runs as (Unraid 'nobody' is 99). Files it creates use this owner.
- Default
- 99
- Value
- 99
Group ID the app runs as (Unraid 'users' is 100).
- Default
- 100
- Value
- 100
Permissions mask for files Optimisarr creates.
- Default
- 002
- Value
- 002
Optional. Map the render node for Intel QSV/VA-API or AMD VA-API hardware transcoding. Remove if the host has no /dev/dri. For NVIDIA NVENC, add '--runtime=nvidia' and the NVIDIA_* variables via Extra Parameters instead (see the setup guide).
- Target
- /dev/dri
- Default
- /dev/dri
- Value
- /dev/dri