2026-03-29, 03:22 PM
What is JellyDL
JellyDL is a self-hosted web UI that lets you browse your Jellyfin library and trigger on-demand background transcodes, then download the result as an MP4 file. It is made up of two parts that work together:
JellyDL (this UI) - A Vue 3 web app you run in Docker alongside Jellyfin
Transcode Download Plugin - A Jellyfin server plugin that does the actual transcoding via ffmpeg and exposes a REST API
Usage is simple:
![[Image: image.png]](https://i.postimg.cc/QCPSm7MJ/image.png)
After pressing download choose the transcode settings
![[Image: image.png]](https://i.postimg.cc/XYvdqq7g/image.png)
Once a download is started it appears in the Queue with live progress and an ETA:
![[Image: image.png]](https://i.postimg.cc/Rh9nBVDV/image.png)
When the transcode finishes the file is ready to save (If allowed a notificatin is sent):
![[Image: image.png]](https://i.postimg.cc/15qbTRZ8/image.png)
Why would you use it?
Jellyfin is great for streaming, but there are plenty of situations where you actually want a local copy of a file in a specific format rather than relying on a live stream:
Part 1 — Install the Transcode Download Plugin
This plugin must be installed on your Jellyfin server first. It is a standard Jellyfin plugin (C# / .NET 9).
Requirements
Install
Download the prebuilt DLL and
https://github.com/dave01945/Jellyfin.Pl...ses/latest
Download both
Then restart Jellyfin:
Configure the Plugin
Go to Dashboard → Plugins → TranscodeDownload and adjust settings to your needs:
Max Concurrent Jobs - 2 - Returns HTTP 429 when limit is exceeded
Output Directory - (empty) - Defaults to
Settings → Server URL in the UI: enter your Jellyfin server address directly (e.g.
You'll also need to log in with your Jellyfin credentials.
Limitations / Known Issues
Links
Feedback and issues welcome on GitHub. Happy to answer questions!
JellyDL is a self-hosted web UI that lets you browse your Jellyfin library and trigger on-demand background transcodes, then download the result as an MP4 file. It is made up of two parts that work together:
JellyDL (this UI) - A Vue 3 web app you run in Docker alongside Jellyfin
Transcode Download Plugin - A Jellyfin server plugin that does the actual transcoding via ffmpeg and exposes a REST API
Usage is simple:
- Browse your library in the JellyDL web UI
- Pick a title and choose your transcode settings (codec, resolution, audio, subtitles)
- The plugin starts an ffmpeg job in the background on your Jellyfin server
- Poll for progress, then download the finished MP4 when it's done
![[Image: image.png]](https://i.postimg.cc/QCPSm7MJ/image.png)
After pressing download choose the transcode settings
![[Image: image.png]](https://i.postimg.cc/XYvdqq7g/image.png)
Once a download is started it appears in the Queue with live progress and an ETA:
![[Image: image.png]](https://i.postimg.cc/Rh9nBVDV/image.png)
When the transcode finishes the file is ready to save (If allowed a notificatin is sent):
![[Image: image.png]](https://i.postimg.cc/15qbTRZ8/image.png)
Why would you use it?
Jellyfin is great for streaming, but there are plenty of situations where you actually want a local copy of a file in a specific format rather than relying on a live stream:
- Travelling or going offline — you want to take content with you on a laptop or phone where you won't have a reliable internet connection back to your server. JellyDL lets you grab a compressed, compatible MP4 before you leave.
- Incompatible formats — your media might be in a format or codec that a particular device or app won't play natively (e.g. HEVC on an older device, or MKV on something that only handles MP4). JellyDL lets you transcode it to something that will just work.
- Reducing file size — your originals might be large remuxes or high-bitrate encodes. JellyDL lets you produce a smaller, good-enough copy for a specific use without touching the original.
- Sharing a clip with someone — rather than giving someone access to your Jellyfin server, you can transcode and download a single file to share directly.
- Hardware-accelerated batch prep — if your server has a GPU, you can use JellyDL to quickly produce device-ready copies of content using NVENC, QSV, VA-API, or similar, offloading the heavy lifting to hardware.
Part 1 — Install the Transcode Download Plugin
This plugin must be installed on your Jellyfin server first. It is a standard Jellyfin plugin (C# / .NET 9).
Requirements
- Jellyfin
10.10.x
- ffmpeg available to Jellyfin (uses Jellyfin's configured path)
- For GPU acceleration: NVENC, QSV, VA-API, VideoToolbox, or AMF drivers installed on the host
Install
Download the prebuilt DLL and
meta.json directly from the GitHub releases page:https://github.com/dave01945/Jellyfin.Pl...ses/latest
Download both
Jellyfin.Plugin.TranscodeDownload.dll and meta.json, then copy them into a versioned folder inside your Jellyfin plugins directory:Code:
sudo mkdir -p /var/lib/jellyfin/plugins/TranscodeDownload_1.0.0.0/
sudo cp Jellyfin.Plugin.TranscodeDownload.dll \
meta.json \
/var/lib/jellyfin/plugins/TranscodeDownload_1.0.0.0/Then restart Jellyfin:
Code:
sudo systemctl restart jellyfinConfigure the Plugin
Go to Dashboard → Plugins → TranscodeDownload and adjust settings to your needs:
Max Concurrent Jobs - 2 - Returns HTTP 429 when limit is exceeded
Output Directory - (empty) - Defaults to
{TranscodePath}/downloads
Job Retention Minutes - 60 - How long completed/failed jobs are kept in memory
Keep Files After Eviction - false - If false, output files are deleted when a job is evicted
Hardware Acceleration - None - None, Nvenc, Qsv, Vaapi, VideoToolbox, Amf
VA-API Device - /dev/dri/renderD128 - Only applies when VA-API is selected
Note: Job state is held in memory and does not survive a Jellyfin restart.
Part 2 — Install JellyDL (the Web UI)
JellyDL ships as a Docker image and is the easiest way to get started.
Docker Compose (recommended, prebuilt image)
Create a docker-compose.yml:
Code:yaml
services:
jellydl:
image: ghcr.io/dave01945/jellydl:latest
ports:
- "8080:80"
environment:
JELLYFIN_INTERNAL_URL: http://jellyfin:8096
restart: unless-stopped
Replace http://jellyfin:8096 with the internal Docker network address of your Jellyfin container. If Jellyfin is on the same Docker network, the service name works directly.
Then start it:
Code:bash
docker compose up -d
Open your browser at: http://localhost:8080 (or your server's IP)
Configuration — Connecting to Jellyfin
JellyDL needs to know where your Jellyfin server is. You must configure it using one of these two methods — if neither is set, it will not work:
- JELLYFIN_INTERNAL_URL
environment variable (recommended with Docker): set this to your Jellyfin server's internal address (e.g. http://jellyfin:8096). All API calls will be proxied through JellyDL's built-in nginx, avoiding CORS issues entirely.http://192.168.1.100:8096). Calls go straight to Jellyfin — useful if you're not using Docker or the proxy isn't available.You'll also need to log in with your Jellyfin credentials.
Limitations / Known Issues
- Job state is in-memory only — a Jellyfin restart clears all jobs
- Only local file paths are supported as transcode input
- Text-based subtitle streams only for MP4 muxing (
mov_text)
- VA-API requires Jellyfin to have access to the configured render device
Links
- JellyDL UI: https://github.com/dave01945/JellyDL
- TranscodeDownload Plugin: https://github.com/dave01945/Jellyfin.Pl...deDownload
Feedback and issues welcome on GitHub. Happy to answer questions!
