quality-gate-encoder¶
quality-gate-encoder watches a Jellyfin library and adds a 720p copy beside every film and episode, so phones and remote viewers direct play the copy instead of making the server transcode live for each stream. Jellyfin's own answer is to transcode on the fly, once per viewer, every time; tools that re-encode a library usually replace the original. This keeps the original untouched and Jellyfin lists the copy as a second version of the same title. Start with Getting started, then check what you see when it worked. The Quality Gate plugin is optional: it caps chosen users at the 720p copy and tells the encoder which titles to make first.
-
One container, two mounts, a GPU device if you have one. Docker Compose and CLI, Intel and NVIDIA.
-
The log lines of a first run, the film's folder afterwards, and the Version menu in Jellyfin.
-
compare_encodes.pyreports which titles have their 720p copy, which are missing and which were skipped. -
Every variable and its default: codec, quality preset, symlink prefix, free-space floor, priority list.
In Jellyfin¶




The copy is named <title> - 720p, the pattern Jellyfin groups as versions of one item, so the library grid does not change and the film's page grows a Version menu. Jellyfin on a different host than the encoder gets a manifest instead of symlinks: Cross-host manifest mode.
What it does¶
- Keeps the original untouched and writes the copy to a destination folder you choose; the
- 720plink beside the original is what Jellyfin reads. - Encodes on an Intel iGPU (QSV) or an NVIDIA card (NVENC), decodes on the same GPU, and falls back to software by itself when the GPU refuses a file.
- Output in HEVC, H.264 or AV1; H.264 comes out as MP4 with AAC for the widest direct play. Switching codec never re-encodes what exists.
- Skips anything already 720p or lower. A restart on a finished library checks the destination instead of re-reading the originals.
- Encodes the titles your viewers are about to watch first when a priority list is written, by the Quality Gate plugin or anything else.
How it runs¶
- One Docker image,
drumsergio/quality-gate-encoder,linux/amd64only. Until 2027-03-31 every release is also published asdrumsergio/jellyfin-encoder; moving is a change of image name. - It polls the source tree instead of relying on inotify, so NFS and CIFS shares work. How it works has the pipeline and what a poll costs on a large share.
- Encodes go to a
.tmpfile and are renamed once verified, so Jellyfin never indexes a half-written file. - Orphan cleanup runs every six hours by default (
CLEANUP_INTERVAL_HOURS) behind the guards on Safety and cleanup: it refuses when the source looks wrong, and delete events are rate-limited.
What it does not do¶
- It does not change or remove an original. What it removes is limited to its own output: orphaned encodes in the destination and stale
- 720plinks. - It makes one size, 720p. There is no setting for another height.
- It does not run on ARM: the image is
linux/amd64only. - It does not decide which users see which version. That is the Quality Gate plugin.
Getting help¶
- No Version menu, every file logging
software decode, or a priority list that is ignored: the last paragraph of What you see when it worked, then FFmpeg log level and Priority list. Then open an issue with theConfig:line from the log and the lines around the error. - A security problem: follow the security policy, never a public issue.
- Sending a fix: Development. The plugin and the other Jellyfin tools: Related projects.
License¶
quality-gate-encoder is released under the GPL-3.0-or-later license.