No description
  • Python 90.1%
  • HTML 8.9%
  • Dockerfile 0.7%
  • Shell 0.3%
Find a file
Tobias Hertel a8d6dfc4c6
All checks were successful
CI / test (push) Successful in 22s
Build and push container image / build-and-push (push) Successful in 2m13s
fix: strip HDR metadata from SDR outputs
2026-09-13 07:51:03 +02:00
.forgejo/workflows fix: provide remote worker fixtures in forgejo validation 2026-09-12 22:34:58 +02:00
app fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
config fix: keep remote transcodes alive during api outages 2026-09-12 23:54:01 +02:00
docs add authenticated settings foundation 2026-08-16 18:43:53 +02:00
scripts added progress display and macos videotoolbox 2026-08-16 16:21:51 +02:00
tests fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
.dockerignore simplified config dirs 2026-08-16 19:39:53 +02:00
.env.example fix: keep remote transcodes alive during api outages 2026-09-12 23:54:01 +02:00
.env.macos.example docs: publish Optimizarr 0.10 deployment model 2026-09-12 20:10:00 +02:00
.gitattributes Initial commit 2026-08-16 14:35:45 +02:00
.gitignore Update .gitignore 2026-08-16 20:25:51 +02:00
CHANGELOG.md fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
compose.dev.yml fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
compose.nvidia.yml docs: publish Optimizarr 0.10 deployment model 2026-09-12 20:10:00 +02:00
compose.qsv.yml docs: publish Optimizarr 0.10 deployment model 2026-09-12 20:10:00 +02:00
compose.worker.yml fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
compose.yml fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
Dockerfile feat: add API workers and dynamic HDR processing 2026-09-12 20:09:53 +02:00
pyproject.toml fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00
README.md fix: strip HDR metadata from SDR outputs 2026-09-13 07:51:03 +02:00

Optimizarr v0.13.2

Optimizarr erzeugt über eine lease-basierte Multi-Worker-Queue optimierte Medienableitungen für Radarr-/Sonarr-Bibliotheken. Eingabemedien werden ausschließlich read-only eingebunden. Ein Worker encodiert zuerst lokal, lädt anschließend in eine versteckte Datei im Zielverzeichnis und die API veröffentlicht diese erst nach gültiger Lease per atomarem Rename.

Schnellstart

cp config/config.example.yml config/config.yml
docker compose -f compose.yml -f compose.qsv.yml up -d --build

Das Dashboard läuft standardmäßig auf http://localhost:8097. Beim ersten Start liegt der einmalige Admin-Code unter config/runtime/setup.token. Einstellungen, Profile, Regeln, Sprachfilter und Worker werden danach in der Administration verwaltet.

Der lokale Worker erhält automatisch ein Token in einem ausdrücklich deklarierten worker-auth-Volume. Die Anwendungseinstellungen bleiben vollständig unter /config; es gibt keinen zusätzlichen /data-Mount. Redis wird im Standard-Compose nicht am Host veröffentlicht.

Remote-Worker unterscheiden einen bestätigten Lease-Verlust von einer vorübergehend nicht erreichbaren API. Während einer Netzwerk- oder VPN-Unterbrechung laufen ausschließlich worker-lokale Transcodes und Prüfungen weiter; Upload und atomarer Publish warten auf eine wieder erreichbare API und eine bestätigte Lease. queue.worker_outage_grace_seconds hält den Job standardmäßig 15 Minuten exklusiv, bevor ein tatsächlich ausgefallener Worker ersetzt werden darf.

Architektur

Radarr / Sonarr ──webhook──> Optimizarr API ──> Redis (intern)
                               ▲       │
                          HTTPS/API    │ atomarer Commit
                               │       ▼
                         Worker ──upload──> /optimized
                           │
                     lokales /work

Worker kennen weder Redis-Zugangsdaten noch den Settings-Schlüssel oder Integrations-Secrets. Sie benötigen nur:

  • OPTIMIZARR_API_URL
  • eine read-only Token-Datei über OPTIMIZARR_WORKER_TOKEN_FILE
  • read-only Quellmounts, den gemeinsamen Output-Mount und lokales /work

Für einen entfernten Worker zuerst in der Administration einen Worker anlegen, das einmalig angezeigte Token in eine Datei schreiben und compose.worker.yml mit OPTIMIZARR_WORKER_TOKEN_PATH, den Medienpfaden und OPTIMIZARR_API_URL starten. HTTP ist für ein abgeschottetes LAN möglich; HTTPS wird empfohlen.

OPTIMIZARR_WORKER_API_TIMEOUT_SECONDS steuert den normalen API-Timeout (Standard: 15 Sekunden). Fortschrittsmeldungen verwenden mit OPTIMIZARR_WORKER_PROGRESS_TIMEOUT_SECONDS bewusst einen kürzeren Timeout von 2 Sekunden, damit ein unterbrochener Tunnel den FFmpeg-Ausgabepuffer nicht ausbremst.

Bestehende Medien einlesen

Unter Administration → Medien einlesen kann vor dem Start eine alphabetisch sortierte Vorschau für Filme, Serien oder beide Medientypen geladen werden. Das Standardlimit ist fünf. Für die ersten 25 Einträge prüft der Preflight die Quelle und zeigt Profile, Zielpfade, geschätzten lokalen Speicherbedarf, geeignete Worker sowie den erwarteten Decoder-/Filter-/Encoder-Pfad. CPU-Tonemapping und fehlende kompatible Worker werden vor dem Einreihen hervorgehoben. Aktive Jobs und unveränderte Medien mit vollständigen, zur aktuellen Profilkonfiguration passenden Ausgaben werden als Duplikate übersprungen.

