media-preview-generator

media-preview-generator

Docker app from stevezau's Repository

Overview

Generate video preview thumbnails for Plex, Emby and Jellyfin with GPU acceleration support. One FFmpeg pass writes the right format for each server (Plex BIF bundle, Emby sidecar BIF, Jellyfin trickplay tiles).

This template seeds a Plex connection below; add Emby/Jellyfin servers (any mix) from the web UI after first start.

Features:

  • Web UI with setup wizard for easy configuration
  • Plex OAuth authentication (no manual token needed)
  • GPU acceleration (NVIDIA, Intel QuickSync, AMD)
  • Background processing with job queue
  • Real-time progress display
  • Scheduled generation via cron expressions
  • Browser notifications when jobs complete

The web interface is available at http://[IP]:8080 after starting the container.
A setup wizard will guide you through connecting to your Plex server.

IMPORTANT - NETWORKING:
If your Plex container uses a custom network (like br1 or macvlan), this container
must use the SAME network to communicate with Plex. Change the Network Type setting
to match your Plex container's network.

GPU SETUP — pick ONE path:

[Intel / AMD]
Pass /dev/dri through (already configured below — no further action needed).

[NVIDIA] — REQUIRED STEPS, in this order:

  1. Install the Nvidia-Driver plugin from Community Applications (bundles the NVIDIA driver and nvidia-container-toolkit needed for --runtime=nvidia).
  2. Add --runtime=nvidia to "Extra Parameters" on this template (NOT --gpus all).
  3. Set the NVIDIA_VISIBLE_DEVICES and NVIDIA_DRIVER_CAPABILITIES variables below.
  4. Optional: if your host has no Intel iGPU and the container fails with a /dev/dri error, remove the Intel GPU Device field.

Common error: "docker: Error response from daemon: AMD CDI spec not found"
-> You're using --gpus all on Unraid. Replace it with --runtime=nvidia.

Why NVIDIA_DRIVER_CAPABILITIES=all? The 'graphics' capability is required for
Dolby Vision Profile 5 thumbnails (libplacebo Vulkan tone-mapping).
'compute,video,utility' alone covers only CUDA/NVDEC and nvidia-smi.

Contributors Forks Stargazers Issues MIT License Docker Pulls codecov AI-Assisted

Media Preview Generator logo

Media Preview Generator

GPU-accelerated video preview thumbnail generation for Plex, Emby, and Jellyfin
Explore the docs

Quick Start · Report Bug · Request Feature


About

Generates video preview thumbnails for Plex, Emby, and Jellyfin. These are the small images you see when scrubbing through videos in any of those servers.

The Problem: Built-in preview generation has gaps depending on the server you run:

  • Plex generates thumbnails single-threaded on the CPU (no GPU support).
  • Emby has no GPU support for thumbnail generation at all.
  • Jellyfin does support hardware-accelerated trickplay, but it shares CPU/GPU with playback — and on a busy server that's resources you'd rather give to the player.

The Solution: This tool runs preview generation off the media server on a machine of your choosing, uses every GPU it finds, and processes files in parallel. When two or more servers contain the same file, FFmpeg runs only once — the result is then written out in each server's own expected format, automatically.

[!NOTE] This project was originally hand-written. Recent development is AI-assisted (Cursor + Claude). All changes are reviewed and tested.


Features

One FFmpeg pass, every server. Point it at Plex, Emby, Jellyfin — any mix, any number — and a single generation run writes the right output format to each (Plex BIF bundle, Emby sidecar BIF, Jellyfin trickplay tiles). See the multi-server guide for how the dispatcher routes one file to every server that owns it.

Automation that just works. Radarr / Sonarr / Tdarr / FileFlows webhooks, Plex direct (Plex Pass), Recently Added polling, cron & interval schedules — all share one universal inbound URL with vendor auto-detection. A 5-step backoff retry (30 s → 2 m → 5 m → 15 m → 60 m) handles files your server hasn't indexed yet. Source-aware dedup re-runs automatically when a file is swapped (e.g. a Sonarr/Radarr quality upgrade) and skips when nothing changed. Need to (re)generate something by hand? Manual Generation lets you search your servers by title — pick a show to cover every episode, or a movie, episode, folder, or single file — or browse your media tree, no path-typing required.

