eebette/jellyfin-tools

Non-plugin tools for helping manage a Jellyfin library.

104

stars

41

commits

Python

primary language

Aug 17, 2026

updated

README

Library Covers TL;DR

Install

pip install jellyfin-tools

Use

jellyfin-tools cover create --image /path/to/image.png --title Library

Overview

The purpose of this library is to share (non-plugin) tools I use for managing my Jellyfin instance and/or media library.

Currently, the only functionality of this library is to generate images with Jellyfin-like styling (shadow overlay and library title text) from source images. This was created because Jellyfin's included functionality to use a custom image as a library cover doesn't run its own styling library on the custom image.

Installation

Prerequisites: Python/pip

Stable

pip install jellyfin-tools

From Git Repo (Newer, Less Stable)

pip install git+https://github.com/eebette/jellyfin-tools

Manual Install

Download

git clone https://github.com/eebette/Jellyfin-Tools

Install

pip install ./Jellyfin-Tools

ℹ️ There are no system dependencies beyond Python. Image processing and text rendering are pure Pillow, which ships prebuilt wheels for every platform — no OpenCV, no libGL, nothing to apt-install.

Docker

No local Python needed — images are published to GitHub Container Registry for amd64 and arm64. Mount the directory containing your images at /data:

docker run --rm -v "$(pwd):/data" ghcr.io/eebette/jellyfin-tools cover create --image /data/art.png --title Movies

Or with the docker-compose.yml from this repository:

docker compose run --rm jellyfin-tools cover create --image /data/art.png --title Movies