Der Kommandozeilenmodus python -m app bootstrap --dry-run --limit 5 bleibt für Wartungsarbeiten verfügbar.

Profile und HDR

Die Standardprofile heißen:

  • 4k-hevc-hdr: HEVC Main10, 10 Mbit/s Ziel, 812 Mbit/s Begrenzung
  • 1080p-hevc-hdr: HEVC Main10, 6 Mbit/s Ziel, 58 Mbit/s Begrenzung
  • 1080p-h264-sdr
  • 720p-h264-sdr

Audio- und Untertitelsprachen lassen sich je Profil als ISO-639-Allowlist führen. Der optionale Modus Beste Hauptspur je Sprache priorisiert verlustfreie und objektbasierte Formate, Kanalzahl und Bitrate. Er kann die beste Originalspur behalten und daraus zusätzlich E-AC-3 5.1 mit standardmäßig 640 kbit/s sowie AAC Stereo mit 192 kbit/s erzeugen. Passende Spuren werden nicht dupliziert und Audio wird niemals hochgemischt. TrueHD/Atmos bleibt in der kopierten Originalspur erhalten; Kompatibilitätsspuren enthalten einen klassischen kanalbasierten Downmix. Kommentar- und Audiodeskriptionsspuren sind separat zuschaltbar.

Ohne audio.selection: best_per_language bleibt das bisherige Verhalten unverändert. Der Bootstrap-Preflight zeigt den geplanten Audiotrack-Aufbau und berücksichtigt ihn ebenso wie die Worker-Speicherreservierung. Nach dem Encode werden Codec, Sprache und Kanalzahl jeder geplanten Spur vor dem Publish validiert.

Das Image enthält die fest gepinnten quietvoid-Werkzeuge dovi_tool 2.3.4 und hdr10plus_tool 1.7.2. Für MKV/HEVC-Profile kann Dolby Vision beziehungsweise HDR10+ auf preserve oder drop gestellt werden. Die Erhaltung ist strikt: fehlt ein Werkzeug, stimmt die Frame-Timeline nicht oder lässt sich das Ergebnis nicht erneut validieren, schlägt der Job sichtbar fehl. Profil 7 wird zu einer Single-Layer-P8.1-RPU konvertiert, Profil 5 zu P8.1 und P8.1 wird neu injiziert. Skalierte dynamische HDR-Ausgaben werden derzeit bewusst abgelehnt, weil Level-5-Aktivflächen nicht sicher proportional angepasst werden können; das 1080p-HDR-Standardprofil verwirft deshalb dynamische Metadaten.

Vor dem Upload durchläuft jede fertige Datei ein verbindliches Validierungs-Gate. Es prüft Dekodierbarkeit an verteilten Stichproben, schwarze Ausgaben, Codec, Auflösung, Laufzeit, Audio-/Untertitelanzahl sowie HDR-Signalisierung. Nur bestandene Outputs gelangen in den weiterhin Lease-geschützten atomaren Publish-Schritt. Pipeline, Fallback-Grund und Prüfbericht bleiben im Job und im Output-State sichtbar. Gleichzeitige Jobs reservieren ihren geschätzten /work-Bedarf atomar; worker.work_reserve_bytes hält standardmäßig zusätzlich 1 GiB frei.

Wichtige Mounts

OPTIMIZARR_CONFIG_PATH=/mnt/user/appdata/optimizarr/config
OPTIMIZARR_MOVIES_PATH=/mnt/user/media/movies
OPTIMIZARR_TV_PATH=/mnt/user/media/tv
OPTIMIZARR_OUTPUT_PATH=/mnt/user/media/optimized
OPTIMIZARR_WORK_PATH=/mnt/cache/appdata/optimizarr/work
OPTIMIZARR_API_PORT=8097

Quellen bleiben :ro. /work sollte lokal und schnell sein. /optimized muss für API und Worker unter demselben kanonischen Pfad sichtbar sein. Nur die API darf eine versteckte Upload-Datei final veröffentlichen.

Upgrade von 0.9

Beim API-Start wird der Redis-Namensraum einmalig von plex-optimizer:* nach optimizarr:* migriert. Sind beide Namensräume befüllt, bricht der Start absichtlich ab. Standardprofil-IDs und deren Referenzen werden migriert; selbst angelegte IDs bleiben unverändert. Bestehende Ableitungsdateien werden weder verschoben noch gelöscht. Vor dem Upgrade Redis, /config/runtime und Compose sichern und alte Worker stoppen.

Alte Variablennamen werden nur beim Upgrade gelesen. Neue Deployments sollten ausschließlich OPTIMIZARR_* verwenden.

Entwicklung

python -m pytest -q
python -m py_compile app/*.py
docker compose -f compose.yml config >/dev/null
docker compose -f compose.yml -f compose.qsv.yml config >/dev/null
docker compose -f compose.yml -f compose.nvidia.yml config >/dev/null
docker build --target test --progress plain .
docker build -t optimizarr:test .

Fehlerdetails erscheinen im Dashboard-Tooltip. Terminale Jobs können neu gestartet und Jobs in jedem Zustand entfernt werden. Bei aktiven Jobs widerruft das Entfernen zuerst die Lease; FFmpeg wird beendet und Worker-Staging sowie unvollständige Uploads werden bereinigt, ohne Quellmedien anzufassen.