GPU-accelerated video preview thumbnail generation for Plex, Emby, and Jellyfin
Explore the docs
Quick Start
·
Report Bug
·
Request Feature
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.
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.
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.
![]() |
![]() |
![]() |
![]() |
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:latestReplace /path/to/media, /path/to/plex/config, and /path/to/app/config with your actual paths.
Timezone: The
/etc/localtimemount 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:
| 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.
| 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.
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.
| 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 |
Contributions are welcome. See CONTRIBUTING.md for local setup, tests, code style, and the PR workflow.
Distributed under the MIT License. See LICENSE for details.
- 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!