Hardware you already have. NVIDIA, AMD, Intel — per-GPU worker counts and FFmpeg threads, automatic in-place CPU retry if a codec fails on the GPU, and HDR / Dolby Vision tone mapping (including Profile 5 via libplacebo). A Previews Readiness panel on each server audits every flag that affects whether your previews actually show up, with one-click toggles and typed confirmation for destructive changes.


Screenshots

Dashboard showing connected Plex / Jellyfin / Emby servers, GPU workers, and job statistics Servers page with one card per Plex / Jellyfin / Emby server, each showing connection status and library count Settings — Processing Options card with per-GPU configuration for an NVIDIA TITAN RTX and Intel UHD 770, CPU workers, and thumbnail quality Automation page Triggers tab listing trigger sources for Sonarr / Radarr / Tdarr / per-vendor manual imports

Quick Start

Docker (Recommended)

docker run -d \
  --name media-preview-generator \
  --restart unless-stopped \
  -p 8080:8080 \
  --device /dev/dri:/dev/dri \
  -e PUID=1000 \
  -e PGID=1000 \
  -v /path/to/media:/media:ro \
  -v /path/to/plex/config:/plex:rw \
  -v /path/to/app/config:/config:rw \
  -v /etc/localtime:/etc/localtime:ro \
  stevezzau/media_preview_generator:latest

Replace /path/to/media, /path/to/plex/config, and /path/to/app/config with your actual paths.

Timezone: The /etc/localtime mount ensures log timestamps and scheduled jobs use your local time. Alternatively, use -e TZ=America/New_York (replace with your timezone).

Then open http://YOUR_IP:8080, retrieve the authentication token from container logs, and complete the setup wizard.

For Docker Compose, Unraid, and GPU-specific setup:


Installation

Method Best For Guide
Docker Most users, easy GPU setup Getting Started
Docker Compose Managed deployments docker-compose.example.yml
Unraid Unraid servers Getting Started — Unraid
  • Web UI only: The Docker image runs the web interface. There is no CLI; all configuration and job management is done via the web UI.
  • PyPI: The package is no longer published on PyPI; use Docker or install from source.

[!IMPORTANT] The Docker Hub image is published as stevezzau/media_preview_generator — the double z is the author's Docker Hub username (not a typo). stevezzau/media_preview_generator on Docker Hub.


GPU Support

Platform Supported GPUs Via
Linux (Docker) NVIDIA, AMD, Intel CUDA/NVENC, VAAPI, QuickSync
Windows (native) NVIDIA, AMD, Intel CUDA, D3D11VA
macOS (native) Apple Silicon, Intel VideoToolbox
Linux / Windows / macOS No GPU CPU workers only

On Docker Desktop (Windows/WSL2 and macOS) the container runs inside a Linux VM, so D3D11VA and VideoToolbox aren't reachable — Docker on those platforms processes on CPU. For GPU acceleration on Windows or macOS, install from source.

See Getting Started — GPU Acceleration for per-vendor setup, tuning, and detection. Detected GPUs are shown in the web UI under Settings or Setup.

GPU + CPU Fallback

CPU fallback is automatic and built into every GPU worker — there is no separate "fallback" pool to configure. If a file fails on the GPU for any reason (unsupported codec, hardware error, driver crash), the same worker automatically retries it on the CPU and the dashboard shows a yellow CPU fallback badge so you know it happened.

If you have a lot of content that never decodes on the GPU, raise CPU Workers above 0 so that those files route straight to dedicated CPU workers instead of blocking a GPU worker each time.

See Automatic GPU → CPU Fallback for details.


Documentation

Document What's there
Documentation Hub Pick the right doc for your task
Getting Started Install with Docker, GPU setup, Unraid, networking
Guides Web UI, schedules, webhooks, HDR handling, troubleshooting
Reference Config options, env vars, REST API, WebSocket events
FAQ Common questions about setup, performance, and compatibility

Built With

Python Docker FFmpeg Flask Gunicorn


Contributing

Contributions are welcome. See CONTRIBUTING.md for local setup, tests, code style, and the PR workflow.


License

Distributed under the MIT License. See LICENSE for details.


Acknowledgments

  • Plex for the media server
  • FFmpeg for video processing
  • LinuxServer.io for the Docker base image
  • Rich for beautiful terminal output
  • All contributors and users

Made with care by stevezau

Star this repo if you find it useful!

Install media-preview-generator on Unraid in a few clicks.

Find media-preview-generator 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.