The output lands next to the source image (or wherever --destination points, as long as it's under /data).

ℹ️ The container runs as root by default, so generated files will be root-owned. Add --user "$(id -u):$(id -g)" to the docker run command to write them as your own user.

Usage

Jellyfin Library Covers

jellyfin-tools cover create --image /path/to/image.png --title Library

This is a command for decorating an existing image to match the styling of a defualt library cover generated by Jellyfin or Emby. By default, it resizes the image, adds a shadow overlay, and enters the text in the correct font and color. Features of Jellyfin/Emby styling were manually reverse-matched by analyzing the image file that was output for a media collection in Jellyfin.

ℹ️ It is recommended to use a️n image which is already in 16:9 (1080p) aspect ratio

Destination option

You can use the --destination flag to provide a destination path to which to write the file. A path must be provided, but the file name is optional.

Styling Options

You can use the --shadow flag to give a 0.0-1.0 percentage transparency to the shadow overlay. Use 0 for no shadow darkening of the cover image. For example:

jellyfin-tools create --image /path/to/image.png --title Library --shadow 0

Custom font option

You can use the --font flag to provide a path to your own font file (any FreeType-supported format, e.g. .ttf or .otf) to use for the title text instead of the bundled Prima Sans Bold:

jellyfin-tools cover create --image /path/to/image.png --title Эфир --font /path/to/DejaVuSans-Bold.ttf

The bundled font only covers Latin characters, so this is needed for titles in other scripts — Cyrillic, Greek, etc.

❗ Text is rendered without complex-script shaping: scripts that require joining or reordering (Arabic, Hebrew with points, Indic scripts, Thai) will not render correctly even with a font that covers them.

Tools

cover

The Problem

Here's what a Jellyfin-generated library image looks like.

img_1.png

Unfortunately, this image is randomly generated from the backdrops of the media in the library, so if we get one we don't like, we just have to keep generating new ones until we get one that looks good.


Here's what a custom library image looks like when used as a custom library cover in Jellyfin:

img_1.png

There's no styling applied.

The Solution

1.gif

Call the jellyfin-tools cover create CLI in this package to apply styling to your image which will match Jellyfin's auto-generated styling. It will also resize the image for optimal use by Jellyfin in order to not take up any unnecessary storage on your server!

jellyfin-tools cover create --image /path/to/image.png --title Library

You can also generate multiple at the same time:

jellyfin-tools cover create --image /path/to/image/1.png /path/to/image/2.png --title Library1 Library2

❗ ️Note that you'll need to include quotes for a library title which includes spaces, or else the CLI doesn't know how to parse it correct. Example:

jellyfin-tools cover create --image /path/to/image/1.png /path/to/image/2.png --title Movies "Home Movies"

img_2.png

Much better!

Contributors

eebette

39 commits

mbeissinger

1 commits

psycotica0

1 commits

eebette/jellyfin-tools

Non-plugin tools for helping manage a Jellyfin library.

104

stars

41

commits

Python

primary language

Aug 17, 2026

updated

README

Library Covers TL;DR

Install

pip install jellyfin-tools

Use

jellyfin-tools cover create --image /path/to/image.png --title Library

Overview

The purpose of this library is to share (non-plugin) tools I use for managing my Jellyfin instance and/or media library.

Currently, the only functionality of this library is to generate images with Jellyfin-like styling (shadow overlay and library title text) from source images. This was created because Jellyfin's included functionality to use a custom image as a library cover doesn't run its own styling library on the custom image.

Installation

Prerequisites: Python/pip

Stable

pip install jellyfin-tools

From Git Repo (Newer, Less Stable)

pip install git+https://github.com/eebette/jellyfin-tools

Manual Install

Download

git clone https://github.com/eebette/Jellyfin-Tools

Install

pip install ./Jellyfin-Tools

ℹ️ There are no system dependencies beyond Python. Image processing and text rendering are pure Pillow, which ships prebuilt wheels for every platform — no OpenCV, no libGL, nothing to apt-install.

Docker

No local Python needed — images are published to GitHub Container Registry for amd64 and arm64. Mount the directory containing your images at /data:

docker run --rm -v "$(pwd):/data" ghcr.io/eebette/jellyfin-tools cover create --image /data/art.png --title Movies

Or with the docker-compose.yml from this repository:

docker compose run --rm jellyfin-tools cover create --image /data/art.png --title Movies

The output lands next to the source image (or wherever --destination points, as long as it's under /data).

ℹ️ The container runs as root by default, so generated files will be root-owned. Add --user "$(id -u):$(id -g)" to the docker run command to write them as your own user.

Usage

Jellyfin Library Covers

jellyfin-tools cover create --image /path/to/image.png --title Library

This is a command for decorating an existing image to match the styling of a defualt library cover generated by Jellyfin or Emby. By default, it resizes the image, adds a shadow overlay, and enters the text in the correct font and color. Features of Jellyfin/Emby styling were manually reverse-matched by analyzing the image file that was output for a media collection in Jellyfin.

ℹ️ It is recommended to use a️n image which is already in 16:9 (1080p) aspect ratio

Destination option

You can use the --destination flag to provide a destination path to which to write the file. A path must be provided, but the file name is optional.

Styling Options

You can use the --shadow flag to give a 0.0-1.0 percentage transparency to the shadow overlay. Use 0 for no shadow darkening of the cover image. For example:

jellyfin-tools create --image /path/to/image.png --title Library --shadow 0

Custom font option

You can use the --font flag to provide a path to your own font file (any FreeType-supported format, e.g. .ttf or .otf) to use for the title text instead of the bundled Prima Sans Bold:

jellyfin-tools cover create --image /path/to/image.png --title Эфир --font /path/to/DejaVuSans-Bold.ttf

The bundled font only covers Latin characters, so this is needed for titles in other scripts — Cyrillic, Greek, etc.

❗ Text is rendered without complex-script shaping: scripts that require joining or reordering (Arabic, Hebrew with points, Indic scripts, Thai) will not render correctly even with a font that covers them.

Tools

cover

The Problem

Here's what a Jellyfin-generated library image looks like.

img_1.png

Unfortunately, this image is randomly generated from the backdrops of the media in the library, so if we get one we don't like, we just have to keep generating new ones until we get one that looks good.


Here's what a custom library image looks like when used as a custom library cover in Jellyfin:

img_1.png

There's no styling applied.

The Solution

1.gif

Call the jellyfin-tools cover create CLI in this package to apply styling to your image which will match Jellyfin's auto-generated styling. It will also resize the image for optimal use by Jellyfin in order to not take up any unnecessary storage on your server!

jellyfin-tools cover create --image /path/to/image.png --title Library

You can also generate multiple at the same time:

jellyfin-tools cover create --image /path/to/image/1.png /path/to/image/2.png --title Library1 Library2

❗ ️Note that you'll need to include quotes for a library title which includes spaces, or else the CLI doesn't know how to parse it correct. Example:

jellyfin-tools cover create --image /path/to/image/1.png /path/to/image/2.png --title Movies "Home Movies"

img_2.png

Much better!

Contributors

eebette

39 commits

mbeissinger

1 commits

psycotica0

1 commits

Languages

Python

98.4%

Dockerfile

1.6%