Open the Apps tab on your Unraid server Search Community Apps for media-preview-generator Review the template variables and paths Click Install

Download Statistics

18,923
Total Downloads

Related apps

Explore more like this

Explore all

Details

Repository
stevezzau/media_preview_generator:latest
Last Updated2026-06-29
First Seen2026-05-27

Runtime arguments

Web UI
http://[IP]:[PORT:8080]/
Network
bridge
Shell
bash
Privileged
false
Extra Params
--restart=unless-stopped

Template configuration

Web UI PortPorttcp

Port for the web interface

Target
8080
Default
8080
Value
8080
Plex URLVariable

URL to your Plex Media Server (use IP address, not localhost)

Target
PLEX_URL
Default
http://192.168.1.100:32400
Plex TokenVariable

Plex authentication token. Find it at: https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ (or use OAuth via Web UI)

Target
PLEX_TOKEN
Media PathPathro

Path to your media files on Unraid (read-only)

Target
/media
Default
/mnt/user/media
Value
/mnt/user/media
Plex Data PathPathrw

Path to Plex application data where previews will be stored

Target
/plex
Default
/mnt/user/appdata/plex/Library/Application Support/Plex Media Server
Value
/mnt/user/appdata/plex/Library/Application Support/Plex Media Server
Config PathPathrw

Path to store configuration, schedules, and job history

Target
/config
Default
/mnt/user/appdata/media-preview-generator
Value
/mnt/user/appdata/media-preview-generator
Local Videos PathVariable

How this container sees media (usually /media)

Target
PLEX_LOCAL_VIDEOS_PATH_MAPPING
Default
/media
Value
/media
Plex Videos PathVariable

How Plex sees media (if different from this container's path)

Target
PLEX_VIDEOS_PATH_MAPPING
Frame Interval (seconds)Variable

Seconds between each preview frame (default: 5). Migrated to settings.json on first start.

Target
PLEX_BIF_FRAME_INTERVAL
Default
5
Value
5
Thumbnail QualityVariable

Preview image quality 1-10, higher = better quality but larger files (default: 4). Migrated to settings.json on first start.

Target
THUMBNAIL_QUALITY
Default
4
Value
4
CPU ThreadsVariable

Number of parallel CPU workers for fallback (default: 1). Migrated to settings.json on first start. GPU config (enable/disable, workers per GPU) is in Web UI Settings.

Target
CPU_THREADS
Default
1
Value
1
Auth Token OverrideVariable

Optional: Override the authentication token. If empty, use the token set during the setup wizard (or auto-generated if skipped). Left unmasked because Unraid's masked password fields can silently fail to save the value (issue #263).

Target
WEB_AUTH_TOKEN
Web PortVariable

Internal port for web server (usually matches Web UI Port)

Target
WEB_PORT
Default
8080
Value
8080
PUIDVariable

User ID for file permissions (99 = nobody on Unraid)

Default
99
Value
99
PGIDVariable

Group ID for file permissions (100 = users on Unraid)

Default
100
Value
100
UMASKVariable

File permission mask

Default
022
Value
022
Intel GPU DeviceDevice

Pass through Intel GPU for QuickSync acceleration

Target
/dev/dri
Default
/dev/dri
Value
/dev/dri
NVIDIA Driver Capabilities (requires --runtime=nvidia in Extra Parameters)Variable

REQUIRES --runtime=nvidia in Extra Parameters — without it, this variable is ignored and the container will either fail to start (e.g. 'AMD CDI spec not found') or fall back to CPU. Recommended value: 'all' (includes the 'graphics' capability needed for Dolby Vision Profile 5 thumbnails via libplacebo Vulkan tone-mapping). 'compute,video,utility' alone covers only CUDA/NVDEC and will NOT give you DV5 support.

Target
NVIDIA_DRIVER_CAPABILITIES
Default
all
Value
all
NVIDIA Visible Devices (requires --runtime=nvidia in Extra Parameters)Variable

REQUIRES --runtime=nvidia in Extra Parameters — without it, this variable is ignored. Which NVIDIA GPUs to expose to the container, e.g. 'all' or a specific GPU UUID. Do NOT use --gpus all on Unraid; that triggers CDI resolution and fails with 'AMD CDI spec not found'.

Target
NVIDIA_VISIBLE_DEVICES
Log LevelVariable

Logging level: DEBUG, INFO, WARNING, ERROR

Target
LOG_LEVEL
Default
INFO
Value
INFO