Add current blog content

This commit is contained in:
Bill Thornton 2022-08-18 12:18:28 -04:00
parent 7cb5d133a2
commit f729bb230b
62 changed files with 7679 additions and 0 deletions

25
docs/general/about.md Normal file
View File

@ -0,0 +1,25 @@
---
uid: about
title: About
---
# About
Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it. We welcome anyone who is interested in joining us in our quest!
Jellyfin seeks to continue development of the original Emby project with a Free Software ethos. It is committed to bringing all its users access to the best possible Media System, developed entirely by a community of volunteers who contribute code, documentation, translations, and support to the project.
The Jellyfin project was started in early December 2018 as a result of Emby's decision to take their 3.6 release closed-source, as well as various philosophical differences with the core developers. Jellyfin seeks to be the free software alternative to Emby and Plex to provide media management and streaming from a dedicated server to end-user devices.
You can find our main repository on [GitHub](https://github.com/jellyfin/jellyfin) as well as our [organization](https://github.com/jellyfin) page.
## Core Team
[Joshua Boniface (joshuaboniface)](https://github.com/joshuaboniface)<br/>
[Anthony Lavado (anthonylavado)](https://github.com/anthonylavado)<br/>
[Andrew Rabert (nvllsvm)](https://github.com/nvllsvm)<br/>
[Bond-009](https://github.com/Bond-009)<br/>
[dkanada](https://github.com/dkanada)<br/>
[Claus Vium (cvium)](https://github.com/cvium)<br/>
[Bill Thornton (thornbill)](https://github.com/thornbill)<br/>
[Cody Robibero](https://github.com/crobibero)<br/>

View File

@ -0,0 +1,117 @@
---
uid: admin-building
title: Building from Source
---
<!-- markdownlint-disable MD029 ol-prefix -->
# Source
As an alternative to using [binary packages](xref:admin-installing), you can build Jellyfin from source.
Jellyfin supports several methods of building for different platforms and instructions for all supported platforms are below.
All package builds begin with these two steps:
1. Clone the repository.
```sh
git clone https://github.com/jellyfin/jellyfin.git
cd jellyfin
```
2. Initialize the submodules.
```sh
git submodule update --init
```
## Container image
1. Build the container image using Docker or Podman.
```sh
docker build -t $USERNAME/jellyfin .
```
or
```sh
podman build -t $USERNAME/jellyfin .
```
2. Run Jellyfin in a new container using Docker or Podman from the built container image.
```sh
docker run -d -p 8096:8096 $USERNAME/jellyfin
```
or
```sh
podman run -d -p 8096:8096 $USERNAME/jellyfin
```
## Linux or MacOS
3. Use the included `build` script to perform builds.
```sh
./build --help
./build --list-platforms
./build <platform> all
```
4. The resulting archives can be found at `../bin/<platform>`.
> [!NOTE]
> This will very likely be split out into a separate repository at some point in the future.
## Windows
3. Install dotnet SDK 6.0 from [Microsoft's Website](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) and [install Git for Windows](https://gitforwindows.org/).
You must be on Powershell 3 or higher.
4. From Powershell set the execution policy to unrestricted.
```powershell
set-executionpolicy unrestricted
```
5. If you are building a version of Jellyfin newer than 10.6.4, you will need to download the build script from a separate repository.
```powershell
git clone https://github.com/jellyfin/jellyfin-server-windows.git windows
```
6. Run the Jellyfin build script.
```powershell
windows\build-jellyfin.ps1 -verbose
```
* The `-WindowsVersion` and `-Architecture` flags can optimize the build for your current environment; the default is generic Windows x64.
* The `-InstallLocation` flag lets you select where the compiled binaries go; the default is `$Env:AppData\Jellyfin-Server\`.
* The `-InstallFFMPEG` flag will automatically pull the stable `ffmpeg` binaries appropriate to your architecture (x86/x64 only for now) from [BtbN](https://github.com/BtbN/FFmpeg-Builds/releases) and place them in your Jellyfin directory.
* The `-InstallNSSM` flag will automatically pull the stable `nssm` binary appropriate to your architecture (x86/x64 only for now) from [NSSM's Website](https://nssm.cc/) and place it in your Jellyfin directory.
7. (Optional) Use [NSSM](https://nssm.cc) to configure Jellyfin to run as a service.
8. Jellyfin is now available in the default directory, or whichever directory you chose.
* Start it from PowerShell.
```powershell
&"$env:APPDATA\Jellyfin-Server\jellyfin.exe"
```
* Start it from CMD.
```cmd
%APPDATA%\Jellyfin-Server\jellyfin.exe
```
> [!NOTE]
> This will very likely be split out into a separate repository at some point in the future.

View File

@ -0,0 +1,99 @@
---
uid: admin-configuration
title: Configuration
---
# Configuration
There are several entry points available for administrators to manage the configuration of their server. This section aims to outline all those configuration methods, explain what options are available, and what each option does.
> [!NOTE]
> The configuration options here are distinct from the [runtime settings](xref:server-settings) available from the Administrator Dashboard in the web client. The configuration options here are generally meant to be static and set before starting the server.
## Command Line Options
Documentation for the available command line options can be obtained by adding the `--help` flag when running the Jellyfin executable.
## Server Paths
The file paths used by the server are determined according the rules outline below. In general, the [XDG specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) is followed by default for non-Windows systems.
### Data Directory
This is the directory that will hold all Jellyfin data, and is also used as a default base directory for some other paths below. It is set from the following sources in order of decreasing precedence.
1. Command line option `--datadir`, if specified
2. Environment variable `JELLYFIN_DATA_DIR`, if specified
3. `<%APPDATA%>/jellyfin`, if running on Windows
4. `$XDG_DATA_HOME/jellyfin`, if `$XDG_DATA_HOME` exists
5. `$HOME/.local/share/jellyfin`
### Configuration Directory
This is the directory containing the server configuration files. It is set from the following sources in order of decreasing precedence.
1. Command line option `--configdir`, if specified
2. Environment variable `JELLYFIN_CONFIG_DIR`, if specified
3. `<Data Directory>/config`, if it exists or if running on Windows
4. `$XDG_CONFIG_HOME/jellyfin` if `$XDG_CONFIG_HOME` exists
5. `$HOME/.config/jellyfin`
### Cache Directory
This is the directory containing the server cache. It is set from the following sources in order of decreasing precedence.
1. Command line option `--cachedir`, if specified
2. Environment variable `$JELLYFIN_CACHE_DIR`, if specified
3. `<Data Directory>/cache`, if Windows
4. `$XDG_CACHE_HOME/jellyfin` if `$XDG_CACHE_HOME` exists
5. `$HOME/.cache/jellyfin`
### Web Directory
This is the directory containing the built files from a [web client](https://github.com/jellyfin/jellyfin-web) release. It is set from the following sources in order of decreasing precedence.
1. Command line option `--webdir`, if specified
2. Environment variable `$JELLYFIN_WEB_DIR`, if specified
3. `<Binary Directory>/jellyfin-web`, where `<Binary Directory>` is the directory containing the Jellyfin executable
> [!NOTE]
> This setting is only used when the server is configured to host the web client. See the `hostwebclient` option in the [Main Configuration Options](#main-configuration-options) section below for additional details.
### Log Directory
This is the directory where the Jellyfin logs will be stored. It is set from the following sources in order of decreasing precedence.
1. Command line option `--logdir`, if specified
2. Environment variable `$JELLYFIN_LOG_DIR`, if specified
3. `<Data Directory>/log`
## Main Configuration
The main server configuration is built upon the ASP .NET [configuration framework](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1), which provides a tiered approach to loading configuration. The base directory to locate the configuration files is set using the [configuration directory](#configuration-directory) setting. The configuration sources are as follows, with later sources having higher priority and overwriting the values in earlier sources.
1. **Hard-coded default values**: These defaults are specified in the Jellyfin [source code](https://github.com/jellyfin/jellyfin/blob/master/Emby.Server.Implementations/ConfigurationOptions.cs) and cannot be changed.
2. **Default logging configuration file** (`logging.default.json`): This file should not be modified manually by users. It is reserved by the server to be overwritten with new settings on each new release.
3. **System-specific logging configuration file** (`logging.json`): This is the file you should change if you want to have a custom logging setup. Jellyfin uses the [Serilog](https://serilog.net/) logging framework, and you can read about the configuration options available in their [documentation](https://github.com/serilog/serilog-settings-configuration).
> [!NOTE]
> This file can be changed at runtime, which will automatically reload the configuration and apply the changes immediately.
4. **Environment variables**: The [documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#environment-variables) provided by Microsoft explains how to set these configuration options via environment variables. Jellyfin uses its own custom `JELLYFIN_` prefix for these variables. For example, to set a value for the `HttpListenerHost:DefaultRedirectPath` setting, you would set a value for the `JELLYFIN_HttpListenerHost__DefaultRedirectPath` environment variable.
5. **Command line options**: Certain command line options are loaded into the configuration system and have the highest priority. The following command line options are mapped to associated configuration options.
- `--nowebclient` sets the `hostwebclient` configuration setting to false
- `--plugin-manifest-url` sets a value for the `InstallationManager:PluginManifestUrl` configuration setting
### Main Configuration Options
This section lists all the configuration options available and explains their function.
|Key|Default Value|Description|
|---|-------------|-----------|
|`hostwebclient`|`True`|Set to `True` if the server should host the web client.|
|`HttpListenerHost:DefaultRedirectPath`|`"web/index.html"` if `hostwebclient` is true; `"swagger/index.html"` if `hostwebclient` is false|The default redirect path to use for requests where the URL base prefix is invalid or missing|
|`InstallationManager:PluginManifestUrl`|`"https://repo.jellyfin.org/releases/plugin/manifest.json"`|The URL for the plugin repository JSON manifest.|
|`FFmpeg:probesize`|`"1G"`|Value to set for the FFmpeg `probesize` format option. See the FFmpg [documentation](https://ffmpeg.org/ffmpeg-formats.html#Format-Options) for more details.|
|`FFmpeg:analyzeduration`|`"200M"`|The value to set for the FFmpeg `analyzeduration` format option. See the FFmpg [documentation](https://ffmpeg.org/ffmpeg-formats.html#Format-Options) for more details.|
|`playlists:allowDuplicates`|`True`|Whether playlists should allow duplicate items or automatically filter out duplicates.|
|`PublishedServerUrl`|Server Url based on primary IP address|The Server URL to publish in udp Auto Discovery response.|

View File

@ -0,0 +1,561 @@
---
uid: admin-hardware-acceleration
title: Hardware Acceleration
---
# Hardware Acceleration
Jellyfin supports [hardware acceleration (HWA) of video encoding/decoding using FFMpeg](https://trac.ffmpeg.org/wiki/HWAccelIntro).
FFMpeg and Jellyfin can support multiple hardware acceleration implementations such as Intel Quicksync (QSV), AMD AMF and NVIDIA NVENC/NVDEC through Video Acceleration APIs.
* [VA-API](https://en.wikipedia.org/wiki/Video_Acceleration_API) is a Video Acceleration API that uses [libva](https://github.com/intel/libva/blob/master/README.md) to interface with local drivers to provide HWA.
* [QSV](https://trac.ffmpeg.org/wiki/Hardware/QuickSync) uses a modified (forked) version of VA-API and interfaces it with [libmfx](https://github.com/intel/media-driver/blob/master/README.md) and their proprietary drivers [(list of supported processors for QSV)](https://ark.intel.com/content/www/us/en/ark.html#@Processors).
OS | Recommended HW Acceleration
------- | -------------
Linux | QSV, NVENC, AMF, VA-API
Windows | QSV, NVENC, AMF
MacOS | VideoToolbox
RPi | V4L2
[Graphics Cards comparison using HWA](https://www.elpamsoft.com/?p=Plex-Hardware-Transcoding)
Based on hardware vendor:
Vendor | Supported HW Acceleration
------- | -------------
NVIDIA | NVENC
AMD | AMF, VA-API
Intel | QSV, VA-API
Apple | VideoToolbox
RPi | V4L2
## Enabling Hardware Acceleration
Hardware acceleration options can be found in the Admin Dashboard under the **Transcoding** section of the **Playback** tab.
Select a valid hardware acceleration option from the drop-down menu, indicate a device if applicable, and check `Enable hardware encoding` to enable encoding as well as decoding, if your hardware supports this.
The hardware acceleration is available immediately for media playback. No server restart is required.
On Linux you can check available GPU using:
```sh
lspci -nn | egrep -i "3d|display|vga"
```
or using `lshw`:
```sh
lshw -C display
```
## H.264 / AVC 10-bit videos
The hardware decoding of H.264 10-bit aka High10 profile video is not supported by any Intel, AMD or NVIDIA GPU.
Please consider upgrading these videos to HEVC 10-bit aka Main10 profile if you want to offload your CPU usage during transcoding.
## Intel Gen9 and Gen11+ iGPUs
> [!NOTE]
> The Intel [Guc/Huc firmware](https://01.org/linuxgraphics/downloads/firmware) must be enabled for optional Low-Power encoding (pre-Gen11 only supports Low-Power H.264).
Instructions:
* ArchLinux: [Arch Wiki](https://wiki.archlinux.org/title/intel_graphics#Enable_GuC_/_HuC_firmware_loading)
* Debian/Ubuntu: [Brainiarc7's gist](https://gist.github.com/Brainiarc7/aa43570f512906e882ad6cdd835efe57)
> [!WARNING]
> For **Jasper Lake** and **Elkhart Lake** chips (such as `N5095`, `N6005` and `J6412`), Low-Power encoding **must** be enabled.
> There's a known kernel issue on these chips in **linux 5.15** that comes with Ubuntu 22.04 LTS preventing you from using Low-Power. You may need to upgrade kernel for this.
> The linux-firmware support is **not included** in Ubuntu 20.04.3 LTS.
> Any Ubuntu from 21.10 **does include** the required drivers.
## Supported Acceleration Methods
> [!Important]
> In Jellyfin 10.8 full hardware-accelerated filtering (scaling, deinterlacing, tone-mapping and subtitle burn-in) on Intel, AMD and NVIDIA hardware are available.
>
> **jellyfin-ffmpeg version 4.4.1-2 or higher is required**, using an older or original version of FFmpeg may disable some hardware filtering improvements.
### VA-API
> [!NOTE]
> Intel iGPU and AMD GPU only.
A List of supported codecs for VA-API can be found [on the Archlinux wiki](<https://wiki.archlinux.org/index.php/Hardware_video_acceleration#Comparison_tables>).
> [!WARNING]
> As of **Jellyfin 10.8** the official Docker image uses Debian 11 which has a compatible version of Mesa for **AMD GPU HEVC** decoding.
>
> Earlier images do not provide a compatible version of Mesa.
### Hardware acceleration on Raspberry Pi 3 and 4
> [!WARNING]
> As of **Jellyfin 10.8** hardware acceleration on Raspberry Pi via `OpenMAX OMX` was dropped and is no longer available.
>
> This decision was made because Raspberry Pi is currently migrating to a `V4L2` based hardware acceleration, which is already available in Jellyfin but does not support all features other hardware acceleration methods provide due to lacking support in FFmpeg.
> Jellyfin will fallback to software de- and encoding for those usecases.
>
> The current state of hardware acceleration support in FFmpeg can be checked on the [rpi-ffmpeg repository](https://github.com/jc-kynesim/rpi-ffmpeg).
### NVIDIA NVENC
> [!NOTE]
> **Minimum required driver version since Jellyfin 10.8:**
>
> * **Linux:** 470.57.02
> * **Windows:** 471.41
Not every card has been tested.
If you want more than three parallel transcoding streams on a consumer (non-Quadro) NVIDIA card, you can use [this patch](https://github.com/keylase/nvidia-patch) to remove the limit.
The patch is recommended for Linux and Windows but may break in the future, so check the compatible driver versions before applying it.
On Linux use `nvidia-smi` to check driver and GPU card version.
**Useful links:**
* [Official list of supported codecs for recent NVIDIA Graphics Cards](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new).
* [Official NVIDIA ffmpeg development docs](https://developer.nvidia.com/ffmpeg).
### AMD AMF
> [!NOTE]
> AMF is available on Windows and Linux.
> [!WARNING]
> As of **Jellyfin 10.8** full OpenCL based hardware filtering in AMF is supported on Windows 10 and newer.
>
> AMD has not implemented the Vulkan based HW decoder and scaler in ffmpeg, the decoding speed may not be as expected on Linux.
>
> The closed source driver `amdgpu-pro` is required when using AMF on Linux.
> [!TIP]
> Most Zen CPUs **do not** come with integrated graphics. You will need a **dedicated GPU** (dGPU) or a Zen CPU with integrated graphics for hardware acceleration.
> If your Zen CPU is suffixed with a *G* or *GE* in model name, you have integrated graphics.
### Intel QuickSync
> [!NOTE]
> Intel QuickSync (QSV) is derived from VA-API on Linux and D3D11VA on Windows, which can utilize Intel's fixed function hardware and EU(execution units) to do video encoding, decoding and processing.
> [!IMPORTANT]
> To use QSV on Linux with recent Intel iGPUs the **nonfree [Intel media driver](https://github.com/intel/media-driver)** is required for full hardware acceleration.
> If you are using `jellyfin-ffmpeg` version 4.4.1-2 or higher it is included and you do not need to install it seperatly.
> Broadwell or newer generation is required for QSV on Linux, otherwise you have to use VA-API.
**Useful links:**
* [Official list of supported codecs for recent Intel Graphics Cards](https://www.intel.com/content/www/us/en/develop/documentation/media-capabilities-of-intel-hardware/top.html).
* [Intel QSV Benchmarks on Linux](https://www.intel.com/content/www/us/en/architecture-and-technology/quick-sync-video/quick-sync-video-installation.html)
* [Collection of useful links and information](https://github.com/Artiume/jellyfin-docs/blob/master/general/wiki/main.md)
----
> [!TIP]
> If your Jellyfin server does not support hardware acceleration, but you have another machine that does, you can leverage [rffmpeg](https://github.com/joshuaboniface/rffmpeg) to delegate the transcoding to another machine.
> Currently Linux-only and requires SSH between the machines, as well as shared storage both for media and for the Jellyfin data directory.
## Common setups
Each hardware acceleration type, as well as each Jellyfin installation type, has different prerequisites for enabling hardware acceleration.
It is always best to consult [the FFMpeg documentation](https://trac.ffmpeg.org/wiki/HWAccelIntro) on the acceleration type you choose for the latest information.
### Hardware acceleration on Docker (Linux)
> [!NOTE]
> This are general instructions, for more specific instructions pleas check the next sections!
In order to use hardware acceleration in Docker, the devices must be passed to the container.
To see what video devices are available, you can run `sudo lshw -c video` or `vainfo` on your machine.
VA-API may require the `render` group added to the docker permissions.
The `render` group id can be discovered in `/etc/group` such as `render:x:122:`.
You can use `docker run` to start the server with the required permissions and devices.
An example command is shown below.
```sh
docker run -d \
--volume /path/to/config:/config \
--volume /path/to/cache:/cache \
--volume /path/to/media:/media \
--user 1000:1000 \
--group-add=122 \ # Change this to match your system
--net=host \
--restart=unless-stopped \
--device /dev/dri/renderD128:/dev/dri/renderD128 \
--device /dev/dri/card0:/dev/dri/card0 \
jellyfin/jellyfin
```
Alternatively, you can use docker-compose with a configuration file so you don't need to run a long command every time you restart your server.
```yaml
version: "3"
services:
jellyfin:
image: jellyfin/jellyfin
user: 1000:1000
group_add:
- 122
network_mode: "host"
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
- /path/to/media:/media
devices:
# VAAPI Devices (examples)
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card0:/dev/dri/card0
```
### NVIDIA hardware acceleration on Docker (Linux)
In order to achieve hardware acceleration using Docker, several steps are required.
Prerequisites:
* GNU/Linux x86_64 with kernel version > 3.10
* Docker >= 19.03
* NVIDIA GPU with Architecture > Fermi (2.1)
* NVIDIA drivers >= 361.93
* [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#getting-started) needs to be installed
Follow the instructions in the link above to install the NVIDIA Container Toolkit for your Linux distribution.
Start your container by adding this parameter:
```sh
--gpus all \
```
A complete run command would look like this:
```sh
docker run -d \
--name=jellyfin \
--gpus all \
-p 8096:8096 \
-p 8920:8920 \
-v /config:/config \
-v /media:/media \
-v /cache:/cache \
--restart unless-stopped \
jellyfin/jellyfin
```
Or with docker-compose >1.28, add the `deploy` section to your Jellyfin service:
```yaml
services:
jellyfin:
image: jellyfin/jellyfin
# ... your Jellyfin config
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]
```
There are some special steps when running with the following option:
```sh
--user 1000:1000
```
You may need to add this user to the video group on your host machine:
```sh
usermod -aG video <user>
```
Once the container is started you can again validate access to the host resources:
```sh
docker exec -it jellyfin nvidia-smi
```
If you get driver information, everything is fine but if you get an error like `couldn't find libnvidia-ml.so library in your system` you need to run the following command:
```sh
docker exec -it jellyfin ldconfig
```
After that, you should ensure the NVIDIA driver loads correctly.
> [!NOTE]
> The official Jellyfin Docker image already sets the required environment variables to allow access to the GPUs via the NVIDIA container runtime.
> If you are building your own image don't forget to include `NVIDIA_DRIVER_CAPABILITIES=all` and `NVIDIA_VISIBLE_DEVICES=all` into your container's environment.
### VA-API hardware acceleration on Debian/Ubuntu
Configuring VA-API on Debian/Ubuntu requires some additional configuration to ensure permissions are correct.
1. Configure VA-API for your system by following the documentation of your OS and/or vendor.
Verify that a `render` device is now present in `/dev/dri`, and note the permissions and group available to write to it, in this case `render`:
```sh
$ ls -l /dev/dri
total 0
drwxr-xr-x 2 root root 100 Apr 13 16:37 by-path
crw-rw---- 1 root video 226, 0 Apr 13 16:37 card0
crw-rw---- 1 root video 226, 1 Apr 13 16:37 card1
crw-rw---- 1 root render 226, 128 Apr 13 16:37 renderD128
```
> [!NOTE]
> On some releases, the group may be `video` or `input` instead of `render`.
2. Make sure that `jellyfin-ffmpeg` version 4.4.1-2 or higher is installed.
3. Check the output of `/usr/lib/jellyfin-ffmpeg/vainfo`.
4. Add the Jellyfin service user to the above group to allow Jellyfin's FFMpeg process access to the device, and restart Jellyfin.
```sh
sudo usermod -aG render jellyfin
sudo systemctl restart jellyfin
```
5. Configure VA-API acceleration in the `Transcoding` page of the Admin Dashboard.
Enter the `/dev/dri/renderD128` device above as the `VA API Device` value.
6. Watch a movie, and verify that transcoding is occurring by watching the `ffmpeg-transcode-*.txt` logs under `/var/log/jellyfin` and using `radeontop` (AMD only) or similar tools.
### Intel QuickSync (QSV) hardware acceleration on Debian/Ubuntu
1. QSV is based on VA-API device on Linux, so please confirm whether you have completed the VA-API configuration first.
2. Make sure that `jellyfin-ffmpeg` version 4.4.1-2 or higher is installed (it ships the current version of `intel-media-driver (iHD)` which is required for QSV).
3. Verify that the iHD driver is properly loaded and recognizes your iGPU.
```sh
sudo /usr/lib/jellyfin-ffmpeg/vainfo | grep iHD
```
4. Configure QSV acceleration in the `Transcoding` page of the Admin Dashboard.
5. Watch a movie, and verify that transcoding is occurring by watching the `ffmpeg-transcode-*.txt` logs under `/var/log/jellyfin` and using `intel_gpu_top` (can be installed with the `intel-gpu-tools` package).
### VA-API and QSV hardware acceleration on LXC or LXD container
> [!WARNING]
> This has been tested with LXC 3.0 and may or may not work with older versions.
Follow the steps above to add the jellyfin user to the `video` or `render` group, depending on your circumstances.
1. Install the required drivers on the host OS
2. Add your GPU to the container.
```sh
lxc config device add <container name> gpu gpu gid=<gid of your video or render group>
```
3. Make sure you have the required devices within the container:
```sh
$ lxc exec jellyfin -- ls -l /dev/dri
total 0
crw-rw---- 1 root video 226, 0 Jun 4 02:13 card0
crw-rw---- 1 root video 226, 0 Jun 4 02:13 controlD64
crw-rw---- 1 root video 226, 128 Jun 4 02:13 renderD128
```
4. Configure Jellyfin to use video acceleration and point it at the right device if the default option is wrong.
5. Try and play a video that requires transcoding and run the following, you should get a hit.
```sh
ps aux | grep ffmpeg | grep accel
```
6. You can also try playing a video that requires transcoding, and if it plays you're good.
Useful resources:
* [LXD Documentation - GPU instance configuration](https://github.com/lxc/lxd/blob/master/doc/instances.md#type-gpu)
* [NVIDIA CUDA inside a LXD container](https://stgraber.org/2017/03/21/cuda-in-lxd/)
### VA-API and QSV hardware acceleration on LXC on Proxmox
> [!IMPORTANT]
> Jellyfin needs to run in a **privileged** LXC container.
> You can convert an existing unprivileged container to a privileged container by taking a backup and restoring it as priviledged.
1. Install the required drivers on the Proxmox host
2. Add your GPU to the container by editing `/etc/pve/lxc/<container-id>.conf` (you may need to change the GIDs in the examples below to match those used on you host).
> [!WARNING]
> This has been tested on `Proxmox VE 7.1` - on previous versions you may need to change `cgroup2` to `cgroup`.
Intel iGPU:
```conf
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
```
NVidia GPU:
```conf
lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 243:* rwm
lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file
```
3. Shutdown and start your container.
4. Install the required drivers in your container.
5. Add the jellyfin user to the `video`, `render` and/or `input` groups depending on who owns the device inside the container.
6. Configure Jellyfin to use hardware acceleration and point it at the right device if the default option is wrong.
7. Try and play a video that requires transcoding and run the following, you should get a hit.
```sh
ps aux | grep ffmpeg | grep accel
```
8. You can also try playing a video that requires transcoding, and if it plays you're good.
### AMD AMF encoding on Ubuntu 18.04 or 20.04 LTS
1. Install the `amdgpu-pro` closed source graphics driver by following the [installation instructions](https://amdgpu-install.readthedocs.io/en/latest/).
2. Then install `amf-amdgpu-pro`.
```bash
sudo apt install amf-amdgpu-pro
```
3. Check if `jellyfin-ffmpeg` contains `h264_amf` encoder:
```bash
$ cd /usr/lib/jellyfin-ffmpeg/
$ ./ffmpeg -encoders | grep h264_amf
V..... h264_amf AMD AMF H.264 Encoder (codec h264)
```
> [!NOTE]
> If not available, update your `jellyfin-ffmpeg` to the latest version and try again.
4. Choose AMD AMF video acceleration in Jellyfin and check the `Enable hardware encoding` option.
5. Watch a movie, then verify that `h264_amf` encoder is working by watching the `ffmpeg-transcode-*.txt` transcoding logs under `/var/log/jellyfin` and using `radeontop` or similar tools.
### AMD AMF encoding on Arch Linux
AMD does not provide official `amdgpu-pro` driver support for Arch Linux, but fortunately, a third-party packaged `amdgpu-pro-installer` is provided in the archlinux user repository.
1. Clone [this repository](https://aur.archlinux.org/pkgbase/amdgpu-pro-installer/) using `git`.
```bash
git clone https://aur.archlinux.org/amdgpu-pro-installer.git
```
2. Enter that folder and make the installation package and install it.
```bash
cd amdgpu-pro-installer
makepkg -si
```
3. Go to step 3 of [Configuring AMD AMF encoding on Ubuntu 18.04 or 20.04 LTS](#amd-amf-encoding-on-ubuntu-1804-or-2004-lts) above.
### OpenCL / CUDA / Intel VPP Tone-Mapping
Hardware based HDR10/HLG/DoVi tone-mapping with NVIDIA NVENC, AMD AMF, Intel QSV and VA-API is done through OpenCL or CUDA. DoVi Profile 5 and 8 tone-mapping requires `jellyfin-ffmpeg` version 5.0.1-5 or higher.
Intel hardware based VPP HDR10 tone-mapping is supported on Intel QSV and VA-API on Linux.
VPP is prefered when both two tone-mapping options are checked on Intel.
OS/Platform | NVIDIA NVENC | AMD AMF | Intel QSV | Intel VA-API | AMD VA-API | Software
----------- | ------------ | -------- | ----------- | ------------ | ---------- | --------
Linux | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | WIP
Windows | ✔️ | ✔️ | ✔️ | N/A | N/A | WIP
Docker | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | WIP
> [!NOTE]
> Tone-mapping on Windows with Intel QSV and AMD AMF requires Windows 10 or newer.
> [!IMPORTANT]
> Make sure the hardware acceleration is well configured before configuring tone-mapping with this instructions.
1. **On Windows:** Install the latest NVIDIA, AMD or Intel drivers.
2. **On Linux or Docker:**
* For **NVIDIA cards** no further configuration is necessary.
* For **AMD cards**, install `amdgpu-pro` with opencl arguments (see [Configuring AMD AMF encoding on Ubuntu 18.04 or 20.04 LTS](#amd-amf-encoding-on-ubuntu-1804-or-2004-lts) for more details):
```sh
sudo ./amdgpu-pro-install -y --opencl=pal,legacy
sudo usermod -aG video $LOGNAME
sudo usermod -aG render $LOGNAME
```
* For **Intel iGPUs**, you have two types of tone-mapping methods: OpenCL and VPP. The latter one does not support fine tuning options.
**OpenCL:** Follow the instructions from [intel-compute-runtime](https://github.com/intel/compute-runtime/releases).
If you are using the official Docker image or the one from linuxserver this step can be skipped.
**VPP:** Make sure `jellyfin-ffmpeg` 4.4.1-2 or higher is installed.
Previous versions did not ship `intel-media-driver` thus it was required to be installed manually.
* When running on docker, the **privileged** flag is required for the OpenCL device to be recognized.
You can do this by adding `--privileged` to your docker command or `privileged: true` to your docker compose file.
> [!WARNING]
> Tone-mapping on Intel VA-API and QSV **requires an iGPU that supports 10-bit decoding**, such as i3-7100 or J4105.
> [!IMPORTANT]
> Do **not use** the `intel-opencl-icd` package from your distro's repository since they were not built with `RELEASE_WITH_REGKEYS` enabled, which is required for P010 pixel interop flags.
3. **Debugging:** Check the OpenCL device status. You will see corresponding vendor name if it goes well.
* Use `clinfo`: Install `clinfo` before using it. `sudo apt install -y clinfo` on Debian/Ubuntu or `sudo pacman -Sy clinfo` on Arch. Then `sudo clinfo`.
* Use `jellyfin-ffmpeg`: `/usr/lib/jellyfin-ffmpeg/ffmpeg -v debug -init_hw_device opencl`
## Verifying Transcodes
To verify that you are using the proper libraries, run this command against your transcoding log.
This can be found at `Admin Dashboard > Logs`, and `/var/log/jellyfin` if installed via the apt repository.
```sh
grep -A2 'Stream mapping:' /var/log/jellyfin/ffmpeg-transcode-<random-id>>.log
```
This returned the following results.
```data
...
Stream mapping:
Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_qsv))
Stream #0:1 -> #0:1 (aac (native) -> mp3 (libmp3lame))
...
```
`Stream #0:0` used software (VAAPI Decode can also say native) to decode HEVC and used HWA to encode.
```data
...
Stream mapping:
Stream #0:0 -> #0:0 (h264 (hevc_qsv) -> h264 (h264_qsv))
Stream #0:1 -> #0:1 (flac (native) -> mp3 (libmp3lame))
...
```
`Stream #0:0` used HWA for both. `hevc_qsv` to decode and `h264_qsv` to encode.

View File

@ -0,0 +1,34 @@
---
uid: admin-install-synology
title: Installing on Synology
---
# Installing on Synology
For [Synology](https://www.synology.com/en-us/dsm), Jellyfin is installed using Docker.
![Installing Synology](~/images/install-synology-1.png)
![Installing Synology](~/images/install-synology-2.png)
![Installing Synology](~/images/install-synology-3.png)
Create the container.
![Installing Synology](~/images/install-synology-4.png)
![Installing Synology](~/images/install-synology-5.png)
Use Advanced Settings to add mount points to your media and config.
![Installing Synology](~/images/install-synology-6.png)
![Installing Synology](~/images/install-synology-7.png)
Host Mode is required for HdHR and DLNA. Use bridge mode if running multiple instances.
![Installing Synology](~/images/install-synology-8.png)
![Installing Synology](~/images/install-synology-9.png)
Browse to `http://SERVER_IP:8096` to access the web client.

View File

@ -0,0 +1,846 @@
---
uid: admin-installing
title: Installing Jellyfin
---
<!-- markdownlint-disable MD036 no-emphasis-as-heading -->
# Installing <!-- omit in toc -->
The Jellyfin project and its contributors offer a number of pre-built binary packages to assist in getting Jellyfin up and running quickly on multiple systems.
## Container images
Official container image: `jellyfin/jellyfin` <a href="https://hub.docker.com/r/jellyfin/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg"></a>.
LinuxServer.io image: `linuxserver/jellyfin` <a href="https://hub.docker.com/r/linuxserver/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/linuxserver/jellyfin.svg"></a>.
hotio image: `hotio/jellyfin` <a href="https://hub.docker.com/r/hotio/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/hotio/jellyfin.svg"></a>.
Jellyfin distributes [official container images on Docker Hub](https://hub.docker.com/r/jellyfin/jellyfin/) for multiple architectures.
These images are based on Debian and [built directly from the Jellyfin source code](https://github.com/jellyfin/jellyfin/blob/master/Dockerfile).
Additionally the [LinuxServer.io](https://www.linuxserver.io/) project and [hotio](https://github.com/hotio) distribute images based on Ubuntu and the official Jellyfin Ubuntu binary packages, see [here](https://github.com/linuxserver/docker-jellyfin/blob/master/Dockerfile) and [here](https://github.com/hotio/jellyfin/blob/release/linux-amd64.Dockerfile) to see their Dockerfile.
> [!Note]
> For ARM hardware and RPi, it is recommended to use the LinuxServer.io or hotio image since hardware acceleration support is not yet available on the native image.
### Docker
[Docker](https://www.docker.com/) allows you to run containers on Linux, Windows and MacOS.
The basic steps to create and run a Jellyfin container using Docker are as follows.
1. Follow the [offical installation guide to install Docker](https://docs.docker.com/engine/install).
2. Download the latest container image.
```sh
docker pull jellyfin/jellyfin
```
3. Create persistent storage for configuration and cache data.
Either create two directories on the host and use bind mounts:
```sh
mkdir /path/to/config
mkdir /path/to/cache
```
Or create two persistent volumes:
```sh
docker volume create jellyfin-config
docker volume create jellyfin-cache
```
4. Create and run a container in one of the following ways.
> [!Note]
> The default network mode for Docker is bridge mode. Bridge mode will be used if host mode is omitted.
> Using host networking (`--net=host`) is optional but required in order to use DLNA.
**Using Docker command line interface:**
```sh
docker run -d \
--name jellyfin \
--user uid:gid \
--net=host \
--volume /path/to/config:/config \ # Alternatively --volume jellyfin-config:/config
--volume /path/to/cache:/cache \ # Alternatively --volume jellyfin-cache:/cache
--mount type=bind,source=/path/to/media,target=/media \
--restart=unless-stopped \
jellyfin/jellyfin
```
Bind Mounts are needed to pass folders from the host OS to the container OS whereas volumes are maintained by Docker and can be considered easier to backup and control by external programs.
For a simple setup, it's considered easier to use Bind Mounts instead of volumes.
Multiple media libraries can be bind mounted if needed:
```sh
--mount type=bind,source=/path/to/media1,target=/media1
--mount type=bind,source=/path/to/media2,target=/media2,readonly
...etc
```
> [!Note]
> There is currently an [issue](https://github.com/docker/for-linux/issues/788) with read-only mounts in Docker.
> If there are submounts within the main mount, the submounts are read-write capable.
**Using Docker Compose:**
Create a `docker-compose.yml` file with the following contents:
```yml
version: '3.5'
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: uid:gid
network_mode: 'host'
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
- /path/to/media:/media
- /path/to/media2:/media2:ro
restart: 'unless-stopped'
# Optional - alternative address used for autodiscovery
environment:
- JELLYFIN_PublishedServerUrl=http://example.com
```
Then while in the same folder as the `docker-compose.yml` run:
```sh
docker-compose up
```
To run the container in background add `-d` to the above command.
You can learn more about using Docker by [reading the official Docker documentation](https://docs.docker.com/).
### Unraid Docker
An Unraid Docker template is available in the repository.
1. Open the unRaid GUI (at least unRaid 6.5) and click on the `Docker` tab.
2. Add the following line under "Template Repositories" and save the options.
```data
https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates
```
3. Click "Add Container" and select "jellyfin".
4. Adjust any required paths and save your changes.
### Kubernetes
A community project to deploy Jellyfin on Kubernetes-based platforms exists [at their repository](https://github.com/home-cluster/jellyfin-openshift).
Any issues or feature requests related to deployment on Kubernetes-based platforms should be filed there.
### Podman
[Podman](https://podman.io) allows you to run rootless containers.
It's also the officially supported container solution on Fedora Linux and its derivatives such as CentOS Stream and RHEL.
Steps to run Jellyfin using Podman are similar to the Docker steps.
1. Install Podman:
```sh
sudo dnf install -y podman
```
2. Create and run a Jellyfin container:
```sh
podman run \
--detach \
--label "io.containers.autoupdate=registry" \
--name myjellyfin \
--publish 8096:8096/tcp \
--rm \
--user $(id -u):$(id -g) \
--userns keep-id \
--volume jellyfin-cache:/cache:Z \
--volume jellyfin-config:/config:Z \
--mount type=bind,source=/path/to/media,destination=/media,ro=true \
docker.io/jellyfin/jellyfin:latest
```
3. Open the necessary ports in your machine's firewall if you wish to permit access to the Jellyfin server from outside the host.
This is not done automatically when using rootless Podman.
If your distribution uses `firewalld`, the following commands save and load a new firewall rule opening the HTTP port `8096` for TCP connections.
```sh
sudo firewall-cmd --add-port=8096/tcp --permanent
sudo firewall-cmd --reload
```
Podman doesn't require root access to run containers, although there are some details to be mindful of; see [the relevant documentation](https://docs.podman.io/en/latest/markdown/podman.1.html#rootless-mode).
For security, the Jellyfin container should be run using rootless Podman.
Furthermore, it is safer to run as a non-root user within the container.
The `--user` option will run with the provided user id and group id _inside_ the container.
The `--userns keep-id` flag ensures that current user's id is mapped to the non-root user's id inside the container.
This ensures that the permissions for directories bind-mounted inside the container are mapped correctly between the user running Podman and the user running Jellyfin inside the container.
Keep in mind that the `--label "io.containers.autoupdate=image"` flag will allow the container to be automatically updated via `podman auto-update`.
The `z` (shared volume) or `Z` (private volume) volume option tells Podman to relabel files inside the volumes as appropriate, for systems running SELinux.
Replace `jellyfin-config` and `jellyfin-cache` with `/path/to/config` and `/path/to/cache` if you wish to use bind mounts.
This example mounts your media library read-only by setting `ro=true`; set this to `ro=false` if you wish to give Jellyfin write access to your media.
#### Managing via Systemd
To run as a systemd service see [Running containers with Podman and shareable systemd services](https://www.redhat.com/sysadmin/podman-shareable-systemd-services).
As always it is recommended to run the container rootless. Therefore we want to manage the container with the `systemd --user` flag.
1. First we have to generate the container as seen above.
2. Next generate the systemd.service file.
```sh
podman generate systemd --new --name myjellyfin > ~/.config/systemd/user/container-myjellyfin.service
```
3. Verify and edit the systemd.service file to your liking.
To further sandbox see [Mastering systemd: Securing and sandboxing applications and services](https://www.redhat.com/sysadmin/mastering-systemd).
An example service file is shown below. **Do not blindly copy**, one should make edits to the service file generated by podman.
```sh
# container-myjellyfin.service
# autogenerated by Podman 2.2.1
# Wed Feb 17 23:49:24 EST 2021
[Unit]
Description=Podman container-myjellyfin.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
ExecStartPre=/bin/rm -f %t/container-myjellyfin.pid %t/container-myjellyfin.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/container-myjellyfin.pid --cidfile %t/container-myjellyfin.ctr-id --cgroups=no-conmon -d --replace --cgroup-manager=systemd --volume jellyfin-config:/config:z --volume jellyfin-cache:/cache:z --volume jellyfin-media:/media:z -p 8096:8096 --userns keep-id --name myjellyfin jellyfin/jellyfin
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/container-myjellyfin.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/container-myjellyfin.ctr-id
PIDFile=%t/container-myjellyfin.pid
KillMode=control-group
Type=forking
# Security Features
PrivateTmp=yes
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
PrivateMounts=yes
ProtectHostname=yes
[Install]
WantedBy=multi-user.target default.target
```
4. Stop the running Jellyfin container.
```sh
podman stop myjellyfin
```
5. Start and enable the service.
```sh
systemctl --user enable --now container-myjellyfin.service
```
At this point the container will only start when the user logs in and shutdown when they log off.
To have the container start as the user at first login we'll have to include one more option.
```sh
loginctl enable-linger $USER
```
6. To enable Podman auto-updates, enable the necessary systemd timer.
```sh
systemctl --user enable --now podman-auto-update.timer
```
### Cloudron
Cloudron is a complete solution for running apps on your server and keeping them up-to-date and secure.
On your Cloudron you can install Jellyfin with a few clicks via the [app library](https://cloudron.io/store/org.jellyfin.cloudronapp.html) and updates are delivered automatically.
The source code for the package can be found [here](https://git.cloudron.io/cloudron/jellyfin-app).
Any issues or feature requests related to deployment on Cloudron should be filed there.
## Windows (x64)
Windows installers and builds in ZIP archive format are available [here](https://jellyfin.org/downloads/#windows).
> [!WARNING]
> If you installed a version prior to 10.4.0 using a PowerShell script, you will need to manually remove the service using the command `nssm remove Jellyfin` and uninstall the server by remove all the files manually.
> Also one might need to move the data files to the correct location, or point the installer at the old location.
> [!WARNING]
> The Basic Install is the recommended way to run the Jellyfin Server.
> Using the Advanced/Service mode may experience FFmpeg hardware acceleration issues, and is only for advanced users.
### Install using Installer (x64)
**Install**
1. Download the latest version.
2. Run the installer.
3. (Optional) When installing as a service (not recommended), pick the service account type.
4. If everything was completed successfully, Jellyfin is now running.
5. Open your browser at <http://your_local_IP_address:8096> to finish setting up Jellyfin.
**Update**
1. Download the latest version.
2. Close or Stop Jellyfin if it is running.
3. Run the installer.
4. If everything was completed successfully, the new version is installed.
**Uninstall**
1. Go to `Add or remove programs` in Windows.
2. Search for Jellyfin.
3. Click Uninstall.
### Manual Installation (x86/x64)
**Install**
1. Download and extract the latest version.
2. Create a folder `jellyfin` at your preferred install location.
3. Copy the extracted folder into the `jellyfin` folder and rename it to `system`.
4. Create `jellyfin.bat` within your `jellyfin` folder containing:
- To use the default library/data location at `%localappdata%`:
```cmd
<--Your install path-->\jellyfin\system\jellyfin.exe
```
- To use a custom library/data location (Path after the -d parameter):
```cmd
<--Your install path-->\jellyfin\system\jellyfin.exe -d <--Your install path-->\jellyfin\data
```
- To use a custom library/data location (Path after the -d parameter) and disable the auto-start of the webapp:
```cmd
<--Your install path-->\jellyfin\system\jellyfin.exe -d <--Your install path-->\jellyfin\data -noautorunwebapp
```
5. Run
```cmd
jellyfin.bat
```
6. Open your browser at `http://<--Server-IP-->:8096` (if auto-start of webapp is disabled)
**Update**
1. Stop Jellyfin
2. Rename the Jellyfin `system` folder to `system-bak`
3. Download and extract the latest Jellyfin version
4. Copy the extracted folder into the `jellyfin` folder and rename it to `system`
5. Run `jellyfin.bat` to start the server again
**Rollback**
1. Stop Jellyfin.
2. Delete the `system` folder.
3. Rename `system-bak` to `system`.
4. Run `jellyfin.bat` to start the server again.
## macOS
macOS Application packages and builds in TAR archive format are available [here](https://jellyfin.org/downloads/#macos).
**Install**
1. Download the latest version.
2. Drag the `.app` package into the Applications folder.
3. Start the application.
4. Click the icon in the menu bar and select "Launch Web UI".
**Upgrade**
1. Download the latest version.
2. Stop the currently running server either via the dashboard or using the menu bar icon.
3. Drag the new `.app` package into the Applications folder and click yes to replace the files.
4. Start the application.
**Uninstall**
1. Stop the currently running server either via the dashboard or using the application icon.
2. Move the `.app` package to the trash.
**Deleting Configuation**
This will delete all settings and user information. This applies for the .app package and the portable version.
1. Delete the folder `~/.config/jellyfin/`
2. Delete the folder `~/.local/share/jellyfin/`
**Portable Version**
1. Download the latest version
2. Extract it into the Applications folder
3. Open Terminal and type `cd` followed with a space then drag the jellyfin folder into the terminal.
4. Type `./jellyfin` to run jellyfin.
5. Open your browser at <http://localhost:8096>
Closing the terminal window will end Jellyfin. Running Jellyfin in screen or tmux can prevent this from happening.
**Upgrading the Portable Version**
1. Download the latest version.
1. Stop the currently running server either via the dashboard or using `CTRL+C` in the terminal window.
1. Extract the latest version into Applications
1. Open Terminal and type `cd` followed with a space then drag the jellyfin folder into the terminal.
1. Type `./jellyfin` to run jellyfin.
1. Open your browser at <http://localhost:8096>
**Uninstalling the Portable Version**
1. Stop the currently running server either via the dashboard or using `CTRL+C` in the terminal window.
1. Move `/Application/jellyfin-version` folder to the Trash. Replace version with the actual version number you are trying to delete.
**Using FFmpeg with the Portable Version**
The portable version doesn't come with FFmpeg by default, so to install FFmpeg you have three options.
- use the package manager homebrew by typing `brew install ffmpeg` into your Terminal ([here's how to install homebrew if you don't have it already](https://treehouse.github.io/installation-guides/mac/homebrew)
- download the most recent static build from [this link](https://evermeet.cx/ffmpeg/get/zip) (compiled by a third party see [this page](https://evermeet.cx/ffmpeg/) for options and information), or
- compile from source available from the official [website](https://ffmpeg.org/download.html)
More detailed download options, documentation, and signatures can be found.
If using static build, extract it to the `/Applications/` folder.
Navigate to the Playback tab in the Dashboard and set the path to FFmpeg under FFmpeg Path.
## Linux
### Linux (generic amd64)
Generic amd64, arm64, and armhf Linux builds in TAR archive format are available [here](https://jellyfin.org/downloads/#linux).
#### Base Installation Process
Create a directory in `/opt` for jellyfin and its files, and enter that directory.
```sh
sudo mkdir /opt/jellyfin
cd /opt/jellyfin
```
Download the latest generic Linux build for your architecture.
The rest of these instructions assume version 10.7.7 is being installed (i.e. `jellyfin_10.7.7_amd64.tar.gz`).
Download the generic build, then extract the archive:
```sh
sudo wget https://repo.jellyfin.org/releases/server/linux/stable/combined/jellyfin_10.7.7_amd64.tar.gz
sudo tar xvzf jellyfin_10.7.7_amd64.tar.gz
```
Create a symbolic link to the Jellyfin 10.7.7 directory.
This allows an upgrade by repeating the above steps and enabling it by simply re-creating the symbolic link to the new version.
```sh
sudo ln -s jellyfin_10.7.7 jellyfin
```
Create four sub-directories for Jellyfin data.
```sh
sudo mkdir data cache config log
```
#### `ffmpeg` Installation
If you are not running a Debian derivative, install `ffmpeg` through your OS's package manager, and skip this section.
> [!WARNING]
> Not being able to use `jellyfin-ffmpeg` will most likely break hardware acceleration and tonemapping.
If you are running Debian or a derivative, you should [download](https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/) and install an `ffmpeg` release built specifically for Jellyfin.
Be sure to download the latest release that matches your OS (4.4.1-1 for Debian Bullseye assumed below).
```sh
sudo wget https://repo.jellyfin.org/releases/server/debian/versions/jellyfin-ffmpeg/4.4.1-1/jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb
sudo dpkg --install jellyfin-ffmpeg_4.4.1-1-bullseye_amd64.deb
```
If you run into any dependency errors, run this and it will install them and `jellyfin-ffmpeg`.
```sh
sudo apt install -f
```
#### Running Jellyfin
Due to the number of command line options that must be passed, it is easiest to create a small script to run Jellyfin.
```sh
sudo nano jellyfin.sh
```
Then paste the following commands and modify as needed.
```sh
#!/bin/bash
JELLYFINDIR="/opt/jellyfin"
FFMPEGDIR="/usr/share/jellyfin-ffmpeg"
$JELLYFINDIR/jellyfin/jellyfin \
-d $JELLYFINDIR/data \
-C $JELLYFINDIR/cache \
-c $JELLYFINDIR/config \
-l $JELLYFINDIR/log \
--ffmpeg $FFMPEGDIR/ffmpeg
```
Assuming you desire Jellyfin to run as a non-root user, `chmod` all files and directories to your normal login user and group.
Also make the startup script above executable.
```sh
sudo chown -R user:group *
sudo chmod u+x jellyfin.sh
```
Finally you can run it.
You will see lots of log information when run, this is normal.
Setup is as usual in the web browser.
```sh
./jellyfin.sh
```
##### Starting Jellyfin on boot (optional)
Create a `systemd` unit file.
```sh
cd /etc/systemd/system
sudo nano jellyfin.service
```
Then paste the following contents, replacing `youruser` with your username.
```ini
[Unit]
Description=Jellyfin
After=network.target
[Service]
Type=simple
User=youruser
Restart=always
ExecStart=/opt/jellyfin/jellyfin.sh
[Install]
WantedBy=multi-user.target
```
Apply the correct permissions to the file, enable the service to start on boot, then start it.
```sh
sudo chmod 644 jellyfin.service
sudo systemctl daemon-reload
sudo systemctl enable jellyfin.service
sudo systemctl start jellyfin.service
```
### Portable DLL
Platform-agnostic .NET Core DLL builds in TAR archive format are available [here](https://jellyfin.org/downloads/#portable).
These builds use the binary `jellyfin.dll` and must be loaded with `dotnet`.
### Arch Linux
Jellyfin can be found in the AUR as [`jellyfin`](https://aur.archlinux.org/packages/jellyfin/), [`jellyfin-bin`](https://aur.archlinux.org/packages/jellyfin-bin/) and [`jellyfin-git`](https://aur.archlinux.org/packages/jellyfin-git/).
### Fedora
Fedora builds in RPM package format are available [here](https://jellyfin.org/downloads/#fedora) for now but an official Fedora repository is coming soon.
1. You will need to enable rpmfusion as ffmpeg is a dependency of the jellyfin server package
```sh
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
```
> [!NOTE]
> You do not need to manually install ffmpeg, it will be installed by the jellyfin server package as a dependency
2. Install the jellyfin server
```sh
sudo dnf install (link to version jellyfin server you want to install)
```
3. Install the jellyfin web interface
```sh
sudo dnf install (link to web RPM you want to install)
```
4. Enable jellyfin service with systemd
```sh
sudo systemctl start jellyfin
```
```sh
sudo systemctl enable jellyfin
```
5. Open jellyfin service with firewalld
```sh
sudo firewall-cmd --permanent --add-service=jellyfin
```
> [!NOTE]
> This will open the following ports
> 8096 TCP used by default for HTTP traffic, you can change this in the dashboard
> 8920 TCP used by default for HTTPS traffic, you can change this in the dashboard
> 1900 UDP used for service auto-discovery, this is not configurable
> 7359 UDP used for auto-discovery, this is not configurable
6. Reboot your machine
```sh
sudo systemctl reboot
```
7. Go to `localhost:8096` or `ip-address-of-jellyfin-server:8096` to finish setup in the web UI
### CentOS
CentOS/RHEL 7 builds in RPM package format are available [here](https://jellyfin.org/downloads/#centos) and an official CentOS/RHEL repository is planned for the future.
The default CentOS/RHEL repositories don't provide FFmpeg, which the RPM requires. You will need to add a third-party repository which provide FFmpeg, such as [RPM Fusion's Free repository](https://rpmfusion.org/Configuration).
You can also build [Jellyfin's version](https://github.com/jellyfin/jellyfin-ffmpeg) on your own. This includes gathering the dependencies and compiling and installing them. Instructions can be found at [the FFmpeg wiki](https://trac.ffmpeg.org/wiki/CompilationGuide/Centos).
### Debian
#### Repository
The Jellyfin team provides a Debian repository for installation on Debian Buster/Bullseye.
Supported architectures are `amd64`, `arm64`, and `armhf`.
> [!NOTE]
> Microsoft does not provide a .NET for 32-bit x86 Linux systems, and hence Jellyfin is **not** supported on the `i386` architecture.
Steps 1 to 3 can also be replaced by:
```sh
sudo apt install extrepo
sudo extrepo enable jellyfin
```
1. Install HTTPS transport for APT as well as `gnupg` and `lsb-release` if you haven't already.
```sh
sudo apt install apt-transport-https gnupg lsb-release
```
2. Import the GPG signing key (signed by the Jellyfin Team):
```sh
curl -fsSL https://repo.jellyfin.org/debian/jellyfin_team.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg
```
3. Add a repository configuration at `/etc/apt/sources.list.d/jellyfin.list`:
```sh
echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/debian $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list
```
> [!NOTE]
> Supported releases are `buster` and `bullseye`.
4. Update APT repositories:
```sh
sudo apt update
```
5. Install Jellyfin:
```sh
sudo apt install jellyfin
```
6. Manage the Jellyfin system service with your tool of choice:
```sh
sudo service jellyfin status
sudo systemctl restart jellyfin
sudo /etc/init.d/jellyfin stop
```
#### Packages
Raw Debian packages, including old versions, are available [here](https://jellyfin.org/downloads/#debian).
> [!NOTE]
> The repository is the preferred way to obtain Jellyfin on Debian, as it contains several dependencies as well.
1. Download the desired `jellyfin` and `jellyfin-ffmpeg` `.deb` packages from the repository.
2. Install the downloaded `.deb` packages:
```sh
sudo dpkg -i jellyfin_*.deb jellyfin-ffmpeg_*.deb
```
3. Use `apt` to install any missing dependencies:
```sh
sudo apt -f install
```
4. Manage the Jellyfin system service with your tool of choice:
```sh
sudo service jellyfin status
sudo systemctl restart jellyfin
sudo /etc/init.d/jellyfin stop
```
### Ubuntu
#### Migrating to the new repository
Previous versions of Jellyfin included Ubuntu under the Debian repository.
This has now been split out into its own repository to better handle the separate binary packages.
If you encounter errors about the `ubuntu` release not being found and you previously configured an `ubuntu` `jellyfin.list` file, please follow these steps.
1. Remove the old `/etc/apt/sources.list.d/jellyfin.list` file:
```sh
sudo rm /etc/apt/sources.list.d/jellyfin.list
```
2. Proceed with the following section as written.
#### Ubuntu Repository
The Jellyfin team provides an Ubuntu repository for installation on Ubuntu Xenial, Bionic, Cosmic, Disco, Eoan, and Focal. Supported architectures are `amd64`, `arm64`, and `armhf`.
Only `amd64` is supported on Ubuntu Xenial.
> [!NOTE]
> Microsoft does not provide a .NET for 32-bit x86 Linux systems, and hence Jellyfin is **not** supported on the `i386` architecture.
1. Install HTTPS transport for APT if you haven't already:
```sh
sudo apt install apt-transport-https
```
2. Enable the Universe repository to obtain all the FFMpeg dependencies:
```sh
sudo add-apt-repository universe
```
> [!NOTE]
> If the above command fails you will need to install the following package `software-properties-common`.
> This can be achieved with the following command `sudo apt-get install software-properties-common`
3. Import the GPG signing key (signed by the Jellyfin Team):
```sh
curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg
```
4. Add a repository configuration at `/etc/apt/sources.list.d/jellyfin.list`:
```sh
echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list
```
> [!NOTE]
> Supported releases are `bionic`, `cosmic`, `disco`, `eoan`, and `focal`.
5. Update APT repositories:
```sh
sudo apt update
```
6. Install Jellyfin:
```sh
sudo apt install jellyfin
```
7. Manage the Jellyfin system service with your tool of choice:
```sh
sudo service jellyfin status
sudo systemctl restart jellyfin
sudo /etc/init.d/jellyfin stop
```
#### Ubuntu Packages
Raw Ubuntu packages, including old versions, are available [here](https://jellyfin.org/downloads/#ubuntu).
> [!NOTE]
> The repository is the preferred way to install Jellyfin on Ubuntu, as it contains several dependencies as well.
1. Enable the Universe repository to obtain all the FFMpeg dependencies, and update repositories:
```sh
sudo add-apt-repository universe
sudo apt update
```
2. Download the desired `jellyfin` and `jellyfin-ffmpeg` `.deb` packages from the repository.
3. Install the required dependencies:
```sh
sudo apt install at libsqlite3-0 libfontconfig1 libfreetype6 libssl1.0.0
```
4. Install the downloaded `.deb` packages:
```sh
sudo dpkg -i jellyfin_*.deb jellyfin-ffmpeg_*.deb
```
5. Use `apt` to install any missing dependencies:
```sh
sudo apt -f install
```
6. Manage the Jellyfin system service with your tool of choice:
```sh
sudo service jellyfin status
sudo systemctl restart jellyfin
sudo /etc/init.d/jellyfin stop
```

View File

@ -0,0 +1,152 @@
---
uid: admin-migrate
title: Migrating
---
# Migrating
It is possible to migrate your system to another system by using environment variables.
It's possible to do this via the command line or by using Docker environment variables.
To read more, see the [Configuration](https://jellyfin.org/docs/general/administration/configuration.html) page.
## Watched Status Migration
There are scripts available that will use the API to copy watched status and users from one instance to another.
This can be done from Plex, Emby or another Jellyfin instance.
[Emby/Jellyfin to Jellyfin migration](https://github.com/CobayeGunther/Emby2Jelly)
[Plex to Jellyfin migration](https://github.com/wilmardo/migrate-plex-to-jellyfin)
## Migrating Linux install to Docker
It's possible to use the data of a local install in the official docker image by mapping files and folders to the same locations and configuring the image accordingly.
> [!Note]
> You need to have exactly matching paths for your files inside the docker container!
> This means that if your media is stored at `/media/raid/` this path needs to be accessible at `/media/raid/` inside the docker container too - the configurations below do include examples.
To guarantee proper permissions, get the `uid` and `gid` of the local user Jellyfin runs as (on a default install this is the `jellyfin` system user).
You can do this by running the following command:
```sh
id jellyfin
```
You need to replace the `<uid>:<gid>` placeholder below with the correct values.
> [!NOTE]
> To properly map the folders for your install, go to `Dashboard > Paths`.
### Using docker cli
```sh
docker run -d \
--user <uid>:<gid> \
-e JELLYFIN_CACHE_DIR=/var/cache/jellyfin \
-e JELLYFIN_CONFIG_DIR=/etc/jellyfin \
-e JELLYFIN_DATA_DIR=/var/lib/jellyfin \
-e JELLYFIN_LOG_DIR=/var/log/jellyfin \
--mount type=bind,source=/etc/jellyfin,target=/etc/jellyfin \
--mount type=bind,source=/var/cache/jellyfin,target=/var/cache/jellyfin \
--mount type=bind,source=/var/lib/jellyfin,target=/var/lib/jellyfin \
--mount type=bind,source=/var/log/jellyfin,target=/var/log/jellyfin \
--mount type=bind,source=</path/to/media>,target=</path/to/media> \
--net=host \
--restart=unless-stopped \
jellyfin/jellyfin
```
### Using docker-compose yaml
```yml
version: "3"
services:
jellyfin:
image: jellyfin/jellyfin
user: <uid>:<gid>
network_mode: "host"
restart: "unless-stopped"
environment:
- JELLYFIN_CACHE_DIR=/var/cache/jellyfin
- JELLYFIN_CONFIG_DIR=/etc/jellyfin
- JELLYFIN_DATA_DIR=/var/lib/jellyfin
- JELLYFIN_LOG_DIR=/var/log/jellyfin
volumes:
- /etc/jellyfin:/etc/jellyfin
- /var/cache/jellyfin:/var/cache/jellyfin
- /var/lib/jellyfin:/var/lib/jellyfin
- /var/log/jellyfin:/var/log/jellyfin
- <path-to-media>:<path-to-media>
```
## Migrating From Emby 3.5.2 to Jellyfin
> [!IMPORTANT]
> Direct database migration from Emby (of any version) to Jellyfin is NOT SUPPORTED.
> We have found many subtle bugs due to the inconsistent database schemas that result from trying to do this, and strongly recommend that all Jellyfin users migrating from Emby start with a fresh database and library scan.
The original procedure is provided below for reference however we cannot support it nor guarantee that a system upgraded in this way will work properly, if at all.
If anyone is interested in writing a database migration script which will correct the deficiencies in the existing database and properly import them into Jellyfin, [we would welcome it however](xref:contrib-index)!
> [!WARNING]
> While it is technically possible to migrate existing configuration of Emby version 3.5.2 or earlier, due to subtle and weird bugs reported after such attempts we do not recommend this migration.
> Emby versions 3.5.3 or 3.6+ cannot be migrated.
> Thus we recommend creating a new Jellyfin configuration and rebuilding your library instead.
Windows users may take advantage of the `install-jellyfin.ps1` script in the [Jellyfin repository](https://github.com/jellyfin/jellyfin) which includes an automatic upgrade option.
This procedure is written for Debian-based Linux distributions, but can be translated to other platforms by following the same general principles.
1. Upgrade to Emby version 3.5.2, so that the database schema is fully up-to-date and consistent.
While this is not required, it can help reduce the possibility of obscure bugs in the database.
2. Stop the `emby-server` daemon:
```sh
sudo service emby-server stop
```
3. Move your existing Emby data directory out of the way:
```sh
sudo mv /var/lib/emby /var/lib/emby.backup
```
4. Remove or purge the `emby-server` package:
```sh
sudo apt purge emby-server
```
5. Install the `jellyfin` package using the [installaton instructions](xref:admin-installing).
6. Stop the `jellyfin` daemon:
```sh
sudo service jellyfin stop
```
7. Copy over all the data files from the Emby backup data directory:
```sh
sudo cp -a /var/lib/emby.backup/* /var/lib/jellyfin/
```
8. Correct ownership on the new data directory:
```sh
sudo chown -R jellyfin:jellyfin /var/lib/jellyfin
```
9. Mark Startup Wizard as completed - if not marked as completed then it can be a security risk especially if remote access is enabled:
```sh
sudo sed -i '/IsStartupWizardCompleted/s/false/true/' /etc/jellyfin/system.xml
```
10. Start the `jellyfin` daemon:
```sh
sudo service jellyfin start
```

View File

@ -0,0 +1,118 @@
---
uid: admin-troubleshoot
title: Troubleshooting
---
# Troubleshooting
This page outlines some solutions to common issues beginners may encounter when running a Jellyfin server.
## Playback Issues
The easiest way to check for issues is by checking the logs, which can be accessed through the console for the web client or in the log directory on your server.
If media is unable transcode, first check the ffmpeg logs.
## Networking Issues
If you can access the web interface over HTTP but not HTTPS, then you likely have an error with the certificate.
Jellyfin uses a PFX file to handle HTTPS traffic.
If you created the file with a password, then you will have to enter that value on the **Networking** page in the settings.
If you can access the server locally but not outside of your LAN, then you likely have an issue with the router configuration.
Check the port forwarding settings on your router to ensure the server is visible from outside your local network.
You can also enable the "Enable automatic port mapping" option on the **Networking** page of the server settings to have the server attempt to configure port forwarding on the router automatically if your router supports it.
If there are no logs at all relating to web traffic, even over a LAN connection, then the server hasn't been reached at all yet.
This would indicate either an incorrect address or an issue somewhere else on the network.
## Debug Logging
To enable debug (much more verbose) logging, it is currently required to manually edit config files since no options exist yet on the frontend.
Go to the Jellyfin configuration directory, find the `logging.default.json` file, and change the minimum level to debug as seen below.
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Debug"
}
}
}
```
Jellyfin will automatically reload the new configuration without needing to restart.
The debug messages show up in the log with the `DBG` tag.
## Real Time Monitoring
This will let Jellyfin automatically update libraries when files are added or modified.
Unfortunately this feature is only supported on certain filesystems.
For Linux systems, this is performed by [inotify](https://en.wikipedia.org/wiki/Inotify).
NFS and rclone do not support inotify, but support can be provided by using a union file system such as [mergerfs](https://github.com/trapexit/mergerfs) with your networked file systems.
Due to the library size, you can receive an error such as this:
```log
[2019-12-31 09:11:36.652 -05:00] [ERR] Error in Directory watcher for: "/media/movies" System.IO.IOException: The configured user limit (8192) on the number of inotify watches has been reached.
```
If you are running Debian, RedHat, or another similar Linux distribution, run the following in a terminal:
```sh
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.d/40-max-user-watches.conf && sudo sysctl -p
```
If you are running ArchLinux, run the following command instead:
```sh
echo fs.inotify.max_user_watches=524288 | sudo tee /etc/sysctl.d/40-max-user-watches.conf && sudo sysctl --system
```
Then paste it in your terminal and press on enter to run it. For Docker, this needs to be done on the host, not the container.
See [here](https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers) for more information.
## Uninstall MacOS
To fully remove all data of Jellyfin from MacOS, run these commands:
```bash
rm -Rfv ~/.config/jellyfin
rm -Rfv ~/.cache/jellyfin
rm -Rfv ~/.local/share/jellyfin
```
## Unlock locked user account
When the admin account is locked out and the Forgot Password feature is not working, you have to unlock the user manually.
To do that, you need to find the `jellyfin.db` file on your system.
The default location on Linux is: `/var/lib/jellyfin/data/`.
For paths in other environments, see [server paths](xref:admin-configuration#server-paths).
### Linux CLI
Before continuing, make sure that you have sqlite3 installed.
When sqlite3 is not installed, you can install it under Debian based systems with `apt install sqlite3`.
After that do the following commands/SQL query:
```bash
sqlite3 /PATH/TO/JELLYFIN/DB/jellyfin.db
```
```sql
UPDATE Users SET InvalidLoginAttemptCount = 0 WHERE Username = 'LockedUserName';
update Permissions set Value = 0 where Kind = 2 and Permission_Permissions_Guid in (select Id from Users where Username = 'LockedUserName');
.exit
```
### SQLiteBrowser
It is also possible to use [SQLiteBrowser](https://sqlitebrowser.org) on systems with a desktop environment.
Start by opening the database inside the SQLite Browser.
After opening the database, navigate to the Execute SQL Tab and execute the following query:
```sql
UPDATE Users SET InvalidLoginAttemptCount = 0 WHERE Username = 'LockedUserName';
update Permissions set Value = 0 where Kind = 2 and Permission_Permissions_Guid in (select Id from Users where Username = 'LockedUserName');
```

View File

@ -0,0 +1,169 @@
---
uid: clients-codec-support
title: Codec Support
---
# [Codec Tables](https://en.wikipedia.org/wiki/List_of_codecs "Wikipedia's list of all codecs")
The goal is to Direct Play all media. This means the container, video, audio and subtitles are all compatible with the client. If the media is incompatible for any reason, Jellyfin will use FFmpeg to [convert the media](http://howto-pages.org/ffmpeg/) to a format that the client can process. Direct Stream will occur if the audio, container or subtitles happen to not be supported. If the video codec is unsupported, this will result in video transcoding. Subtitles can be tricky because they can cause Direct Stream (subtitles are remuxed) or video transcoding (burning in subtitles) to occur. This is the most intensive CPU component of transcoding. Decoding is less intensive than encoding.
## [Video Compatibility](https://en.wikipedia.org/wiki/Comparison_of_video_container_formats "Wikipedia's video codec tables")
[Breakdown of video codecs.](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs)
[Test your browser's compatibility for any codec profile.](https://cconcolato.github.io/media-mime-support/)
| Sorted by efficency (excluding bit depth) | Chrome | Edge | Firefox | Safari | Android | Android TV | iOS | SwiftFin (iOS) | [Roku](https://developer.roku.com/docs/specs/media/streaming-specifications.md) | Kodi | [Desktop](https://docs.jellyfin.org/general/clients/index.html#jellyfin-desktop) |
|-|-|-|-|-|-|-|-|-|-|-|-|
| [MPEG-4 Part 2/SP](https://en.wikipedia.org/wiki/DivX) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| [MPEG-4 Part 2/ASP](https://en.wikipedia.org/wiki/MPEG-4_Part_2#Advanced_Simple_Profile_(ASP)) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | ✅ | ✅ |
| [H.264 8Bit](https://caniuse.com/#feat=mpeg4 "H264 Browser Support Reference") | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [H.264 10Bit](https://caniuse.com/#feat=mpeg4 "H264 Browser Support Reference") | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| [H.265 8Bit](https://caniuse.com/#feat=hevc "HEVC Browser Support Reference") | ❌ | ✅<sup>7</sup> | ❌ | 🔶<sup>1</sup> | 🔶<sup>2</sup> | ✅<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | ✅ | ✅ | ✅ |
| [H.265 10Bit](https://caniuse.com/#feat=hevc "HEVC Browser Support Reference") | ❌ | ✅<sup>7</sup> | ❌ | 🔶<sup>1</sup> | 🔶<sup>2</sup> | 🔶<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | ✅ | ✅ | ✅ |
| [VP9](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#VP9 "V9 Browser Support Reference") | ✅ | ✅ | ✅ | ❌ | ✅<sup>3</sup> | 🔶<sup>3</sup> | ❌ | ❌ | ✅ | ✅ | ✅ |
| [AV1](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#AV1 "AV1 Browser Support Reference") | ✅ | ✅ | ✅ | ❌ | ✅ | 🔶<sup>4</sup> | ❌ | ❌ | ✅ | ✅ | ✅ |
<sup>1</sup>HEVC is only supported in MP4, M4V, and MOV containers.
<sup>2</sup>Android playback is currently broken. Client reports that HEVC is supported and attempts to Direct Stream.
<sup>3</sup>May be (partially) dependent on Hardware support (can be compensated with CPU decoding on Android). Most new Android phones in the higher price range and many "4K" Android TV devices have VP9 hardware decoding support. Refer to you manufacturer for supported codecs.
<sup>4</sup>Needs atleast Android TV 10
<sup>5</sup>As of [version 0.12](https://github.com/jellyfin/jellyfin-androidtv/pull/671), HEVC is enabled on all devices running Android 5.0+, but early generations of the Amazon Fire may not work yet. 10Bit may be supported depending on your device. Before Client 0.12, HEVC support was enabled on specific devices.
<sup>6</sup>HEVC decoding is supported on Apple devices with the A8X chip or newer and at least iOS 14
<sup>7</sup>HEVC decoding is only supported on Windows 10 with the HEVC Video Extension from the Microsoft [store](https://www.microsoft.com/store/productId/9NMZLZ57R3T7).
[Format Cheatsheet:](https://en.wikipedia.org/wiki/MPEG-4#MPEG-4_Parts)
|[MPEG-2<br>Part 2](https://en.wikipedia.org/wiki/H.262/MPEG-2_Part_2)|[MPEG-4<br>Part-2](https://en.wikipedia.org/wiki/MPEG-4_Part_2)<sup>1</sup>|[MPEG-4<br>Part-10](https://en.wikipedia.org/wiki/Advanced_Video_Coding)|[MPEG-4<br>Part-14](https://en.wikipedia.org/wiki/MPEG-4_Part_14)|[MPEG-H<br>Part 2](https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding)|
|:---:|:---:|:---:|:---:|:---:|
|H.262|MPEG-4 SP/ASP|H.264|MP4 Container<sup>2</sup>|H.265|
|MPEG-2 Video|DivX|MPEG-4 AVC||HEVC|
|DVD-Video|DX50||||
<sup>1</sup>[MPEG-4 Part-2 vs Part-10](https://www.afterdawn.com/glossary/term.cfm/mpeg_4_part_10)
<sup>2</sup>[MPEG-4 Part 17: MP4TT Subtitles](https://en.wikipedia.org/wiki/MPEG-4_Part_17)
## [Audio Compatibility](https://en.wikipedia.org/wiki/Comparison_of_video_container_formats#Audio_coding_formats_support "Wikipedia's audio codec tables")
If the audio codec is unsupported or incompatible (such as playing a 5.1 channel stream on a stereo device), the audio codec must be transcoded. This is not nearly as intensive as video transcoding.
||Chrome|Edge|Firefox|Safari|Android|Android TV|iOS|SwiftFin (iOS) |Roku|Kodi|Desktop|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|FLAC|✅|✅|✅|✅|✅|✅|✅|✅|✅|✅|✅|
|MP3|🔶<sup>1</sup>|✅|🔶|✅|✅|✅|✅|✅|✅|✅|✅|
|AAC|✅|✅|✅|✅|✅|✅|✅|✅|✅|✅|✅|
|[AC3](https://www.loc.gov/preservation/digital/formats/fdd/fdd000209.shtml)|✅|✅|❌|✅|✅|✅|✅|✅||✅|✅|
|[EAC3](https://en.wikipedia.org/wiki/Dolby_Digital_Plus)<sup>2</sup>|✅|✅|✅|✅|✅|✅|✅|✅||✅|✅|
|VORBIS<sup>3</sup>|✅|✅|✅|❌|✅|❌|❌|✅|✅|✅|✅|
|DTS<sup>4</sup>|❌|❌|❌|❌|✅|✅|❌|✅|✅<sup>6</sup>|✅|✅|
|OPUS|✅|✅|✅|🔶<sup>5</sup>|✅|✅|🔶<sup>5</sup>|✅|✅|✅|✅|
[Format Cheatsheet:](https://en.wikipedia.org/wiki/Moving_Picture_Experts_Group#External_links)
|[MPEG-1](https://en.wikipedia.org/wiki/MPEG-1)|[MPEG-2](https://en.wikipedia.org/wiki/MPEG-2)|
|:---:|:---:|
|[MP2 (layer 2)](https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_II)|[AAC (Part 7)](https://en.wikipedia.org/wiki/Advanced_Audio_Coding)|
|[MP3 (layer 3)](https://en.wikipedia.org/wiki/MP3)||
<sup>1</sup>MP3 Mono is incorrectly reported as unsupported and will transcode to AAC.
<sup>2</sup>Only EAC3 2.0 has been tested.
<sup>3</sup>OGG containers are not supported and will cause VORBIS to convert.
<sup>4</sup>Only DTS Mono has been tested.
<sup>5</sup>Safari only supports opus in `.caf` files
<sup>6</sup>Supported via passthrough on all devices. Native support for AC3 & E-AC3 on Roku TVs & Ultra.
ATSC Standard for [AC-3 and EAC-3](https://www.atsc.org/wp-content/uploads/2015/03/A52-201212-17.pdf).
## [Subtitle Compatibility](https://en.wikipedia.org/wiki/Comparison_of_video_container_formats#Subtitle/caption_formats_support "Wikipedia's subtitle codec tables")
Subtiles can be a subtle issue for transcoding. Containers have a limited number of subtitles that are supported. If subtitles need to be transcoded, it will happen one of two ways: they can be converted into another format that is supported, or burned into the video due to the subtitle transcoding not being supported. Burning in subtitles is the most intensive method of transcoding. This is due to two transcodings happening at once; applying the subtitle layer on top of the video layer.
Here is a [breakdown](https://www.afterdawn.com/guides/archive/subtitle_formats_explained.cfm) of common subtitle formats.
||Format|TS|MP4|MKV|AVI|
|:---:|:---:|:---:|:---:|:---:|:---:|
|[SubRip Text (SRT)](https://en.wikipedia.org/wiki/SubRip)|Text|❌|🔶|✅|🔶|
|[WebVTT (VTT)](https://en.wikipedia.org/wiki/WebVTT)<sup>1</sup>|Text|❌|❌|✅|🔶|
|ASS/SSA|Formatted Text|❌|❌|✅|🔶|
|VobSub<sup>2</sup>|Picture|✅|✅|✅|🔶|
|MP4TT/TXTT|XML|❌|✅|❌|❌|
|PGSSUB|Picture|❌|❌|✅|❌|
|EIA-608/708<sup>3</sup>|Embedded|✅|✅|✅|❌|
<sup>1</sup>VTT are supported in an [HLS Stream](https://helpx.adobe.com/adobe-media-server/dev/webvtt-subtitles-captions.html).
<sup>2</sup>DVB-SUB [(SUB + IDX)](https://forum.videohelp.com/threads/261451-Difference-between-SUB-and-IDX-file) is another name for VobSub files.
<sup>3</sup>EIA-608/708 subtitles are embedded in private channels (channel 21) in a MPEG video codec. EIA-608 are standard CC subtitles with the black bar background, while EIA-708 are typically SDH.
### Types of Subtitles
There are many variations of subtitles. Closed, open, burned-in, forced, SDH, and CC are among the common types of subtitles. The format (such as SubRIP or VobSUB) does not matter for the type of subtitle.
#### Closed Subtitles
This is the generic name for subtitles that can be turned on or off. This can be Forced, SDH, CC or normal subtitles.
#### Burned-in
Open subtitles (also known as burned-in subtitles) are subtitles that have been permanently placed in the video and cannot be turned off. Open subtitles are the most common type of subtitles, where the subtitles are part of the video stream and cannot be toggled on or off.
#### SDH and Closed Captioning
SDH and CC are subtitles for the Deaf and Hard of Hearing. They include extra content such as background noises. SDH and CC are not defined by a specific type of subtitle, just by their intent. If using an OTA Tuner and DVR, the subtitles will be [embedded](https://evertz.com/resources/eia_608_708_cc.pdf) into the video and transcoding them before extracting the subtitles will destroy the subtitles.
#### Forced
"Forced subtitles are common on movies and only provide subtitles when the characters speak a foreign or alien language, or a sign, flag, or other text in a scene is not translated in the localization and dubbing process. In some cases, foreign dialogue may be left untranslated if the movie is meant to be seen from the point of view of a particular character who does not speak the language in question." - [Wikipedia](https://en.wikipedia.org/wiki/Subtitles#Categories)
### Extracting Subtitles
To extract subtitles, the following commands can be used. The section `0:s:0` means the first subtitle, so `0:s:1` would be the second subtitle.
#### SSA/ASS Subtitles
```bash
ffmpeg -dump_attachment:t "" -i file.mkv -map 0:s:1 -c:s ass extracted-subtitle.ass
```
#### Recorded OTA Content
Content recorded OTA will typically have subtitles [embedded](https://aberdeen.io/blog/2009/06/18/the-basics-of-608-vs-708-captions/) into the video codec itself. These subtitles are typically EIA-608 for analog and EIA-708 for digital.
```bash
ffmpeg -f lavfi -i "movie=Ronin (1998).ts[out+subcc]" -map 0:1 "Ronin (1998).srt"
```
## [Container Compatibility](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers)
If the container is unsupported, this will result in remuxing. The video and audio codec will remain intact, but wrapped in a supported container. This is the least intensive process. Most video containers will be remuxed to use the HLS streaming protocol and TS containers. Remuxing shouldn't be a concern even for an RPi3.
||Chrome|Edge|Firefox|Safari|Android|Android TV|Kodi|Roku|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|[MP4](https://en.wikipedia.org/wiki/MPEG-4_Part_14)<sup>1</sup>|✅|✅|✅|✅|✅|✅|✅|✅|
|[MKV](https://en.wikipedia.org/wiki/Matroska)<sup>2, 3</sup>|❌|✅|❌|❌|✅|✅|✅|✅|
|[WebM](https://en.wikipedia.org/wiki/WebM)<sup>3, 5</sup>|✅|✅|✅|❌|✅|✅|✅|✅|
|[TS](https://en.wikipedia.org/wiki/MPEG_transport_stream)<sup>4</sup>|✅|✅|✅|✅|✅|✅|✅|✅|
|[OGG](https://en.wikipedia.org/wiki/Ogg)<sup>5</sup>|✅|✅|✅|❌|✅|✅|✅|✅|
<sup>1</sup>MP4 containers are one of the few containers that will not remux.
<sup>2</sup>MKV containers can hold nearly any codec, but are not compatible with streaming in Firefox and will remux.
<sup>3</sup>MKV containers are improperly labeled as WebM in Firefox during playback.
<sup>4</sup>TS is one of the primary containers for streaming for Jellyfin.
<sup>5</sup>WebM and OGG have limited codec support (by design), refer to [this](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#WebM) for WebM and [this](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#Ogg) for OGG.

View File

@ -0,0 +1,632 @@
---
uid: clients-css-customization
title: CSS Customization
---
# CSS Customization
In `Dashboard > General`, the "Custom CSS" field can be used to override current CSS in Jellyfin's stylesheet.
[Custom CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) provides customization such as changing colors, changing layouts, and item size and behavior. Below is a list of various tweaks that can be applied. The CSS tweaks work on both the web client, and the [Android application](https://play.google.com/store/apps/details?id=org.jellyfin.mobile&hl=en_US). The code will apply in the order that it is written, however `!important` will overrule everything. To learn more about `!important` and more, see [CSS Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) or [specifishity](https://specifishity.com/). To implement these changes, go to `Dashboard > General > Custom CSS` to start.
If you have little or no experience with CSS, various resources and tutorials can be found online. Using the tweaks and examples below makes it quite easy to get started with making your own changes to your Jellyfin instance.
![Screenshot of the 'Custom CSS' setting in the administrator dashboard of the web client](~/images/custom-css-customcssfield.png)
## General Information About CSS
You can learn more about CSS using sites like [w3schools](https://www.w3schools.com/css/default.asp) and [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS). Below are some very basic CSS knowledge that will let you do rough edits to the pre-made tweaks below.
### Colors
CSS supports multiple color formats, but typically the hex color codes are used for specific colors. To get a specific color, exact color data such as the hex codes below have to be used.
Some examples of hex color codes:
* Green: `#5dd000`
* Blue: `#0000d0`
* Red: `#d00000`
* Transparent Black: `#00000058`
Go [here](https://htmlcolorcodes.com/color-picker) for a hex color chart to get a code for any given color.
If you are looking for a more standard and less specific color, typing the literal name of colors suits that purpose well. For example, to get the color "yellow" you can simply write "yellow", this will use a preset yellow color.
`yellow` Yellow <br>
`red` Red <br>
`aquamarine` Aquamarine <br>
`lightseagreen` Light Sea Green
Go [here](https://www.w3schools.com/colors/colors_names.asp) for a list of color names supported.
### Comments
A section of code or text inbetween `/*` and `*/` indicates a comment, and will be ignored.
This allows you to add descriptions for any particular section of code.
It can also be used to disable code without deleting it.
`/* This might be added above code to tell you what it does */`
### CSS Chaining
CSS can be "chained" together to modify different sections together at the same time. An example of this is the "Border Color" tweak. It lists the elements to be modified, and performs a change that is applied to all of them.
"Border Color" tweak:
```css
.emby-input, .emby-textarea, .emby-select { border-color: #d00000; }
```
## Tweak List
To apply any one of these tweaks, copy and paste the CSS code from the example into the "Custom CSS" field. To use multiple tweaks, simply add them one after another into the field. Any applied code will remain in the field. To remove a tweak, delete or comment out the code for it from the field. Changes apply immediately when the settings page is saved and doesn't require restarting your Jellyfin server.
### Played Indicator
This will affect the played/watched indicator. Replace the hex color with any value you like.
### Indicators Without Tweak
![Screenshot of the default watched indicators](~/images/custom-css-normalwatched.png)
### Green Indicators
```css
.playedIndicator { background: #5dd000; }
```
![Screenshot of watched indicators with a custom green color applied](~/images/custom-css-greenwatched.png)
### Transparent And Dark Indicators
```css
/* Make watched icon dark and transparent */
.playedIndicator {background: #00000058;}
```
![Screenshot of watched indicators with a custom transparent color applied](~/images/custom-css-transparentwatched.png)
### Display external links in mobile layout
The mobile app disables display of external links to IMDb, TheMovieDB, Trakt, etc by default.
To enable the external links again, add the following snippet:
```css
.layout-mobile .itemExternalLinks {
display: block !important;
}
```
### Hide Home Icon from Header
```css
.headerHomeButton { display: none; }
.headerButton.headerButtonRight.headerUserButton.paper-icon-button-light { display: none; }
```
### Hide Cast Icon from Header
```css
.headerCastButton { display: none; }
```
### Hide Sync Icon from Header
```css
.headerSyncButton { display: none; }
```
### Hide User Settings from Header
```css
.material-icons.person { display: none; }
```
### Hide Live TV Channel Listings
```css
.guideChannelNumber { display: none; }
```
### Reduce Live TV Channel Width
```css
.channelsContainer { max-width: 8em; }
```
### Hide Cast & Crew
```css
#castCollapsible { display: none; }
```
### Hide More Like This
```css
#similarCollapsible { display: none; }
```
### Hide Next Up
```css
div.nextUpSection { display: none; }
```
### Hide Star Ratings
```css
div.starRatingContainer { display: none; }
```
### Replace "Latest Movies" text with Custom Text such as "Recently Added Movies"
```css
#homeTab > div > div.section2 > div:nth-child(1) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a > h2 {display: none;}
#homeTab > div > div.section2 > div:nth-child(1) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a > span {display: none;}
#homeTab > div > div.section2 > div:nth-child(1) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a:after {
content: 'Recently Added Movies ';
font-size: 24px;
font-weight: normal;
}
```
### Replace Latest TV Shows text with Custom Text such as "Recently Added TV Shows"
```css
#homeTab > div > div.section2 > div:nth-child(2) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a > h2 {display: none;}
#homeTab > div > div.section2 > div:nth-child(2) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a > span {display: none;}
#homeTab > div > div.section2 > div:nth-child(2) > div.sectionTitleContainer.sectionTitleContainer-cards.padded-left > a:after {
content: 'Recently Added TV Shows ';
font-size: 24px;
font-weight: normal;
}
```
### Background Image on Login Page
```css
#loginPage {
background: url("https://i.ytimg.com/vi/avCWDDox1nE/maxresdefault.jpg");
background-size: cover;
}
```
### Background Image on Homepage
```css
.backdropImage { display: none; }
.backgroundContainer {
background-color: rgba(0, 0, 0, 0);
background-image: url("https://i.ytimg.com/vi/avCWDDox1nE/maxresdefault.jpg");
filter: blur(10px);
background-size: cover;
}
```
[Additional MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
### Transparent Top Menu
```css
.skinHeader.focuscontainer-x.skinHeader-withBackground.skinHeader-blurred {background:none; background-color:rgba(0, 0, 0, 0);}
.skinHeader.focuscontainer-x.skinHeader-withBackground.skinHeader-blurred.noHomeButtonHeader {background:none; background-color:rgba(0, 0, 0, 0);}
```
### Image Edge Rounded
```css
.cardContent-button,
.itemDetailImage {
border-radius: 0.25em;
}
```
### Enlarge Tab Buttons
Enlarges the tab buttons, suggested, genres, etc. By default they are really tiny, especially on mobile.
```css
/* Adjust both "size-adjust" and "size" to modify size */
.headerTabs.sectionTabs {text-size-adjust: 110%; font-size: 110%;}
.pageTitle {margin-top: auto; margin-bottom: auto;}
.emby-tab-button {padding: 1.75em 1.7em;}
```
**The enlarged tab buttons and transparent menu look like this:**
![Screenshot of enlarged tab buttons and transparent menu](~/images/custom-css-transparenttopbarenlargedtabs.png)
### Minimalistic Login Page
This looks even better together with the transparent top menu!
```css
/* Narrow the login form */
#loginPage .readOnlyContent, #loginPage form {max-width: 22em;}
/* Hide "please login" text, margin is to prevent login form moving too far up */
#loginPage h1 {display: none}
#loginPage .padded-left.padded-right.padded-bottom-page {margin-top: 50px}
/* Hide "manual" and "forgot" buttons */
#loginPage .raised.cancel.block.btnManual.emby-button {display: none}
#loginPage .raised.cancel.block.btnForgotPassword.emby-button {display: none}
```
![Screenshot of the minimalistic login page](~/images/custom-css-minimallogin.png)
### Stylized Episode Previews
The episode previews in season view are sized based on horizontal resolution. This leads to a lot of wasted space on the episode summary and a high vertical page, which requires a lot of scrolling. This code reduces the height of episode entries, which solves both problems.
```css
/* Size episode preview images in a more compact way */
.listItemImage.listItemImage-large.itemAction.lazy {height: 110px;}
.listItem-content {height: 115px;}
.secondary.listItem-overview.listItemBodyText {height: 61px; margin: 0;}
```
![Screenshot of a TV show page with stylized episode previews](~/images/custom-css-episodepreview.png)
### Stylized and Smaller Cast & Crew Info
This will drastically change the style of cast info into something very similar to how Plex approaches it. This override will lead to somewhat smaller thumbnails, and also works with all themes.
```css
/* Shrink and square (or round) cast thumnails */
#castContent .card.overflowPortraitCard.personCard.card-hoverable.card-withuserdata {width: 4.2cm !important; font-size: 90% !important;}
#castContent .card.overflowPortraitCard.personCard.card-withuserdata {width: 4.2cm !important; font-size: 90% !important;}
/* Correct image aspect ratio behaviour, set border-radius to zero for square tiles */
#castContent .cardContent-button.cardImageContainer.coveredImage.cardContent.cardContent-shadow.itemAction.lazy {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground1.cardContent.cardContent-shadow.itemAction {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground2.cardContent.cardContent-shadow.itemAction {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground3.cardContent.cardContent-shadow.itemAction {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground4.cardContent.cardContent-shadow.itemAction {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardContent-button.cardImageContainer.coveredImage.defaultCardBackground.defaultCardBackground5.cardContent.cardContent-shadow.itemAction {background-size: cover; !important; border-radius: 2.5cm;}
#castContent .cardScalable {width: 3.8cm !important; height: 3.8cm !important; border-radius: 2.5cm;}
#castContent .cardOverlayContainer.itemAction {border-radius: 2.5cm;}
/* Center the mouseover buttons */
#castContent .cardOverlayButton-br {bottom: 4%; right: 15%; width: 70%;}
#castContent .cardOverlayButton.cardOverlayButton-hover.itemAction.paper-icon-button-light {margin:auto;}
```
![Screenshot of stylized and smaller Cast & Crew info](~/images/custom-css-stylizedcast.png)
### Pictureless Cast & Crew
```css
#castContent .card.overflowPortraitCard { width: 4.2cm; font-size: 90%; }
#castContent .personCard { width: auto; }
#castContent .personCard .cardBox { margin-bottom: 0px; margin-right: 0px; }
#castContent { flex-wrap: wrap; max-height: 9.75em; }
div.personCard > :first-child > :first-child { display: none; }
.itemDetailPage .cardText { text-align: left; }
.itemDetailPage .textActionButton { text-align: left; }
```
![Screenshot of Pictureless Cast & Crew info](~/images/custom-css-nopicturecast.png)
### Custom Background Color
```css
.backgroundContainer, .dialog, html { background-color: #0fd0d0; }
```
### Darken the Background
This darkens the background on Blue Radiance and Purple Haze, edit the percentage depending how dark you want it. Lower is darker.
```css
/* Darken background, only works with blue radiance */
.backgroundContainer {background-color: #000000; filter: brightness(50%);}
```
### Right Header Color
This modifies the colors of the cast, search and user buttons in the top right.
```css
.headerRight { color: yellow; }
```
![Screenshot of a custom yellow color for the icon buttons in the top right of the screen](~/images/custom-css-rightheader.png)
### Console Panel Custom Color
Modifies the color of the left menu panel.
```css
.mainDrawer-scrollContainer { color: yellow; }
```
![Screenshot of a custom yellow color on the left menu panel](~/images/custom-css-consolepanel.png)
### General Page Custom Color
```css
.dashboardGeneralForm { color: yellow; }
```
![Screenshot of a custom yellow color on the General Page](~/images/custom-css-generalcolor.png)
### Custom Border Color
This will change the border color for text fields and drop-down menus.
```css
.emby-input, .emby-textarea, .emby-select { border-color: #d00000; }
```
This will affect the border color of highlighted (selected) text fields and drop-down menus.
```css
.emby-input:focus, .emby-textarea:focus, .emby-select-withcolor { border-color: #ffffff !important; }
```
![Screenshot of a custom red border color](~/images/custom-css-bordercolor.png)
### Full Header Tweak
```css
.skinHeader, .mainDrawer, .emby-input, .emby-textarea, .emby-select, .navMenuOption-selected, .cardBox, .paperList { background: #ff9475; }
```
![Screenshot of the full header tweak](~/images/custom-css-full-header-mod.png)
### Disable Image Carousel for Libraries
This will make it so libraries and media fit neatly onto the homepage with no left to right scrolling required.
```css
@media all and (min-width: 50em) {
.homePage .emby-scroller {
margin-right: 0;
}
.homePage .emby-scrollbuttons {
display: none;
}
.homePage .itemsContainer {
flex-wrap: wrap;
}
}
```
### Shift Scroller Buttons
```css
.emby-scrollbuttons {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 0;
justify-content: space-between;
pointer-events: none;
}
.emby-scrollbuttons-button {
pointer-events: initial;
}
```
### "Hotdogs and Catsup" Color Theme Example
An example of a color theme.
![Screenshot of the "Hotdogs and Catsup" color theme](~/images/custom-css-hotdog-and-catsup.png)
```css
.skinHeader, .mainDrawer, .emby-input, .emby-textarea, .emby-select, .navMenuOption-selected, .cardBox, .paperList {
background: #ff9475;
}
.emby-input, .emby-textarea, .emby-select {
border-color: #fdbe7d;
}
.backgroundContainer.withBackdrop, .backdropContainer, .backgroundContainer {
background: #fdbe7d;
}
#myPreferencesMenuPage .listItemBodyText,
.emby-tab-button[data-index="0"],
#myPreferencesMenuPage > div > div > div > a:nth-child(odd),
.button-submit,
.mainAnimatedPage *:nth-child(odd),
.dashboardGeneralForm *:nth-child(odd),
.mainDrawer-scrollContainer *:nth-child(odd),
.headerRight *:nth-child(odd) {
color: red;
}
#myPreferencesMenuPage .listItemIcon,
.emby-tab-button[data-index="1"],
#myPreferencesMenuPage > div > div > div > a:nth-child(even),
.mainAnimatedPage *:nth-child(even),
.dashboardGeneralForm *:nth-child(even),
.mainDrawer-scrollContainer *:nth-child(even),
.headerRight *:nth-child(even)
.cancel {
color: yellow;
}
```
### Floating Now Playing Controls
![Screenshot of the floating "Now Playing" controls](~/images/custom-css-floatingnowplaying.png)
```css
/* fixed height for the bottom row */
:root {
--element-fixed-top: 95px;
}
/* Now playing bar in the footer */
.nowPlayingBar {
width: 650px;
z-index: 10;
position: fixed;
top: 300px;
height: 120px;
border-style: solid;
border-color: white;
background-color: black;
margin-left: 50%;
}
/* Only child of nowPlayingBar */
.nowPlayingBarTop {
height: 5px !important;
max-width: 500px
top: 10px;
}
/* Song progress seekbar */
.nowPlayingBarPositionContainer {
position: relative;
top: 1.0em !important;
}
/* Container that holds album thumbnail, artist and album name */
.nowPlayingBarInfoContainer {
position: fixed !important;
left: 12px;
top: 34px;
height: 60px;
width: 1100px;
}
/* Holds the next, previous track, play/pause, next and time elements */
.nowPlayingBarCenter {
position: relative !important;
left: 32px;
top: var(--element-fixed-top);
min-width: 500px;
}
/* Hold mute, volume slider container, repeat, favorite and remote control buttons */
.nowPlayingBarRight {
width: 402px !important;
left: -60px;
}
/* Mute button */
.muteButton {
position: relative;
top: var(--element-fixed-top);
}
/* Volume slider */
.nowPlayingBarVolumeSliderContainer {
position: relative;
left: -4px;
top: var(--element-fixed-top);
}
/* Toggle repeat */
.toggleRepeatButton {
position: relative !important;
left: -20px;
top: var(--element-fixed-top);
}
/* Favorite */
.nowPlayingBarUserDataButtons {
position: relative;
left: -4px;
top: var(--element-fixed-top);
}
/* Remote control */
.remoteControlButton {
left: -110px;
top: var(--element-fixed-top);
}
```
### Change Icon Pack
You can choose between Material Icons (Icon Pack used by Jellyfin) and Fontawesome icons.
Material Icons:
* Outlined:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Outline.css");
```
* Rounded:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/round.css");
```
* Sharp:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Sharp.css");
```
Fontawesome Icons:
* Solid:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/solid.css");
```
* Regular:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/regular.css");
```
* Light:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/light.css");
```
* duotone:
```css
@import url(https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/duotone.css");
```
## Community Links
Some links to places where custom CSS has been discussed and shared!
### Community Posts
Keep in mind that these posts may have been made under previous versions of Jellyfin. Some of these tweaks listed in these guides may not work anymore!
* [Custom CSS Guide](https://www.reddit.com/r/jellyfin/comments/fgmu6k/custom_css_updated_for_1050)
* ["But wait, there is more Custom CSS!"](https://www.reddit.com/r/jellyfin/comments/htrfrx/but_wait_there_is_more_custom_css)
* [Customizable Plug n' Play CSS for Jellyfin](https://www.reddit.com/r/jellyfin/comments/g9gmjj/customizable_plug_n_play_css_for_jellyfin)
* [Easy Jellyfin custom CSS](https://www.reddit.com/r/jellyfin/comments/crxqk5/easy_jellyfin_custom_css)
* [Custom CSS - updated for 10.5.0](https://www.reddit.com/r/jellyfin/comments/fgmu6k/custom_css_updated_for_1050)
* [Sharing even more custom CSS (and some fixes to previous stuff)](https://www.reddit.com/r/jellyfin/comments/bvnt65/sharing_even_more_custom_css_and_some_fixes_to)
* [Posting my Jellyfin Custom CSS](https://www.reddit.com/r/jellyfin/comments/p13yqg/posting_my_jellyfin_custom_css/)
### Community Themes
* [Monochromic - A custom theme for Jellyfin mediaserver created using CSS overrides](https://github.com/CTalvio/Monochromic)
* [Kaleidochromic - Yet another custom theme for Jellyfin mediaserver created using CSS overrides, built on top of Monochromic](https://github.com/CTalvio/Kaleidochromic)
* [Novachromic - A light theme, built on top of Monochromic](https://github.com/CTalvio/Novachromic)
* [JellySkin - Vibrant Jellyfin theme with a lot a animations](https://github.com/prayag17/JellySkin)
* [JellyFlix - The Best Netflix Clone for Jellyfin](https://github.com/prayag17/JellyFlix)
* [Jellyfin Netflix Dark - The Best Netflix Dark Theme for Jellyfin Around!](https://github.com/DevilsDesigns/Jellyfin-Netflix-Dark)
* [Dark and Green - A Emby like night mode skin](https://github.com/mbcooper83/jellyfin-css-darkandgreen)
* [Hint of Green](https://github.com/looi-wh/HintOfGreenCSS)

View File

@ -0,0 +1,441 @@
---
uid: clients-index
title: Clients
---
# Clients
Clients connect your devices to your Jellyfin server and let you view your content on any supported device. You can find a list of clients below with their current development status.
> [!NOTE]
> If you are interested in helping out, please see our [contribution guide](xref:contrib-index) and feel free to contact us for more information!
>
> If they aren't on this page, some clients can be found at the [jellyfin-archive organization on GitHub](https://github.com/jellyfin-archive).
Do you have a client that interfaces with Jellyfin and want to see it listed here? Please [submit a pull request](https://github.com/jellyfin/jellyfin-docs)!
## Browsers
Our goal is to provide support for the two most recent versions of these browsers.
- Firefox
- Firefox ESR
- Chrome
- Chrome for Android
- Safari for MacOS and iOS
- Edge
Older browsers may be supported as a result of the needs of specific web-based clients, but full functionality is not guaranteed on their desktop version.
## Android
### Jellyfin for Android
The official Jellyfin Android app, which supports Android 5 and above.
**Status:** ⭐ Active
**Links:**
<a href="https://play.google.com/store/apps/details?id=org.jellyfin.mobile">
<img width="153" src="https://jellyfin.org/images/store-icons/google-play.png" alt="Jellyfin on Google Play"/>
</a>
<a href="https://www.amazon.com/gp/aw/d/B081RFTTQ9">
<img width="153" src="https://jellyfin.org/images/store-icons/amazon.png" alt="Jellyfin on Amazon Appstore"/>
</a>
<a href="https://f-droid.org/en/packages/org.jellyfin.mobile/">
<img width="153" src="https://jellyfin.org/images/store-icons/fdroid.png" alt="Jellyfin on F-Droid"/>
</a>
- [GitHub](https://github.com/jellyfin/jellyfin-android)
- [Download](https://jellyfin.org/clients/#android)
### Jellyfin for Android TV and Amazon Fire TV
Jellyfin Android TV is the official Jellyfin client for Android TV, NVIDIA Shield, and Amazon Fire TV devices.
**Status:** ⭐ Active
**Links:**
<a href="https://play.google.com/store/apps/details?id=org.jellyfin.androidtv">
<img width="153" src="https://jellyfin.org/images/store-icons/google-play.png" alt="Jellyfin for Android TV on Google Play"/>
</a>
<a href="https://www.amazon.com/gp/aw/d/B07TX7Z725">
<img width="153" src="https://jellyfin.org/images/store-icons/amazon.png" alt="Jellyfin for Android TV on Amazon Appstore"/>
</a>
- [GitHub](https://github.com/jellyfin/jellyfin-androidtv)
- [Download](https://jellyfin.org/clients/#androidtv)
### Gelli
Native music player for Android devices with transcoding support, gapless playback, favorites, playlists, and many other features. The code is based on a relatively recent version of Phonograph and contributions are welcome!
**Status:** ⭐ Active, 3rd-Party
**Links:**
<a href="https://f-droid.org/packages/com.dkanada.gramophone/">
<img width="153" src="https://jellyfin.org/images/store-icons/fdroid.png" alt="Gelli on F-Droid"/>
</a>
- [GitHub](https://github.com/dkanada/gelli)
- [Download](https://github.com/dkanada/gelli/releases)
### Yatse
A third party remote control for Jellyfin with support for Chromecast playback.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [Website](https://yatse.tv)
### MrMC
A third party app with direct play and HDR support. Available on Android, Android TV, Fire TV, and iOS/Apple TV.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [Website](https://mrmc.tv)
### Findroid
Findroid is a third-party Android application for Jellyfin that provides a native user interface to browse and play movies and series.
**Status:** ⭐ Active, 3rd-Party
**Links:**
<a href='https://play.google.com/store/apps/details?id=dev.jdtech.jellyfin'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' width="153"/>
</a>
<a href='https://apt.izzysoft.de/fdroid/index/apk/dev.jdtech.jellyfin'><img alt='Get it on IzzyOnDroid' src='https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png' width="153"/>
</a>
- [Github](https://github.com/jarnedemeulemeester/findroid)
## Roku
### Jellyfin for Roku
The official Jellyfin Roku app.
**Status:** ⭐ Active
**Links:**
<a href='https://channelstore.roku.com/details/592369/jellyfin'><img alt='Get it on the Roku Store' src='https://upload.wikimedia.org/wikipedia/commons/thumb/8/8c/Roku_logo.svg/1280px-Roku_logo.svg.png' width="200"/></a>
- [GitHub](https://github.com/jellyfin/jellyfin-roku)
## Cross-Platform Clients
### Jellyfin Media Player
Desktop client using jellyfin-web with embedded MPV player. Supports direct play of most file
formats on Windows, Mac OS, and Linux. Media plays within the same window using the
jellyfin-web interface unlike Jellyfin Desktop. Supports audio passthrough. Based on Plex Media Player.
**Status:** ⭐ Active
**Links:**
- [Github](https://github.com/jellyfin/jellyfin-media-player)
- [Binary Releases](https://github.com/jellyfin/jellyfin-media-player/releases)
- [Flathub](https://flathub.org/apps/details/com.github.iwalton3.jellyfin-media-player)
### Jellyfin Audio Player
A third party standalone music streaming app for iOS and Android. This client includes full support for background audio and casting.
**Status** ✅ In Development, 3rd-Party
**Links:**
- [GitHub](https://github.com/leinelissen/jellyfin-audio-player)
- [TestFlight install for iOS](https://testflight.apple.com/join/cf2AMDpx)
- [Download for Android](https://github.com/leinelissen/jellyfin-audio-player/releases)
### Jellyfin MPV Shim
Provides background cast client using MPV. The client has support for direct play of advanced codecs such as 10 bit HEVC with subtitles, many customizable options, and whole-season subtitle preference support.
**Status:** ⭐ Active
**Links:**
- [Github](https://github.com/jellyfin/jellyfin-mpv-shim)
- [Windows Release](https://github.com/jellyfin/jellyfin-mpv-shim/releases)
- [Flathub](https://flathub.org/apps/details/com.github.iwalton3.jellyfin-mpv-shim)
### Jellycli
Terminal player for Jellyfin, only for music at the moment.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitHub](https://github.com/tryffel/jellycli)
### Jellyfin-CLI
Terminal player for Jellyfin, written in Python.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitHub](https://github.com/marios8543/Jellyfin-CLI)
- [PyPI](https://pypi.org/project/Jellyfin-CLI)
### Jellyamp
Desktop client for listening to music from a Jellyfin server.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [Github](https://github.com/m0ngr31/jellyamp)
### Preserve
Music client inspired by players such as foobar2000 or Clementine. Available on desktop or web.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitLab](https://gitlab.com/tonyfinn/preserve)
- [Browser](https://preserveplayer.com)
### Finamp
A third party app for music playback. Supports offline mode/downloading songs.
**Status** ⭐ Active, 3rd-Party
**Links:**
<a href="https://play.google.com/store/apps/details?id=com.unicornsonlsd.finamp">
<img width="153" src="https://jellyfin.org/images/store-icons/google-play.png" alt="Finamp on Google Play"/>
</a>
<a href="https://apps.apple.com/us/app/finamp/id1574922594">
<img width="153" src="https://developer.apple.com/app-store/marketing/guidelines/images/badge-example-preferred.png" alt="Download on the App Store"/>
</a>
<a href="https://f-droid.org/packages/com.unicornsonlsd.finamp/">
<img width="153" src="https://jellyfin.org/images/store-icons/fdroid.png" alt="Finamp on F-Droid"/>
</a>
- [GitHub](https://github.com/UnicornsOnLSD/finamp)
## Web
### Web Scrobbler
Extension for browsers based on Chromium and Firefox that allows scrobble services like libre.fm and last.fm.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitHub](https://github.com/web-scrobbler/web-scrobbler)
- [Website](https://web-scrobbler.github.io)
## Linux
### Tauon Music Box
Tauon Music Box is a modern streamlined music player for desktop with a minimal interface that's packed with features! An emphasis on playlists and direct file importing puts you in control of your music collection.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitHub](https://github.com/Taiko2k/TauonMusicBox)
- [Flatpak](https://flathub.org/apps/details/com.github.taiko2k.tauonmb)
- [Website](https://tauonmusicbox.rocks)
### jftui
A terminal client for Jellyfin built as a REPL interface, that uses mpv for multimedia playback.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [GitHub](https://github.com/Aanok/jftui)
## Apple
### Jellyfin for iOS
The official Jellyfin iOS client.
**Status:** ⭐ Active
**Links:**
<a href='https://apps.apple.com/us/app/jellyfin-mobile/id1480192618'><img alt='Download on the App Store' src='https://developer.apple.com/app-store/marketing/guidelines/images/badge-example-preferred.png'/></a>
- [GitHub](https://github.com/jellyfin/jellyfin-expo)
### SwiftFin for iOS/tvOS
The Jellyfin app rewritten in Swift in order to support HDR and direct play capabilities for multiple formats.
**Status:** ✅ In Development
**Links:**
<a href='https://testflight.apple.com/join/oZd0QzWv'><img height='70' alt='Join the Beta on TestFlight' src='https://anotherlens.app/testflight-badge.png'/></a>
- [GitHub](https://github.com/jellyfin/SwiftFin)
### Infuse for iOS/Apple TV
A third party client with HDR support and direct play capabilities for multiple formats.
**Status:** ⭐ Active, 3rd-Party
**Links:**
<a href='https://apps.apple.com/app/id1136220934?mt=8'><img alt='Download on the App Store' src='https://developer.apple.com/app-store/marketing/guidelines/images/badge-example-preferred.png'/></a>
- [Website](https://firecore.com/infuse)
### MrMC for iOS/Apple TV
A third party app with direct play and HDR support. Available on iOS and Apple TV.
**Status:** ⭐ Active, 3rd-Party
**Links:**
- [Website](https://mrmc.tv)
## Kodi
### Jellyfin for Kodi
Kodi thick client for Jellyfin. This add-on syncs your Jellyfin metadata into Kodi's local database for a more native feel.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-kodi)
- [Installing](xref:clients-kodi)
### JellyCon
Kodi thin client for Jellyfin. This add-on is fully dynamic and allows for fast user switching and is compatible with other Kodi sources.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/jellyfin/jellycon)
- [Installing](xref:clients-kodi)
## LG WebOS
### Jellyfin for WebOS
The official Jellyfin WebOS app.
**Status:** ✅ In Development
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-webos)
## Mopidy
### Mopidy-Jellyfin
An official plugin for Mopidy that uses Jellyfin as a backend.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/jellyfin/mopidy-jellyfin)
- [Installing](xref:clients-mopidy)
## Samsung TV
### Jellyfin for Tizen
The official Jellyfin Samsung TV client for TVs running Tizen (2015 and above models).
**Status:** ✅ In Development
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-tizen)
## UWP
### Jellyfin UWP Client
A wrapper around Jellyfin's web interface for UWP devices (Windows 10, Windows Phone 10, Xbox One, Windows IOT, etc.)
**Status:** ✅ In Development
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-uwp)
### Videotape
A 3rd party UWP media player with support for Jellyfin.
**Status:** ⭐ Active, 3rd-Party
**Links:**
<a href='//www.microsoft.com/store/productId/9nlvh2ll4p1z?cid=storebadge&ocid=badge'><img alt='Get it from Microsoft' src='https://developer.microsoft.com/en-us/store/badges/images/English_get-it-from-MS.png' width="200"/></a>
- [Website](https://usuaia.com/videotape)
## Volumio
### Jellyfin for Volumio
A plugin for Volumio that uses Jellyfin as a backend.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/patrickkfkan/volumio-jellyfin)
## Discord
### Discord Music Bot
A Discord bot that allows playing your Jellyfin music library in Discord voice channels.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/kgt1/jellyfin-discord-music-bot)
## Popcorn Hour / Syabas
### Jellyfin-NMT
A proxy that generates YAMJ style HTML compatible with A-100/A-110 Popcorn Hour Network Media Tank devices.
**Status:** ⭐ Active
**Links:**
- [GitHub](https://github.com/SenorSmartyPants/jellyfin-nmt)

View File

@ -0,0 +1,171 @@
---
uid: clients-kodi
title: Kodi
---
# Kodi
## Add-on Repository
There are two different Kodi add-ons that serve slightly different use cases.
* [Jellyfin for Kodi](https://github.com/jellyfin/jellyfin-kodi) - This add-on syncs metadata from selected Jellyfin libraries into the local Kodi database. This has the effect of making interacting with it feel very much like vanilla Kodi with local media (shows up under Movies/TV Shows on the home screen by default, virtually no delay, etc). However, it also tends to consume the database and not share well, so if you have local media or something else that interacts with the database directly, you'll have conflicts and it won't be happy. The sync process can take some extra time on Kodi startup if you don't leave it running 24/7, but it's mostly in the background while Kodi is running.
* [JellyCon](https://github.com/jellyfin/jellycon) - Behaves more like a standard Kodi streaming add-on. Media is accessed primarily by going through the Add-ons -> JellyCon menu, however you can set up menu options to link to it and show info on the home screen. It also allows easier switching between multiple Jellyfin servers or users since it doesn't have to rely on syncing all the metadata down. By not having metadata synced, it has to request info from the server which can take a bit more time when you're browsing (typically only a second or two in my testing), but you don't have to wait for the database to sync or keep it up to date.
### Install Add-on Repository
The most convenient install method of our Jellyfin add-ons is to use the official Kodi Jellyfin Repository. Using this repository allows for easy install of our add-ons, as well as automatically keeping the add-ons up to date with the latest version. Any other Jellyfin related add-ons that may be built in the future will also be available here.
The installation method for the repository varies depending on what kind of device you're using, outlined below.
#### General Use Devices (PCs and Tablets)
1. Download the repository installer found [here](https://kodi.jellyfin.org/repository.jellyfin.kodi.zip).
* It will be saved as `repository.jellyfin.kodi.zip`
2. Install the Jellyfin repository.
* Open Kodi, go to the settings menu, and navigate to "Add-on Browser"
* Select "Install from Zip File"
* If prompted, enter settings and enable "Unknown Sources", then go back to the Add-on Browser
* Select the newly downloaded file and it will be installed
#### "Embedded" Devices (Android TV, Firestick, and other TV Boxes)
1. Open Kodi, go to the settings menu, and navigate to "File manager"
* Select "Add source"
* In the text box, enter `https://kodi.jellyfin.org`
* Enter a name for the data source, such as "Jellyfin Repo" and select Ok
2. From the settings menu, navigate to "Add-on Browser"
* Select "Install from Zip File"
* If prompted, enter settings and enable "Unknown Sources", then go back to the Add-on Browser
* Select the data source you just added
* Install `repository.jellyfin.kodi.zip`
## Jellyfin for Kodi
> [!TIP]
> It's highly recommended to install the `Kodi Sync Queue` plugin into the Jellyfin server as well.
> This will keep your media libraries up to date without waiting for a periodic re-sync from Kodi.
> [!CAUTION]
> Remote Kodi databases, like MySQL, are not supported. A local SQLite database is required (this is the default).
### Jellyfin for Kodi Overview
This add-on syncs metadata from selected Jellyfin libraries into the local Kodi database. This has the effect of making interacting with it feel very much like vanilla Kodi with local media. This means that our Jellyfin content will be displayed on the home screen under the proper media headings by default, it has virtually no delay while interacting with the library, etc. However, it also assumes that it's the only media source and in largely incompatible with other media sources that interact with Kodi's database.
Media in Kodi's database is automatically kept in sync with the server in one of several ways:
* Startup sync - Each time Kodi starts, it will reach out to the Kodi Sync Queue plugin in the server and request all updated media since it's last checkin time (when Kodi was last shut down)
* Live sync - This happens while Kodi is running. When the server updates an item, it will send a notification to Kodi over a websocket connection that it has new media that needs to be updated.
### Install Jellyfin for Kodi Add-on
1. Install Jellyfin for Kodi.
* From within Kodi, navigate to "Add-on Browser"
* Select "Install from Repository"
* Choose "Kodi Jellyfin Add-ons", followed by "Video Add-ons"
* Select the Jellyfin add-on and choose install
2. Within a few seconds you should be prompted for your server details.
* If a Jellyfin server is detected on your local network, it will displayed in a dialog
* If a Jellyfin server is not detected on your local network, select "Manually Add Server". Enter your server info into the text field.
* Enter the server name or IP address and the port number (default value is 8096)
* Host: `192.168.1.10:8096`
* If using SSL and a reverse proxy, enter the full URL in the "Host" field
* Host: `https://jellyfin.example.com`
* Note that if you have a baseurl set, you should append that value to the end of the host field.
* Host: `192.168.0.10:8096/jellyfin`
* Select user account and input password, or select "Manual Login" and fill in your user infomation
3. Once you're succesfully authenticated with the server, you'll be asked about which mode you'd like to use, Add-on vs Native, which are outlined below.
#### Add-on Mode
Add-on mode uses the Jellyfin server to translate media files from the filesystem to Kodi. This is the default setting for the add-on, and is sufficient for most use cases. It will work both on the local network and over the Internet through a reverse proxy or VPN connection. Providing network speed is sufficient, Kodi will direct play nearly all files and put little overhead on the Jellyfin server.
To use Add-on mode, simply choose "Add-on" at the dialog and proceed to [Library Syncing](xref:clients-kodi#library-syncing)
#### Native Mode
Native mode accesses your media files directly from the filesystem, bypassing the Jellyfin server during playback. Native mode needs more setup and configuration, but it can, on rare occasions, lead to better performance where network bandwidth is a limitation. It requires your media to be available to the device Kodi is running on over either NFS or Samba, and therefore should only be used on a LAN or over a VPN connection.
To use Native mode, first set up your libraries in Jellyfin with a remote path.
1. In the Jellyfin server, navigate to the Libraries section of the admin dashboard.
* Select an existing library (or create a new one)
* Select the media folder
* Enter the path to your network share in the "Shared network folder" textbox
* Possible formats:
* NFS
* `nfs://192.168.0.10:/path/to/media`
* Samba
* Guest User - `\\192.168.0.10\share_name`
* Custom User (Not Recommended) - `\\user:password@192.168.0.10\share_name`
* It's more secure to use the generic Guest mapping here and specify credentials from within Kodi
* Mounted share
* If you have mounted your network share, you can reference the local mount point. This can be more performant but generally means it only works for one type of operating system, given the difference between the file systems
* `/mnt/media` (Linux)
* `Z:\media` (Windows)
* `/Volumes/media` (Mac OS)
2. Configure libraries in Kodi
* Skip the initial library selection. We need to add file shares to Kodi first
* Within Kodi, navigate to the settings menu and select "File manager"
* Select "Add source"
* Select "Browse" and "Add network location"
* Create either a NFS or SMB location from the selection box and fill in the necessary information about your network share
* If you are using a mounted share, browse to the mount point on your file system rather than the network share
* Select your newly created location and choose "Ok"
* Give your media source a name and choose "Ok"
* Go to Add-ons -> Jellyfin -> Manage Libraries -> Add Libraries
3. Proceed to [Library Syncing](xref:clients-kodi#library-syncing)
#### Library Syncing
This screen allows you to choose which libraries to sync to your Kodi install. This process will copy metadata for your media into the local Kodi database, allowing you to browse through your media libraries as if they were native to your device.
Either choose "All" or select individual libraries you'd like synced, and select OK. Syncing the metadata will start automatically. The duration of this process varies greatly depending on the size of your library, the power of your local device, and the connection speed to the server.
You can still access any libraries that haven't been synced by going through the Jellyfin add-on menu. These unsynced libraries will be labeled as "dynamic."
If an error occurs during syncing, enable debug logging in the Jellyfin add-on in Kodi and if in a Unix-like OS, set the **log level** of Samba to 2 to see if there are issues authenticating.
### Multiple User Accounts
The Jellyfin for Kodi add-on doesn't natively handle multiple user accounts. Fortunately, Kodi has a built in method of handling this called profiles. Information about this can be found on the Profiles page of the [Kodi Wiki](https://kodi.wiki/view/Profiles). Once profiles have been created, you must install the Jellyfin add-on and go through the installation steps above for each user profile. When you switch Kodi profiles, you will also switch Jellyfin users. You can tell Kodi to bring you to a profile login screen during startup by going to the Profiles section inside of the Settings page and checking the box for "Show login screen on startup."
> [!NOTE]
> Kodi's default skin does not display all unicode characters. To display unicode characters the skin's font must be changed.
### Multiple Clients
When using multiple Kodi clients do not copy Kodi's database (i.e. `myvideosXYZ.db`, `jellyfin.db`) files from one client to the other to try and reduce initial syncing time. This will partially work, but it will cause conflicts between clients and the sync process from the server won't work properly.
## JellyCon
### JellyCon Overview
JellyCon behaves more like a standard Kodi streaming add-on. Media is accessed primarily by going through the Add-ons -> JellyCon menu, however depending on what skin is being used custom shortcuts and widgets can be added to the home menu. It also allows easier switching between multiple Jellyfin servers or users since it doesn't have to rely on syncing all the metadata down. By not having metadata synced, it has to request info from the server which can take a bit more time when you're browsing, but you don't have to wait for the database to sync or keep it up to date. It's also compatible with other media sources and can be used with other add-ons without issue.
### Install JellyCon Add-on
1. Instally JellyCon Add-on
* From within Kodi, navigate to "Add-on Browser"
* Select "Install from Repository"
* Choose "Kodi Jellyfin Add-ons", followed by "Video Add-ons"
* Select the JellyCon add-on and choose install
2. Within a few seconds you should be prompted for your server details.
* If a Jellyfin server is detected on your local network, it will displayed in a dialog. Otherwise, you will be prompted for a URL
* Select a user from the list, or Manual Login to type in a username/password
### Configuring Home
Many Kodi skins allow for customizing of the home menu with custom nodes and widgets. However, all of these use slightly different layouts and terminology. Rather than a step by step guide, this section serves as an barebones introduction to customizing a skin.
#### Examples
If you would like a link on the home screen to open a library in your Jellyfin server called "Kid's Movies", you would point the menu item to the path: `Add-On -> Video Add-On -> JellyCon -> Jellyfin Libraries -> Kid's Movies -> Create menu item to here`.
Beyond just modifying where the home menu headers go, many skins also allow you to use widgets. Widgets help populate the home screen with data, often the posters of media in the selected image. If you would like to display the most recent movies across all of your Jellyfin libraries on the home screen, the path would be: `Add-On -> Video Add-On -> JellyCon -> Global Lists -> Movies -> Movies - Recently Added (20) -> Use as widget`
Another common use case of widgets would be to display the next available episodes of shows that you may be watching. As above, this can be done both with individual libraries or with all libraries combined:
* `Add-On -> Video Add-On -> JellyCon -> Jellyfin Libraries -> Anime -> Anime - Next Up (20) -> Use as widget`
* `Add-On -> Video Add-On -> JellyCon -> Global Lists -> TV Shows -> TV Shows - Next Up (20) -> Use as widget`

View File

@ -0,0 +1,117 @@
---
uid: clients-mopidy
title: Mopidy
---
# Installing Mopidy Extension
The Mopidy Jellyfin extension is available to install from [PyPi](https://pypi.org/project/Mopidy-Jellyfin) using pip.
## General
For general use computers, such as workstations or laptops, it's recommended to install Mopidy extensions in user mode. Installing python packages from pip using sudo or root permissions can lead to conflicts with your package manager in the future.
1. Install Mopidy using your method of choice using the [official documentation](https://docs.mopidy.com/en/latest/installation/)
2. Install the Jellyfin extension for Mopidy:
```sh
pip3 install --user mopidy-jellyfin
```
3. (Optional) Install other mopidy related packages:
```sh
pip3 install --user mopidy-mpd mopidy-musicbox-webclient
```
4. Configure your `mopidy.conf` located at `$HOME/.config/mopidy/mopidy.conf`
See [Config File](xref:clients-mopidy#config-file)
5. There may be a need to install extra `gstreamer` codecs if they're not already on your system, but these are highly variable and depend on your hardware and distro
6. Start the program by running `mopidy` from a terminal
7. See [Usage](xref:clients-mopidy#usage)
## Raspberry Pi (Remote Controlled Speakers)
Utilizing a Raspberry Pi (or other small form factor computer) it's possible to use Mopidy to build a set of standalone smart speakers connected to your Jellyfin server.
1. Grab the latest [raspbian image](https://www.raspberrypi.org/downloads/raspbian/). Unless you have a need for a GUI, the 'Lite' image is plenty for this project.
2. Install the image to the SD card (See the [official documentation](https://www.raspberrypi.org/documentation/installation/installing-images/README.md))
3. Install Mopidy from their [apt repo](https://docs.mopidy.com/en/latest/installation/debian/#install-from-apt-mopidy-com) to ensure we get the latest version
4. Install required OS packages:
```sh
sudo apt install mopidy mopidy-mpd gstreamer1.0-plugins-bad python3-pip
```
5. Install the Jellyfin extension and any other Mopidy related packages you may want:
```sh
sudo pip3 install mopidy-jellyfin mopidy-musicbox-webclient
```
6. Configure your `mopidy.conf` located at `/etc/mopidy/mopidy.conf`:
See [Config File](xref:clients-mopidy#config-file)
7. Enable and start the mopidy service:
```sh
sudo systemctl enable --now mopidy
```
8. See [Usage](xref:clients-mopidy#usage)
## Config File
The config file for Mopidy is divided into sections in an INI format. An example for Jellyfin is shown here.
```ini
[jellyfin]
hostname = Jellyfin server hostname
username = username
password = password
libraries = Library1, Library2 (Optional: will default to "Music" if left undefined)
albumartistsort = False (Optional: will default to True if left undefined)
album_format = {ProductionYear} - {Name} (Optional: will default to "{Name}" if left undefined)
```
* `libraries` determines what is populated into Mopidy's internal library (view by Artists/Album/etc). Using the file browser will show all music or book libraries in the Jellyfin server
* `albumartistsort` changes whether the media library populates based on "Artist" or "Album Artist" metadata
* `album_format` can be used to change the display format of music albums when using the file browser view. Currently the only really usable fields are ProductionYear and Name
Other options that may be useful to include:
```ini
[mpd]
enabled = true
# Useful if you want to control this instance from a remote MPD client
hostname = 0.0.0.0
port = 6600
# This will help avoid timeout errors for artists or folders with large amounts of files
connection_timeout = 300
# Used in the event you want to control this system from a web browser
[http]
hostname = 0.0.0.0
port = 6680
```
Be aware that Mopidy provides no security on open ports, so if you'll be running this in a public place you'll likely want to change `0.0.0.0` to `127.0.0.1` to prevent somebody else from hijacking your listening session.
## Usage
Once Mopidy is running, you can connect and control it with your client of choice. MPD clients will connect using port 6600 by default. Tested MPD clients include [ncmpcpp](https://github.com/arybczak/ncmpcpp) and [M.A.L.P](https://play.google.com/store/apps/details?id=org.gateshipone.malp). Web clients can be reached at `http://localhost:6680`, or `http://$IP_ADDRESS:6680` if this is a remote system.
## Upgrading
When a new version of Mopidy Jellyfin is released, you can upgrade via pip using the `--upgrade` flag.
```sh
pip3 install --user --upgrade mopidy-jellyfin
```

View File

@ -0,0 +1,78 @@
---
uid: clients-web-config
title: Jellyfin Web Configuration
---
# Jellyfin Web Configuration
## Editing
The Jellyfin Web default interface can be configured using the `config.json` file in the webroot. Where this is and how to edit it depends on the installation method.
We recommend obtaining the [stable](https://github.com/jellyfin/jellyfin-web/blob/release-10.7.z/src/config.json) or the [unstable](https://github.com/jellyfin/jellyfin-web/blob/master/src/config.json) default version of the file to pre-populate your configuration directory before starting Jellyfin for the first time; unlike most other components of this directory, it will not be created automatically.
### Debian/Ubuntu/Fedora/CentOS Packages
The configuration can be found at `/usr/share/jellyfin/web/config.json`. This file is registered as a configuration file by the Debian packages, and any changes to the defaults will be handled by `apt` on upgrade.
### Docker
Overriding the default `config.json` can be done with an additional volume parameter to your `docker run` command, e.g.
```sh
--volume /path/to/config/web-config.json:/jellyfin/jellyfin-web/config.json
```
> [!NOTE]
> If the config.json file doesn't exist on the first run, Docker will map it to a directory instead of a file, which won't work.
## Customizations
### Custom Menu Links
Jellyfin 10.8 adds the ability to specify custom links to be inserted in the navigation menu via the `config.json` file.
Links are configured with a `name`, `url`, and optional `icon` property.
The icon is specified using the name of an icon from the [Material Design Icons](https://jossef.github.io/material-design-icons-iconfont/) used in Jellyfin Web.
By default the "link" icon will be used.
```json
"menuLinks": [
{
"name": "Custom Link",
"url": "https://jellyfin.org"
},
{
"name": "Custom Link w. Custom Icon",
"icon": "attach_money",
"url": "https://demo.jellyfin.org/stable"
}
]
```
## Privacy-focused changes
Our default settings for the Jellyfin Web `config.json` file include some features that privacy-focused or completely-offline users may want to disable. Each option is detailed below.
### Google Chromecast
By default, Jellyfin Web includes Chromecast-from-browser support. This requires downloading files from Google servers to support this functionality.
To disable it, edit `config.json` and remove the line:
```json
"plugins/chromecastPlayer/plugin"
```
in the `plugins` section. Be sure to remove the last comma from the line above if this is the last line in the list.
### YouTube Trailers
By default, Jellyfin Web includes functionality to auto-load movie trailers from YouTube. This functionality is disabled within Jellyfin by default, but the resources are included in the Web config to make enabling the feature easy.
To disable it, edit `config.json` and remove the line:
```json
"plugins/youtubePlayer/plugin"
```
in the `plugins` section.

View File

@ -0,0 +1,52 @@
---
uid: community-standards
title: Jellyfin Community Standards
---
# Jellyfin Community Standards
As time marches on and Jellyfin, and the Internet more broadly, continues to grow, it is important to establish standards by which community members should interact. While there are numerous such "Codes of Conduct" out there, I am not a fan of most, and I felt it important to establish our own, suited to our project, as well as a dispute resolution mechanism tailored to our needs. Questions about this document should be directed towards me. --Joshua, Project Leader
## Mission Statement
* Jellyfin aims to be the best media streaming platform possible, built entirely by volunteers without any monetary gain, proprietary/locked features, or unreasonable centralization.
* Jellyfin is a project made up entirely and exclusively of Volunteers who donate their free time to the project.
* Fostering a community of respectful and productive contributors is central to our success and longevity.
* Jellyfin is not and will never be under the control of any corporation or profit-driven entity, and does not exist to make money for anyone, including any volunteer contributors or the project leadership.
## Code of Conduct
At all times when interacting with the Jellyfin community via any method (Matrix, Reddit, Forums, etc.), you must abide by the following:
* **Respect others and remember the Human.** Do exhibit kindness and empathy to others, and make them feel welcome. Do not antagonize, flame, insult, demean, abuse, or harass others. Do not use slurs or sexualized language. Do not dox or otherwise expose others' private information, even if it is shared publicly elsewhere.
* **English is the primary working language of Jellyfin, but the majority of our community do not speak English as their primary language**. Be patient when language issues arise, and do not mistake incomplete language knowledge for ignorance or worse. Always act in good faith and give other contributors the benefit of the doubt, and try to read positivity rather than negativity into messages where at all possible. If you are having trouble communicating an idea in English, please post in your native language and ask for help, and someone is likely to understand. As per rule 1, abuse of community members due to language issues is not tolerated.
* Jellyfin, as set out in our Mission Statement, is created exclusively by volunteers. As they are freely giving their time and effort, **no volunteer contributor owes anything whatsoever to any other contributor, any user, or the project itself**. Contributors are free to come and go as they please, to work on and give attention to what they deem interesting or important, and to respond or not respond to anything they wish. That said the administrative team would kindly request that regular contributors inform us of long-term departures to ensure we are aware, should the need arise.
* If you have questions to ask of the community, **please choose the appropriate location** (see our [Getting Help](xref:getting-help) page) and **ask your question in full, immediately, with as much detail as possible**. Author issues aside, [Asking Questions the Smart Way](http://www.catb.org/~esr/faqs/smart-questions.html) is a valuable resource. **Do not pester or harass** community members for help or to answer questions, **do not require others to pry information** out of you, and **do not spam questions** - they will be answered when they are answered.
* Jellyfin is a media server system for your own media collection. Our communities are not a place to obtain media. **Do not engage in, encourage, or facilitate piracy**. Do not ask questions about where to obtain media. Do not ask for access to other users' servers, or sell or transfer access to private servers in our communities.
## Dispute Resolution and Moderation
Disputes are inevitable, including violations of the rules above. When these occur, the following policy applies.
* Before any other resolution step, we trust the community to police itself. If you see a community member violating these community standards, please let them know, and link them to this document. Do not respond in kind (e.g. respond to a flame with a flame). Most disagreements can be solved with education and discussion.
* If the issue cannot be resolved between the contributors, any complaints, instances of explicit rulebreaking, or unresolvable disagreements with other community members may be directed towards the Administrative team, or the Project Leaders directly. You may do so through email (`team [at] jellyfin.org`) or on Matrix via a direct message. Please include details and context as appropriate.
* The team will review the complaint and decide on an action, including but not limited to: informal private guidance, informal private warnings, formal public warnings, temporary ban(s) from the various platforms, or permanent ban(s).
* Formal warnings will be made under a "second-chance-only" policy. Once warned, if one repeats the same behaviour, the response will escalate as appropriate to the infraction.
* Moderation tasks in some locations are delegated to other team members. This dispute resolution procedure applies anywhere under the Jellyfin umbrella. The Administrative team and Project Leaders retain final say in any dispute resolutions.
## Changelog
This document represents official Jellyfin project policy. Any changes to this document require a changelog entry here and approval by a Project Leader.
2020-09-14, Joshua Boniface: Initial version of the community standards document. Based *very* loosely on several CoCs including the Contributor Covenant, and various Forum rules I've read and written over the years.

View File

@ -0,0 +1,58 @@
---
uid: contrib-branding
title: Branding
---
# Branding
## Usage of the Jellyfin name
You are free to use the Jellyfin name to promote your project, with some restrictions:
* Do not use the Jellyfin name in a way that would make the average user think you are associated with the project, unless permission was given by the Project Leader or Leadership Team.
* Only include the Jellyfin name in your project's name in a way that makes it clear you are not affiliated with the Jellyfin project, and to indicate compatibility with Jellyfin (For example *Awesome Client for Jellyfin*).
* Do not use the Jellyfin name in any context that promotes, allows or encourages piracy.
* Do not wrongfully claim to be part of the Jellyfin team.
## Writing Style
As a general rule, Jellyfin should always be capitalized, but language, file, or system conventions trump Jellyfin naming conventions.
Specific examples include:
* Writing referring to the project in the abstract should use capitalized `Jellyfin` at all times. `I contribute to Jellyfin and you should too!`
* C# class and project names, including their files and directories, should use capitalized `Jellyfin` as required by the C# case standards (camelCase or PascalCase). `Jellyfin.LiveTv`, `Jellyfin.sln`
* Other code elements, where the code formatting or style requires lowercase, should use lowercase `jellyfin`. `jellyfinWebComponentsBowerPath`
* The Git repository and non-C# files inside of it should use lowercase `jellyfin` for convenience on case-sensitive filesystems. `build-jellyfin.ps1`
* The final output binary, initscrips, and package names should use lowercase `jellyfin` for similar reasons as above. `jellyfin.dll`, `jellyfin_3.5.2-1_all.deb`, `jellyfin.zip`
* Configuration directories can use either depending on operating system conventions. `/var/lib/jellyfin`, `AppData/Jellyfin`
* The logo has no strict rules for capitalization, the style is dependent on aesthetics and font choice.
## Icons and Other Assets
All iconography and other resources can be found in the [jellyfin-ux](https://github.com/jellyfin/jellyfin-ux) repository.
* Icons
* Banners
* Fonts
### Logo
When using the full version of the logo, the text should only be placed to the right of the icon.
![The logo should have the text placed on the right of the icon.](~/images/branding-logo-yes-side.png) ![The logo should never have the text placed below the icon.](~/images/branding-logo-no-below.png)
The design for the logo uses a gradient for the infill, and if the non-transparent logo is chosen there is an optional background color.
* Gradient Start: `#AA5CC3`
* Gradient End: `#00A4DC`
* Background Colour: `#000B25`
### Theme
* Background Colour: `#101010`
* Accent Colour: `#00A4DC`
### Fonts
The banner uses the [Quicksand](https://fonts.google.com/specimen/Quicksand) font.

View File

@ -0,0 +1,208 @@
---
uid: contrib-development
title: Development
---
# How to contribute code to Jellyfin
This page details how our repositories are organized, how to get started editing the code and creating your first pull request, and some general procedures around pull requests in Jellyfin.
## What should you work on?
There are many projects within the [organization](https://github.com/jellyfin) to browse through for contributions.
Summarized here are the two biggest ones, one for backend devs and another for frontend devs.
* [Jellyfin Server](https://github.com/jellyfin/jellyfin): The server portion, built using .NET 6 and C#.
* [Jellyfin Web](https://github.com/jellyfin/jellyfin-web): The main client application built for browsers, but also used in some of our other clients that are just wrappers.
Note that each of the repositories also has its own documentation on how to get started with that project, generally found in the repository README. You can also view the organization [source tree](xref:contrib-source-tree) to see how some of the bigger projects are structured.
The best way to get going on some actual development is to look through the [issues list](https://github.com/jellyfin/jellyfin/issues) of the associated repository, find an issue you would like to work on, and start hacking! Issues are triaged regularly by the administrative team, and labels assigned that should help you find issues within your skill-set. Once you start working on an issue, please comment on it stating your intent to work on the issue, to avoid unnecessary duplication of work.
### Major Issue Types
A list of issue types can be found on the [issue guidelines](xref:contrib-issues#issue-labels) section.
### What if there isn't an issue?
If there isn't already an issue dealing with the changes you want to make, please [create an issue](xref:contrib-issues) to track it first, then ensure your PR(s) reference the issue in question. This is especially useful for bugs that are found and then fixed by the author, so both the original issue and the fix can be documented and tracked in detail.
## How should you make changes?
Once you've found something you want to work on or improve, the next step is to make your changes in the code, test them, then submit a Pull Request (PR) on GitHub.
For simplicity, all examples assume the developer is operating on Linux with SSH access to GitHub, however the general ideas can be applied to HTTP-based GitHub interfaces, and can be translated to Windows or MacOS.
If you aren't familiar with Git, we recommend the [official documentation](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control) to understand how this version control system works and how to use it.
### Set up your copy of the repo
The first step is to set up a copy of the Git repository of the project you want to contribute to. Jellyfin follows a "fork, feature-branch, and PR" model for contributions.
1. On GitHub, "Fork" the Jellyfin repository you wish to contribute to, to your own user account using the "Fork" button in the relevant repository.
2. Clone your fork to your local machine and enter the directory:
```sh
git clone git@github.com:yourusername/projectname.git
cd projectname/
```
3. Add the "upstream" remote, which allows you to pull down changes from the main project easily:
```sh
git remote add upstream git@github.com:jellyfin/projectname.git
```
4. To get the `Jellyfin.Server` project to run successfully, checkout both the [server](https://github.com/jellyfin/jellyfin), as well as the [web client](https://github.com/jellyfin/jellyfin-web) project.
5. Build the Jellyfin Web project with NPM, and copy the location of the resulting `dist` folder.
6. In your `Jellyfin.Server` project add an environment variable named `JELLYFIN_WEB_DIR` with the value set to the full path of your `dist` folder.
You will now be ready to begin building or modifying the project.
### Make changes to the repo
Once you have your repository, you can get to work.
1. Rebase your local branches against upstream `master` so you are working off the latest changes:
```sh
git fetch --all
git rebase upstream/master
```
1. Create a local feature branch off of `master` to make your changes:
```sh
git checkout -b my-feature master
```
1. Make your changes and commits to this local feature branch.
1. Repeat step 1 on your local feature branch once you're done your work, to ensure you have no conflicts with other work done since you stated.
1. Push up your local feature branch to your GitHub fork:
```sh
git push --set-upstream origin my-feature
```
1. On GitHub, create a new PR against the upstream `master` branch following the advice below.
1. Once your PR is merged, ensure you keep your local branches up-to-date:
```sh
git fetch --all
git checkout master
git rebase upstream/master
git push -u origin master
```
1. Delete your local feature branch if you no longer need it:
```sh
git branch -d my-feature
```
### CONTRIBUTORS.md
If it's your first time contributing code to a particular repository, please add yourself to the `CONTRIBUTORS.md` file at the bottom of the `Jellyfin Contributors` section. While GitHub does track this, having the written document makes things clearer if the code leaves GitHub and lets everyone quickly see who's worked on the project for copyright or praise!
## Official Branches
### Feature Branches
From time to time, major projects may come up that require multiple PRs and contributions from multiple people. For these tasks, feature branches specific to the feature should be created, based off of `master`. This helps allow the work to progress without breaking `master` for long periods, and allowing those interested in that particular project the ability to work at their own pace instead of racing to fix a broken feature before the next release. To create a feature branch, please communicate with a Core team member and that can be arranged.
Once the feature a feature branch was created for is ready, it can be merged in one shot into `master` and the feature branch removed. Alternatively, for very-long-lived features, certain "stable" snapshots can be merged into `master` as required.
### The Master Branch
The `master` branch is the primary face of the project and main development branch. Except for emergency release hotfixes, all PRs should target `master`. As a general rule, no PR should break master and all PRs should be tested before merging to ensure this does not occur. We're only human and this is still likely to happen, but you should generally be safe to build off of `master` if you want the latest and greatest version of Jellyfin.
## Testing a Pull Request
To test someone else's pull request, you must import the changes to your local repository.
1. Fetch the changes in a pull request and link them to a new local branch:
```sh
git fetch upstream pull/<PR_ID>/head:my-testing-branch
```
> [!NOTE]
> `<PR_ID>` is pull request number on GitHub.
1. Checkout the new local branch:
```sh
git checkout my-testing-branch
```
1. Perform any testing or build required to test, then return to master and delete the branch:
```sh
git checkout master
git branch -D my-testing-branch
```
## Pull Request Guidelines
When submitting a new PR, please ensure you do the following things. If you haven't, please read [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) as it is a great resource for writing useful commit messages.
* Before submitting a PR, squash "junk" commits together to keep the overall history clean. A single commit should cover a single significant change: avoid squashing all your changes together, especially for large PRs that touch many files, but also don't leave "fixed this", "whoops typo" commits in your branch history as this is needless clutter in the final history of the project.
* Write a good title that quickly describes what has been changed. For example, "Add LDAP support to Jellyfin". As mentioned in [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/), always use the imperative mood, and keep the title short but descriptive. The title will eventually be a changelog entry, so please try to use proper capitalization but no punctuation; note that the Core team may alter titles to better conform to this standard before merging.
* For anything but the most trivial changes that can be described fully in the (short) title, follow the PR template and write a PR body to describe, in as much detail as possible:
1. Why the changes are being made. Reference specific issues with keywords (`fixes`, `closes`, `addresses`, etc.) if at all possible.
2. How you approached the issue (if applicable) and briefly describe the changes, especially for large PRs.
* If your pull request isn't finished yet please mark it as a "draft" when you open it. While this tag is in place, the pull request won't be merged, and reviews should remain as comments only. Once you're happy with the final state of your PR, please remove this tag; forgetting to do so might result in your PR being unintentionally ignored as still under active development! Inactive WIPs may occasionally elicit pings from the team inquiring on the status, and closed if there is no response.
* Avoid rebasing and force-pushing to large or complex pull requests if at all possible, and especially after reviews. It forces unnecessary reviews to verify the changes are still okay and build properly.
* Expect review and discussion. If you can't back up your changes with a good description and through review, please reconsider whether it should be done at all. All PRs to `dev` require at least one approving review from an administrative team member, however we welcome and encourage reviews from any contributor, especially if it's in an area you are knowledgeable about. More eyes are always better.
* All PRs require review by at least two team members before being merged into `master`, though reviews from any contributor are welcome! After the second team member review the PR may be merged immediately, or more review or feedback requested explicitly from other contributors if required.
## Building and Testing Inside a Docker Container
We need to install all development dependencies and pull down the code inside the container before we can compile and run.
> [!NOTE]
> Run each command on a separate line. The container we'll test in is named `jftest`. Within Docker, anytime the entrypoint executable is terminated, the session restarts, so just exec into it again to continue. This is also why we explicitly kill it to reload the new version.
### Master Branch
```sh
docker exec -ti jftest bash
apt-get update && apt-get install git gnupg wget apt-transport-https curl autoconf g++ make libpng-dev gifsicle automake libtool make gcc musl-dev nasm
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg && mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/debian/10/prod.list && mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
apt-get update && apt-get install dotnet-sdk-6.0 npm
cd /opt && git clone https://github.com/jellyfin/jellyfin.git && git clone https://github.com/jellyfin/jellyfin-web.git
cd jellyfin/ && DOTNET_CLI_TELEMETRY_OPTOUT=1 dotnet publish --disable-parallel Jellyfin.Server --configuration Debug --output="/jellyfin" --self-contained --runtime linux-x64
cd /opt/jellyfin-web && npm install && cp -r /opt/jellyfin-web/dist /jellyfin/jellyfin-web
kill -15 $(pidof jellyfin)
```
### Pull Request
First, complete the steps above to setup your container to build the master branch.
> [!NOTE]
> `<PR_ID>` is pull request number on GitHub.
```sh
docker exec -ti jftest bash
cd /opt/jellyfin
git fetch origin pull/<PR_ID>/head:my-testing-branch
git merge my-testing-branch
dotnet build
kill -15 $(pidof jellyfin)
```

View File

@ -0,0 +1,34 @@
---
uid: contrib-index
title: Contributing
---
# Contributing to Jellyfin
Thank you for your interest in contributing to the Jellyfin project! This page and its children describe the ways you can contribute, as well as some of our policies. This should help guide you through your first Issue or PR.
Even if you can't contribute code, you can still help Jellyfin! The two main things you can help with are testing and creating issues. Contributing to code, documentation, translations, and other non-code components are all outlined in the sections below.
## Reporting Issues
We use GitHub extensively to track open issues, new enhancements or features, and other aspects of development.
Please see the [getting help](xref:getting-help) page for help with troubleshooting and finding bugs, and the [documentation on issues](xref:contrib-issues) for more information on how to submit good issues.
## Developing Code
The entire project consists of a C# core server, a Javascript web client, and a number of other clients written in various languages and frameworks. If you have experience with these languages, we're always grateful for any contributions you might want to make!
For general guidelines on how the project works, including how to set up your development copy, make changes, and guidelines on Pull Requests (PRs), please see the [documentation on contributing code](xref:contrib-development). Jellyfin follows a "fork and PR" methodology; if you're not familiar with this, please see the [relevant section](xref:contrib-development#set-up-your-copy-of-the-repo).
## Adding To Documentation
Documentation is incredibly helpful! All these docs are written using [DocFX](https://dotnet.github.io/docfx/). You can find the raw markdown in the [documentation repository](https://github.com/jellyfin/jellyfin-docs). Pull requests are welcome!
## Translating
If you're interested in helping to translate Jellyfin into your local language, we use [Weblate](https://weblate.org/en/) running at [translate.jellyfin.org](https://translate.jellyfin.org) to handle translations. These are collected in the `translations` branches of the various repositories and are merged into the `master` branches before each release.
## Testing
Testing is the easiest way to contribute. Simply use Jellyfin, and if you run into problems, [let us know](xref:getting-help). This is the most common way we uncover bugs, through a user doing something we hadn't thought about. If the issue does end up being related to the code, a [bug issue](xref:contrib-issues#reporting-bugs) can then be opened.

View File

@ -0,0 +1,81 @@
---
uid: contrib-issues
title: Reporting Issues
---
# Reporting Issues
This page discusses how to open issues, including the policies and procedures of the Jellyfin project around handling issues.
Issues should **only** detail software bug reports.
All other discussions, including initial troubleshooting, should be directed towards [our help channels](xref:getting-help).
## Requesting Features
Please note that feature and enhancement requests should be directed towards [our Fider instance](https://features.jellyfin.org) for tracking, voting, and reporting. Please keep all feature requests to this page and not GitHub issues.
## Searching and Voting
Before opening an issue, please [search the existing issues](https://github.com/jellyfin/jellyfin/issues?utf8=✓&q=is%3Aissue) to see if a similar problem or feature request has been reported. Duplicate issues clutter the repository and should be avoided.
If you do find an issue that matches, or closely matches, your issue, please make use of the :+1: reaction to confirm the issue also affects you or that you support the feature request. If you wish, add a comment as well describing your version of the issue or feature use case.
If the existing issue is closed, please read through it to see if the accepted workaround(s) apply to your case. If not, leave a comment and the issue will be reopened. Note that, since PRs go into `dev` first but releases are built from `master`, an issue's fix won't be immediately available in the official sources, but will be included in the next release.
## Opening an Issue
Once you're ready to open an issue, please [see this page](https://github.com/jellyfin/jellyfin/issues/new/choose)!
### Reporting Bugs
When writing an bug issue, please ensure you capture as much relevant detail as possible - this is very important to assist in troubleshooting and triaging/investigating the issue. Some useful elements include:
* How you installed Jellyfin (upgrade or fresh install)
* What platform and operating system you're using (Debian, Arch, Docker, etc.)
* What you were doing that caused the issue to appear
* Any relevant log output
* Any non-standard configurations you use
Bugs should be tagged with `[bug]` at the beginning of their title. This will later be removed by the Jellyfin team when assigning labels. To assist in triaging, if you know which other [label(s)](xref:contrib-issues#issue-labels) should be applied to your issue, please add them after the `[bug]` label.
Bugs should be reproduceable. That is, you should be able to have determined through troubleshooting how to replicate the issue. While one-time bugs shouldn't be ignored, if they're difficult or impossible to reproduce, it's likely very hard to fix them. Please attempt to reproduce the bug before filing the issue, and include the smallest test case you can to demonstrate it.
If you ever need assistance for troubleshooting or opening an issue, please [contact the community](xref:getting-help) and we'll try to help you out!
## Issue Labels
Jellyfin features a number of issue labels to assist in triaging and managing issues. Users cannot assign these themselves due to GitHub's permissions, but they will be added by an team member during triaging.
### Categories
These labels are broad categories for which part of the codebase is affected.
* `backend`: An issue that mainly relates to the server backend code.
* `build`: An issue that mainly relates to the build process.
### Criticality
These labels help determine how critical an issue is.
* `regression`: An issue in need of immediate attention due to a regression from the last build.
* `bug`: A bug in the code that affects normal usage.
### Management
These labels help assist in managing the project and direction.
* `good first issue`: Something that should be very straightforward to do, and is a great place to get started.
* `help wanted`: An issue that currently has no clear expert within the project and could use outside assistance.
* `roadmap`: A meta-issue related to the future roadmap of the project.
* `investigation`: An investigation-type issue into the codebase.
### Pull Requests
These labels apply only to pull requests for administrative purposes.
* `requires testing`: A PR that has not been tested in a live environment yet. Any major backend-affecting PRs should be tested before being merged to avoid regressions.

View File

@ -0,0 +1,129 @@
---
uid: contrib-release-procedure
title: Releases
---
# Release Procedure
This document is a guide for the core team, provided publicly to ensure transparency in the release process.
## Versioning
Jellyfin uses [semantic versioning](https://semver.org). All releases will have versions in the `X.Y.Z` format, starting from `10.0.0`. Note however that the `10.Y.Z` release chain represents the "cleanup" of the codebase, so it should be accepted that `10.Y.Z` breaks all compatibility, at some point, with previous Emby-compatible interfaces, and may also break compatibility with previous `10.Y` releases if required for later cleanup work. Our versioning will typically follow the patterns below:
### X: Major Versions
* Breaks compatibility with the HTTP or plugin APIs
### Y: Minor Versions
* Introduces new features
* Makes minor backwards-compatible API changes
### Z: Hotfix Versions
* Critical bug fixes or minor changes
## General Release Philosophy
Releases will generally be performed on Sundays "when ready". For Major/Minor releases, the "when ready" is generally quite flexible and is whenever the release is truly ready without major breaking bugs. After a major release, each Sunday the Admin team should review the recently merged PRs and, if backports are required, perform a Hotfix release containing those PRs.
### Major Release Procedure
#### Preparation
1. Testing is ongoing via `master` nightly builds, so `master` should be generally unbroken before proceeding. The version of `master` should already reflect the upcoming major release version (i.e. `X.Y.0`).
1. Once `master` is in a generally stable state after extensive work, announce a "golden nightly" is incoming via the [jellyfin-dev](https://matrix.to/#/#jellyfin-dev:matrix.org) Matrix/Riot channel and Reddit.
1. Collect testing information and repeat as needed.
1. Once the release is considered stable and working, announce full PR freeze via the [jellyfin-dev](https://matrix.to/#/#jellyfin-dev:matrix.org) Matrix/Riot channel.
1. Allow one further "golden nightly" and at least 48 hours of testing time. Restart this process if major breaking bugs are found.
1. Once all testing is complete and the release remains stable, proceed.
#### Release Web Client
1. Create a release branch on the [jellyfin-web](https://github.com/jellyfin/jellyfin-web) repository via CLI from `master`, named `release-X.Y.z`, where `X` and `Y` are the new version number, and `z` is a literal `z`. Push the new branch to GitHub.
2. Create a GitHub release for the new version, based on the newly-created `release-X.Y.z` branch. The tag should be named `vX.Y.Z` (i.e. `vX.Y.0`) and the release named "Release X.Y.Z". The release body should contain the following link only, replacing the version as required:
```md
[Please see the release announcement on the main repository.](https://github.com/jellyfin/jellyfin/releases/tag/vX.Y.Z)
```
3. Publish the release.
#### Release Server
1. Create a release branch on the [jellyfin](https://github.com/jellyfin/jellyfin) repository via CLI from `master`, named `release-X.Y.z`, where `X` and `Y` are the new version number, and `z` is a literal `z`. Push the new branch to GitHub.
2. Create a GitHub release for the new version, based on the newly-created `release-X.Y.z` branch. The tag should be named `vX.Y.Z` (i.e. `vX.Y.0`) and the release named "Release X.Y.Z". The release body should contain the following components:
a. A quick top blurb under a `# Jellyfin X.Y.Z` header.
a. A list of features, including in-line links to Fider if available, under a `## New Features and Major Improvements` header.
a. A list of known release notes, categorized by the relevant platform (e.g. `[All]` or `[Windows]`), under a `## Important Release Notes` header.
a. If applicable, a set of release notes/comments about FFmpeg, under a `## FFmpeg` header.
a. A full changelog, split by repository with `### [repo](https://github.com/jellyfin/repo)` subheaders, under a `## Changelog` header. Each element should be a PR number and the PR title.
3. Publish the release.
4. Wait for builds to complete.
5. Announce the new release in the [jellyfin-announce](https://matrix.to/#/#jellyfin-announce:matrix.org) Matrix/Riot channel and anywhere else required (e.g. Reddit, etc.).
### Hotfix Release Procedure
1. During normal work on the `master` branch, select PRs suitable for backporting by tagging them with the `stable-backport` label during the PR lifecycle. All PRs will target `master` and thus bugfixes for the stable release must include this label to be included.
1. Collect the list of merged `stable-backport` PRs from all relevant repositories.
1. For each repository, perform stable branch reconciliation for the relevant PRs:
1. For each PR slated for backport:
1. Grab the *merge commit* hash for the PR from `master` branch.
1. Cherry-pick the merge commit into the `release-x.y.z` branch via: `git cherry-pick -sx -m1 <merge-commit-hash>`.
1. Fix any merge conflicts, generally keeping what's in the merge. If there are significant merge conflicts, this likely indicates that the fix is too large for backporting.
1. Finalize the cherry-pick via: `git add` and `git commit -v`.
1. For the main [jellyfin](https://github.com/jellyfin/jellyfin) repository, bump the version of the repository to the new hotfix version with the `bump_version` script and commit the result with the message "Bump version for X.Y.Z".
1. Push the updated release branch to GitHub.
#### Web Client
1. Create a GitHub release for the new version, based on the relevant `release-X.Y.z` branch. The tag should be named `vX.Y.Z` and the release named "Release X.Y.Z". The release body should contain the following link only, replacing the version as required:
```md
[Please see the release announcement on the main repository.](https://github.com/jellyfin/jellyfin/releases/tag/vX.Y.Z)
```
2. Publish the release on GitHub and the archive repository.
#### Server
1. Create a GitHub release for the new version, based on the relevant `release-X.Y.z` branch. The tag should be named `vX.Y.Z` and the release named "Release X.Y.Z". The release body should contain the following components:
a. A quick top blurb under a `# Jellyfin X.Y.Z` header.
a. A list of known release notes, categorized by the relevant platform (e.g. `[All]` or `[Windows]`), under a `## Important Release Notes` header.
a. If applicable, a set of release notes/comments about FFmpeg, under a `## FFmpeg` header.
a. A full changelog, split by repository with `### [repo](https://github.com/jellyfin/repo)` subheaders, under a `## Changelog` header. Each element should be a PR number and the PR title.
1. Publish the release.
1. Wait for builds to complete.
1. Announce the new release in the [jellyfin-announce](https://matrix.to/#/#jellyfin-announce:matrix.org) channel and anywhere else as required.

View File

@ -0,0 +1,116 @@
---
uid: contrib-source-tree
title: Source Tree
---
# Source Tree
Jellyfin is a maze of clients, plugins, and other useful projects. These source trees can serve as an excellent tool to inform new developers about the structure of several projects.
## [Jellyfin Server](https://github.com/jellyfin/jellyfin)
1. .ci: `Azure Pipelines Build definitions`
2. DvdLib: `DVD Anaylzer`
3. Emby.Dlna: `DLNA support for the server`
- Profiles: `DLNA Profiles for clients`
4. Emby.Drawing: `image processor managing the image encoder and image cache paths`
5. Emby.Naming: `parsers for the media filenames`
6. Emby.Notifications: `listening for events and sending the associated notification`
7. Emby.Photos: `metadata provider for photos`
8. Emby.Server.Implementations: `main implementations of the interfaces`
- ScheduledTasks: `all scheduled tasks can be found here`
9. Jellyfin.Api: `Jellyfin API`
- Controller: `API controllers answering the Jellyfin API requests`
- Helpers:
- MediaInfoHelper.cs: `logic for the stream builder that determines method of playback such as Direct Play or Transcoding`
10. Jellyfin.Data: `models used in the Entity Framework Core Database schema`
11. Jellyfin.Drawing.Skia: `image manipulation like resizing images, making image collages`
12. Jellyfin.Networking: `managing network interaces and settings`
13. Jellyfin.Server.Implementations: `like Emby.Server.Implementations, implementations using the EF Core Database`
14. Jellyfin.Server: `main server project that starts the whole server`
15. MediaBrowser.Common: `common methods used throughout the server`
16. MediaBrowser.Controller: `interface definitions`
17. MediaBrowser.LocalMetadata: `metadata provider and saver for local images, local Collections and Playlists`
18. MediaBrowser.MediaEncoding: `managing ffmpeg while interacting with the media files`
19. MediaBrowser.Model: `defining models used throughout the server`
20. MediaBrowser.Providers: `managing multiple metadata sources`
21. MediaBrowser.XbmcMetadata: `metadata provider and saver for local .nfo files`
22. RSSDP: [RSSDP library](https://github.com/Yortw/RSSDP)`, including custom changes, for the Simple Service Discovery (SSDP) protocol`
23. apiclient: `files used for generating the axios API client`
24. deployment: `files used while building Jellyfin for different plattforms`
25. tests: `multiple Unit Test projects testing Jellyfin functionality`
26. Dockerfile.* `Dockerfiles defining the Jellyfin Docker image`
## [Web Client](https://github.com/jellyfin/jellyfin-web)
1. src:
- assets: `images, styles, splash screens, and any other static assets`
- css: `all global stylesheets used throughout the client`
- img: `images for things like device icons and logos`
- splash: `progressive web apps will show these splash screens`
- components: `custom elements used for different sections of the user interface`
- playerstats.js: `display playback info in browsers and other clients that include the web source`
- controllers: `scripts that handle the logic for different pages`
- elements: `custom UI components that are used globally such as buttons or menus`
- legacy: `currently used for all polyfills and scripts related to backwards compatibility`
- libraries: `dependencies that we eventually want to remove and include during the build step`
- scripts: `any script that isn't tied to a UI element or page but rather general functionality`
- strings: `translations for the entire interface`
- themes: `custom and bundled themes can be found here in their own directories`
## [Android](https://github.com/jellyfin/jellyfin-android)
1. res:
- android:
2. src:
- NativeShell:
- res:
- src:
- RemotePlayerService.java: `handles the notification tile that can control playback`
- www:
- cordova:
## [Android TV](https://github.com/jellyfin/jellyfin-androidtv)
1. app:
- src:
- main:
- java/org/jellyfin/androidtv:
- constant: `constants/enums`
- data:
- compat: `classes ported from old apiclient to maintain compatibility in the app (Deprecated should be replaced/removed)`
- eventhandling: `API webservice event handling`
- model: `various data models`
- querying: `extensions to the querying package in the apiclient (Should probably be replaced/removed)`
- repository: `data repositories for shared access`
- di: `dependency injection modules`
- integration: `Android TV homescreen channel integrations`
- preference: `interface for Android shared preferences`
- ui:
- browsing: `views for browsing items (rows, grids, etc.)`
- home: `home screen views`
- itemdetail: `item detail views`
- itemhandling: `BaseItem views`
- livetv: `live TV views`
- playback: `media player views`
- preference: `app preferences/settings views`
- presentation: `presenters from MVP architecture`
- search: `search views`
- shared: `shared code for UI classes`
- startup: `authentication views`
- util: `various utilities`
- res: `Android resource files for XML layouts, translations, images, etc.`
## [Kodi](https://github.com/jellyfin/jellyfin-kodi)
1. jellyfin_kodi
- database: `manipulating the local Jellyfin sqlite database`
- dialogs: `code behind popup menus for user interaction`
- entrypoint: `main add-on settings page`
- helper: `small helper functions, mostly formatting or reused functions`
- jellyfin: `interacting with the server`
- objects:
- kodi: `handling local Kodi media types and database`
2. resources:
- language: `string files for localization`
- skins: `design of popup menus for user interaction`

50
docs/general/faq.md Normal file
View File

@ -0,0 +1,50 @@
---
uid: faq
title: FAQ
---
# Frequently Asked Questions
## Why fork Emby? Why did you start this project?
We explain our rationale on our [about page](xref:about).
## Why don't you support my favorite client or feature?
Chances are, we'd like to support it! But it hasn't been implemented yet.
Jellyfin is an entirely volunteer-driven project, so until a developer is able and willing to implement a feature, it likely won't be done.
We track our features on [our Fider instance](https://features.jellyfin.org), so please check that out, upvote the features you like, and add your own requests.
If you're a developer and are interested in helping out, [please hack away](xref:contrib-index) and let us know [on Matrix](xref:getting-help) so we can help.
## When will release {X} happen? When will feature {X} be available?
When the Jellyfin team feels it is ready.
Please remember we are all volunteers and want to deliver the best possible experience.
To that end, releases happen when we feel there has been sufficient testing without new issues being found.
Releases are also subject to the availability of the people who manage the builds and publishes for different platforms.
## I'm having problems with Jellyfin, how do I get help?
Please see our [getting help](xref:getting-help) page for details on where to engage the community.
## Why is my media not showing up in Jellyfin?
This normally comes down to one of the following issues:
1. [File permissions](https://wikipedia.org/wiki/File-system_permissions) are not properly configured on your media.
2. Your media does not follow the organizational requirements for Jellyfin's scanner to properly identify media. (Valid organization schemes can be found in the documentation for [Movies](xref:server-media-movies), [Shows](xref:server-media-shows), [Music](xref:server-media-music), and others.)
## How can I contribute to this project?
Please see our [contributing guide](xref:contrib-index) page for details on how to get started.
We are always looking for C# and frontend developers, mobile app developers, translators, and documentation writers to help!
## How do I request a new feature?
Please see our [requesting features](xref:contrib-issues#requesting-features) page for details in requesting a new feature in Jellyfin.
## How do I support this project?
All we can ask is you [use Jellyfin](xref:admin-installing), [report any bugs](xref:contrib-issues#reporting-bugs), and tell your friends about us!
Really, we're just people volunteering our time to help build a better media system, so joining the community is the best way to show your support.
We do offer a donations page [on OpenCollective](https://opencollective.com/jellyfin), however please note that these funds are **only** used for infrastructure. All our developers are unpaid volunteers on principle.

View File

@ -0,0 +1,51 @@
---
uid: getting-help
title: Getting Help
---
# Getting Help
If you are having trouble using or configuring Jellyfin, there are several ways to get help. Please ensure you read our [Community Standards](xref:community-standards) before interacting in any of the following locations.
* The Jellyfin [Matrix channels](https://matrix.to/#/#jellyfinorg:matrix.org): For chat and real-time discussions.
* All channels are bridged to IRC and Discord.
* The Jellyfin [subreddit](https://www.reddit.com/r/jellyfin): For general discussions.
We are also active on social media.
* [Facebook](https://www.facebook.com/Jellyfin-319514125331205)
* [Twitter](https://twitter.com/jellyfin)
## Matrix Channels
* <a href="https://matrix.to/#/#jellyfin:matrix.org"><img alt="jellyfin" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix&label=jellyfin"></a>: General chat related to the project
* <a href="https://matrix.to/#/#jellyfin-announce:matrix.org"><img alt="jellyfin-announce" src="https://img.shields.io/matrix/jellyfin-announce:matrix.org.svg?logo=matrix&label=jellyfin-announce"></a>: Announcements for releases and other important information
* <a href="https://matrix.to/#/#jellyfin-troubleshooting:matrix.org"><img alt="jellyfin-troubleshooting" src="https://img.shields.io/matrix/jellyfin-troubleshooting:matrix.org.svg?logo=matrix&label=jellyfin-troubleshooting"></a>: User troubleshooting
* <a href="https://matrix.to/#/#jellyfin-dev:matrix.org"><img alt="jellyfin-dev" src="https://img.shields.io/matrix/jellyfin-dev:matrix.org.svg?logo=matrix&label=jellyfin-dev"></a>: Main room for development communication
* <a href="https://matrix.to/#/#jellyfin-dev-client:matrix.org"><img alt="jellyfin-dev-client" src="https://img.shields.io/matrix/jellyfin-dev-client:matrix.org.svg?logo=matrix&label=jellyfin-dev-client"></a>: Client and Web development
* <a href="https://matrix.to/#/#jellyfin-dev-android:matrix.org"><img alt="jellyfin-dev-android" src="https://img.shields.io/matrix/jellyfin-dev-android:matrix.org.svg?logo=matrix&label=jellyfin-dev-android"></a>: Android, Android TV and Fire TV development
* <a href="https://matrix.to/#/#jellyfin-dev-ios:matrix.org"><img alt="jellyfin-dev-ios" src="https://img.shields.io/matrix/jellyfin-dev-ios:matrix.org.svg?logo=matrix&label=jellyfin-dev-ios"></a>: iOS, iPadOS, macOS, and tvOS development
* <a href="https://matrix.to/#/#jellyfin-dev-python:matrix.org"><img alt="jellyfin-dev-python" src="https://img.shields.io/matrix/jellyfin-dev-python:matrix.org.svg?logo=matrix&label=jellyfin-dev-python"></a>: Python development
* <a href="https://matrix.to/#/#jellyfin-dev-roku:matrix.org"><img alt="jellyfin-dev-roku" src="https://img.shields.io/matrix/jellyfin-dev-roku:matrix.org.svg?logo=matrix&label=jellyfin-dev-roku"></a>: Roku development
* <a href="https://matrix.to/#/#jellyfin-offtopic:matrix.org"><img alt="jellyfin-offtopic" src="https://img.shields.io/matrix/jellyfin-offtopic:matrix.org.svg?logo=matrix&label=jellyfin-offtopic"></a>: Chat about anything
## IRC Channels
All channels are bridged from Matrix to [Libera.chat](https://libera.chat) for convenience.
* [#jellyfin](ircs://irc.libera.chat:6697/#jellyfin)
* [#jellyfin-announce](ircs://irc.libera.chat:6697/#jellyfin-announce)
* [#jellyfin-troubleshooting](ircs://irc.libera.chat:6697/#jellyfin-troubleshooting)
* [#jellyfin-dev](ircs://irc.libera.chat:6697/#jellyfin-dev)
* [#jellyfin-dev-client](ircs://irc.libera.chat:6697/#jellyfin-dev-client)
* [#jellyfin-dev-android](ircs://irc.libera.chat:6697/#jellyfin-dev-android)
* [#jellyfin-offtopic](ircs://irc.libera.chat:6697/#jellyfin-offtopic)
## Discord
For convenience, we have a Discord server that is bridged to the chats above. Note that **Matrix** is still the preferred chat platform, and Discord messages may be missed due to bridge instability.
[Join our Discord](https://discord.gg/zHBxVSXdBV)

View File

@ -0,0 +1,87 @@
---
uid: network-reverse-proxy-apache
title: Apache
---
## Apache HTTP Server Project
"The [Apache HTTP Server Project](https://httpd.apache.org/) is an effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services in sync with the current HTTP standards."
```conf
<VirtualHost *:80>
ServerName DOMAIN_NAME
# Comment to prevent HTTP to HTTPS redirect
Redirect permanent / https://DOMAIN_NAME
ErrorLog /var/log/apache2/DOMAIN_NAME-error.log
CustomLog /var/log/apache2/DOMAIN_NAME-access.log combined
</VirtualHost>
# If you are not using a SSL certificate, replace the 'redirect'
# line above with all lines below starting with 'Proxy'
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName DOMAIN_NAME
# This folder exists just for certbot(You may have to create it, chown and chmod it to give apache permission to read it)
DocumentRoot /var/www/html/jellyfin/public_html
ProxyPreserveHost On
# Letsencrypt's certbot will place a file in this folder when updating/verifying certs
# This line will tell apache to not to use the proxy for this folder.
ProxyPass "/.well-known/" "!"
ProxyPass "/socket" "ws://SERVER_IP_ADDRESS:8096/socket"
ProxyPassReverse "/socket" "ws://SERVER_IP_ADDRESS:8096/socket"
ProxyPass "/" "http://SERVER_IP_ADDRESS:8096/"
ProxyPassReverse "/" "http://SERVER_IP_ADDRESS:8096/"
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem
Protocols h2 http/1.1
# Enable only strong encryption ciphers and prefer versions with Forward Secrecy
SSLCipherSuite HIGH:RC4-SHA:AES128-SHA:!aNULL:!MD5
SSLHonorCipherOrder on
# Disable insecure SSL and TLS versions
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
ErrorLog /var/log/apache2/DOMAIN_NAME-error.log
CustomLog /var/log/apache2/DOMAIN_NAME-access.log combined
</VirtualHost>
</IfModule>
```
If you encouter errors, you may have to enable `mod_proxy`, `mod_ssl`, `proxy_wstunnel`, `http2` and `remoteip` support manually.
```bash
sudo a2enmod proxy proxy_http ssl proxy_wstunnel remoteip http2
```
## Apache with Subpath (example.org/jellyfin)
When connecting to server from a client application, enter `http(s)://DOMAIN_NAME/jellyfin` in the address field.
Set the [base URL](xref:network-index#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect.
> [!WARNING]
> HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/).
The following configuration can be saved in ```/etc/httpd/conf/extra/jellyfin.conf``` and included in your vhost.
```conf
# Jellyfin hosted on http(s)://DOMAIN_NAME/jellyfin
<Location /jellyfin/socket>
ProxyPreserveHost On
ProxyPass "ws://127.0.0.1:8096/jellyfin/socket"
ProxyPassReverse "ws://127.0.0.1:8096/jellyfin/socket"
</Location>
<Location /jellyfin>
ProxyPass "http://127.0.0.1:8096/jellyfin"
ProxyPassReverse "http://127.0.0.1:8096/jellyfin"
</Location>
```

View File

@ -0,0 +1,80 @@
---
uid: network-reverse-proxy-caddy
title: Caddy
---
# Caddy
"[Caddy](https://caddyserver.com/), sometimes clarified as the Caddy web server, is an open source, HTTP/2-enabled web server written in Go. It uses the Go standard library for its HTTP functionality." - [Wikipedia](https://en.wikipedia.org/wiki/Caddy_(web_server))
You can reverse proxy to Jellyfin either with or without a config file, and either method offers automatic HTTPS if you want to use your public domain name.
**If you want HTTPS, make sure your domain name's A/AAAA records are pointed at your public IP address.**
If you aren't familiar with Caddy yet, check out its [Getting Started](https://caddyserver.com/docs/getting-started) guide.
## One-liners
The easiest way to reverse proxy to Jellyfin is with the `reverse-proxy` command:
```bash
caddy reverse-proxy --from :5001 --to 127.0.0.1:8096
```
That is a simple but production-ready plaintext HTTP reverse proxy.
If you have:
- permission to bind to low ports, and
- a public domain name's DNS records pointed at your machine,
then you can serve over HTTPS just as easily:
```bash
caddy reverse-proxy --from example.com --to 127.0.0.1:8096
```
You will see Caddy provision a TLS certificate for your site and if it succeeds, you can then access your Jellyfin server over HTTPS with your domain name.
## Caddyfile
If you want to use a config file, create a file called `Caddyfile` for the configuration.
The first `reverse-proxy` command above is equivalent to the following options.
```txt
:5001
reverse_proxy 127.0.0.1:8096
```
To get HTTPS, simply change the first line to your domain name.
```txt
example.com
reverse_proxy 127.0.0.1:8096
```
### Subpath
You can serve Jellyfin only at a particular base path and not proxy all other requests.
To do this, first configure Jellyfin to use a base path.
If you already have access to the web interface, go to `Admin > Networking` and enter a path like `/jellyfin` in the Base URL field.
If not, you may instead go to `<Configuration Directory>/network.xml` and modify the value of `<BaseUrl>` according to your needs. For information on the directory location, please consult the [configuration documentation](https://jellyfin.org/docs/general/administration/configuration.html#configuration-directory).
You might have to restart the Jellyfin server for this to take effect.
Then simply give the `reverse_proxy` directive a path matcher.
```txt
example.com
reverse_proxy /jellyfin/* 127.0.0.1:8096
```
With that config, Caddy will only proxy requests that start with `/jellyfin/`.
Note the trailing slash - that is optional, but recommended.
## Community Links
- [Windows Guide for Caddy v2](https://www.reddit.com/r/jellyfin/comments/gdwe0s/windows_and_caddy_v2_reverse_proxy_guide)
- [Windows Guide for Caddy v1](https://www.reddit.com/r/jellyfin/comments/ek8ugr/windows_reverse_proxy_guide)

View File

@ -0,0 +1,37 @@
---
uid: network-dlna
title: DLNA
---
## DLNA
DLNA is based on uPnP.
DLNA will send a broadcast signal from Jellyfin.
This broadcast is limited to Jellyfin's current subnet.
If you are using docker, the network should use Host Mode, otherwise the broadcast signal will only be sent in the bridged network inside of docker.
If DLNA fails to bind properly, the message `[ERR] Failed to bind to port 1900: "Address already in use". DLNA will be unavailable` should appear in the logs.
Setting `Alive message interval (seconds)` to 30 seconds also appears to help discovery for some clients.
If a base URL is set, try removing it and restarting the server.
### DLNA Logging
Use these entries in `logging.default.json` to turn on DLNA debug logs.
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Warning",
"Override": {
"Microsoft": "Warning",
"System": "Warning",
"Emby.Dlna": "Debug",
"Emby.Dlna.Eventing": "Debug"
}
}
}
}
```

View File

@ -0,0 +1,87 @@
---
uid: network-fail2ban
title: fail2ban
---
## Fail2ban
Fail2ban is an intrusion prevention software framework that protects computer servers from brute-force attacks.
Fail2ban operates by monitoring log files (e.g. /var/log/auth.log, /var/log/apache/access.log, etc.) for selected entries and running scripts based on their content.
Jellyfin produces logs that can be monitored by Fail2ban to prevent brute-force attacks on your machine.
### Requirements
* Jellyfin remotely accessible
* Fail2ban installed and running
* Knowing where the logs for Jellyfin are stored: by default `/var/log/jellyfin/`
### Step one: create a jail
You need to create a jail for Fail2ban.
If you are on Ubuntu and use nano as editor, type:
```bash
sudo nano /etc/fail2ban/jail.d/jellyfin.local
```
And add this to the file:
```bash
[jellyfin]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = jellyfin
maxretry = 3
bantime = 86400
findtime = 43200
logpath = /var/log/jellyfin/jellyfin*.log
```
Save and exit nano.
Note:
1. If jellyfin is running in a docker container, then add the following to jellyfin.local file
```bash
action = iptables-allports[name=jellyfin, chain=DOCKER-USER]
```
2. If you are running Jellyfin on a non-standard port, then change the port from 80,443 to the relevant port say 8096 8920
### Step two: create a filter
The filter explains to Fail2ban where to look in the log file. This is the tricky part.
```bash
sudo nano /etc/fail2ban/filter.d/jellyfin.conf
```
And add this to the new file:
```bash
[Definition]
failregex = ^.*Authentication request for ".*" has been denied \(IP: "<ADDR>"\)\.
```
Save and exit, then reload Fail2ban:
```bash
sudo systemctl restart fail2ban
```
You're done.
### Step three: test
You can test this new jail:
```bash
fail2ban-regex /var/log/jellyfin/*.log /etc/fail2ban/filter.d/jellyfin.conf
```
And see the output.

View File

@ -0,0 +1,40 @@
---
uid: network-reverse-proxy-haproxy
title: HAProxy
---
## HAProxy
"[Haproxy](https://www.haproxy.com/) is a free, open source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers.[1] It is written in C[2] and has a reputation for being fast and efficient (in terms of processor and memory usage)." - [Wikipedia](https://en.wikipedia.org/wiki/HAProxy)
```txt
frontend jellyfin_proxy
bind *:80
# Note that haproxy requires you to concatenate the certificate and key into a single file
# Uncomment the appropriate lines after you have acquired a SSL Certificate
#
# HAProxy <1.7
# bind *:443 ssl crt /etc/ssl/DOMAIN_NAME.pem
#
# HAProxy >1.8
# bind *:443 ssl crt /etc/ssl/DOMAIN_NAME.pem alpn h2,http/1.1
# redirect scheme https if !{ ssl_fc }
#
# Uncomment these lines to allow LetsEncrypt authentication
# acl letsencrypt_auth path_beg /.well-known/acme-challenge/
# use_backend letsencrypt if letsencrypt_auth
acl jellyfin_server hdr(host) -i DOMAIN_NAME
use_backend jellyfin if jellyfin_server
backend jellyfin
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server jellyfin SERVER_IP_ADDRESS:8096
# Uncomment these lines to allow LetsEncrypt authentication
#
#backend letsencrypt
# server letsencrypt 127.0.0.1:8888
```

View File

@ -0,0 +1,138 @@
---
uid: network-index
title: Networking
---
# Networking
This section describes how to get basic connectivity to a Jellyfin server, and also some more advanced networking scenarios.
## Connectivity
Many clients will automatically discover servers running on the same LAN and display them on login. If you are outside the network when you connect you can type in the complete IP address or domain name in the server field with the correct port to continue to the login page. You can find the default ports below to access the web frontend.
HTTP and HTTPS are the primary means of connecting to the server. If using a self-signed certificate for HTTPS, some clients may not work such as Chromecast or Roku.
> [!WARNING]
> In order for Chromecast to work on a non-public routable connection, 8.8.8.8 must be blocked on the Chromecast's Gateway. Blocking 8.8.8.8 on your router is the easiest solution to this problem.
### Port Bindings
This document aims to provide an administrator with knowledge on what ports Jellyfin binds to and what purpose they serve.
#### Static Ports
* 8096/tcp is used by default for HTTP traffic. You can change this in the dashboard.
* 8920/tcp is used by default for HTTPS traffic. You can change this in the dashboard.
* 1900/udp is used for service auto-discovery. This is not configurable.
* 7359/udp is also used for auto-discovery. This is not configurable.
**HTTP Traffic:** 8096
The web frontend can be accessed here for debugging SSL certificate issues on your local network. You can modify this setting from the **Networking** page in the settings.
**HTTPS Traffic:** 8920
This setting can also be modified from the **Networking** page to use a different port.
**Service Discovery:** 1900
Since client auto-discover would break if this option were configurable, you cannot change this in the settings at this time. DLNA also uses this port and is required to be in the local subnet.
**Client Discovery:** 7359 UDP
Allows clients to discover Jellyfin on the local network. A broadcast message to this port with `Who is JellyfinServer?` will get a JSON response that includes the server address, ID, and name.
#### Dynamic Ports
Live TV devices will often use a random UDP port for HDHomeRun devices. The server will select an unused port on startup to connect to these tuner devices.
### Monitoring Endpoints
See @monitoring for details on the monitoring endpoints that Jellyfin provides.
## Self-Signed Certificate
[See here for more information.](https://www.sslshopper.com/article-most-common-openssl-commands.html)
Create a private key.
```sh
openssl req -x509 -newkey rsa:4096 -keyout ./privkey.pem -out cert.pem -days 365 -nodes -subj '/CN=jellyfin.lan'
```
Omit `-nodes` to set a password interactively.
Remove `-days 365` to make it 'permanent'.
Add `-subj '/CN=localhost'` to make it not ask interactive questions about content of certificate.
The above command creates `./privkey.pem` which will require one more step before use in Jellyfin.
```sh
openssl pkcs12 -export -out jellyfin.pfx -inkey privkey.pem -in /usr/local/etc/letsencrypt/live/domain.org/cert.pem -passout pass:
```
## Running Jellyfin Behind a Reverse Proxy
It's possible to run Jellyfin behind another server acting as a reverse proxy. With a reverse proxy setup, this server handles all network traffic and proxies it back to Jellyfin. This provides the benefits of using DNS names and not having to remember port numbers, as well as easier integration and management of SSL certificates.
> [!WARNING]
> In order for a reverse proxy to have the maximum benefit, you should have a publically routable IP address and a domain with DNS set up correctly.
> These examples assume you want to run Jellyfin under a sub-domain (e.g. jellyfin.example.com), but are easily adapted for the root domain if desired.
> [!WARNING]
> Be careful when logging requests with your reverse proxy. Jellyfin sometimes sends authentication information as part of the URL (e.g <code>api_key</code> parameter), so logging the full request
> path can expose secrets to your logfile. We recommend that you either protect your logfiles or do not log full request URLs or censor sensitive data from the logfile.
> The nginx documentation below includes an example how to censor sensitive information from a logfile.
Some popular options for reverse proxy systems are [Apache](https://httpd.apache.org), [Caddy](https://caddyserver.com), [Haproxy](https://www.haproxy.com), [Nginx](https://www.nginx.com) and [Traefik](https://traefik.io).
* [Apache](xref:network-reverse-proxy-apache)
* [Caddy](xref:network-reverse-proxy-caddy)
* [HAProxy](xref:network-reverse-proxy-haproxy)
* [Nginx](xref:network-reverse-proxy-nginx)
* [Traefik](xref:network-reverse-proxy-traefik)
While not a reverse proxy, Let's Encrypt can be used independently or with a reverse proxy to provide SSL certificates.
* [Let's Encrypt](xref:network-letsencrypt)
When following this guide, be sure to replace the following variables with your information.
* `DOMAIN_NAME`: Your public domain name to access Jellyfin on (e.g. jellyfin.example.com)
* `example.com`: The domain name Jellyfin services will run under (e.g. example.com)
* `SERVER_IP_ADDRESS`: The IP address of your Jellyfin server (if the reverse proxy is on the same server use 127.0.0.1)
In addition, the examples are configured for use with Let's Encrypt certificates. If you have a certificate from another source, change the SSL configuration from `/etc/letsencrypt/DOMAIN_NAME/` to the location of your certificate and key.
Ports 80 and 443 (pointing to the proxy server) need to be opened on your router and firewall.
### Known Proxies
Add the IP address/hostname of your reverse proxy to the `Known Proxies` (under Admin Dashboard -> Networking). This is a comma separated list of IP addresses/hostnames of known proxies used when connecting to your Jellyfin instance and is required to make proper use of X-Forwarded-For headers. Requires a server restart after saving.
### Base URL
Running Jellyfin with a path (e.g. `https://example.com/jellyfin`) is supported by the Android and web clients.
> [!WARNING]
> Base URL is known to break HDHomeRun, DLNA, Sonarr, Radarr, Chromecast, and MrMC.
The Base URL setting in the **Networking** page is an advanced setting used to specify the URL prefix that your Jellyfin instance can be accessed at. In effect, it adds this URL fragment to the start of any URL path. For instance, if you have a Jellyfin server at `http://myserver` and access its main page `http://myserver/web/index.html`, setting a Base URL of `/jellyfin` will alter this main page to `http://myserver/jellyfin/web/index.html`. This can be useful if administrators want to access multiple Jellyfin instances under a single domain name, or if the Jellyfin instance lives only at a subpath to another domain with other services listening on `/`.
The entered value on the configuration page will be normalized to include a leading `/` if this is missing.
This setting requires a server restart to change, in order to avoid invalidating existing paths until the administrator is ready.
There are three main caveats to this setting.
1. When setting a new Base URL (i.e. from `/` to `/baseurl`) or changing a Base URL (i.e. from `/baseurl` to `/newbaseurl`), the Jellyfin web server will automatically handle redirects to avoid displaying users invalid pages. For instance, accessing a server with a Base URL of `/jellyfin` on the `/` path will automatically append the `/jellyfin` Base URL. However, entirely removing a Base URL (i.e. from `/baseurl` to `/`, an empty value in the configuration) will not - all URLs with the old Base URL path will become invalid and throw 404 errors. This should be kept in mind when removing an existing Base URL.
2. Client applications generally, for now, do not handle the Base URL redirects implicitly. Therefore, for instance in the Android app, the `Host` setting *must* include the BaseURL as well (e.g. `http://myserver:8096/baseurl`), or the connection will fail.
3. Any reverse proxy configurations must be updated to handle a new Base URL. Generally, passing `/` back to the Jellyfin instance will work fine in all cases and the paths will be normalized, and this is the standard configuration in our examples. Keep this in mind however when doing more advanced routing.
### Final Steps
It's strongly recommend that you check your SSL strength and server security at [SSLLabs](https://www.ssllabs.com/ssltest/analyze.html) if you are exposing these services to the internet.

View File

@ -0,0 +1,230 @@
---
uid: network-letsencrypt
title: Let's Encrypt
---
## LetsEncrypt with Certbot
LetsEncrypt is a service that provides free SSL/TLS certificates to users. Certbot is a client that makes this easy to accomplish and automate. In addition, it has plugins for Apache and Nginx that make automating certificate generation even easier.
Installation instructions for most Linux distributions can be found on the [Certbot](https://certbot.eff.org/docs/install.html#operating-system-packages) website.
Once the packages are installed, you're ready to generate a new certificate.
### Apache
#### Certbot Apache Plugin
After installing Certbot and the Apache plugin, certificate generation is accomplished by with the following command.
```sh
certbot certonly --apache --noninteractive --agree-tos --email YOUR_EMAIL -d DOMAIN_NAME
```
Update the 'SSLCertificateFile' and 'SSLCertificateKeyFile' sections, then restart the service.
Add a job to cron so the certificate will be renewed automatically.
```sh
echo "0 0 * * * root certbot renew --quiet --no-self-upgrade --post-hook 'systemctl reload apache2'" | sudo tee -a /etc/cron.d/renew_certbot
```
#### Certbot Webroot
##### Debian
If the certbot apache plugin doesn't work with your config, use webroot instead.
Add the following to your <VirtualHost> section after configuring it a reverse proxy:
```conf
DocumentRoot /var/www/html/
#Do not pass the .well-known directory when using certbot and webroot
ProxyPass /.well-known !
```
Run the certbot command as root:
```sh
sudo certbot certonly --webroot -w /var/www/html --agree-tos --email YOUR_EMAIL -d DOMAIN_NAME
```
### HAProxy
HAProxy doesn't currently have a Certbot plugin. To get around this, run Certbot in standalone mode and proxy traffic through your network.
Enable the frontend and backend in the config above, and then run Certbot.
```sh
certbot certonly --standalone --preferred-challenges http-01 --http-01-port 8888 --noninteractive --agree-tos --email YOUR_EMAIL -d DOMAIN_NAME
```
The port can be changed to anything you like, but be sure that the HAProxy config and your Certbot command match.
HAProxy needs to have the certificate and key files concatenated into the same file to read it correctly. This can be accomplished with the following command.
```sh
cat /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem > /etc/ssl/DOMAIN_NAME.pem
```
Uncomment `bind *:443` and the redirect section in the configuration, then reload the service.
#### Automatic Certificate Renewal
Place the following script in `/usr/local/bin/` to automatically update your SSL certificate.
```sh
SITE=DOMAIN_NAME
# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE
# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > /etc/ssl/$SITE.pem
# reload haproxy
service haproxy reload
```
Make sure the script is executable.
```sh
chmod u+x /usr/local/bin/letsencrypt-renew.sh
```
Add a job to cron so the certificate will be renewed automatically.
```data
@monthly /usr/bin/certbot renew --renew-hook "/usr/local/bin/letsencrypt-renew.sh" >> /var/log/letsencrypt-renewal.log
```
### Nginx
After installing Certbot and the Nginx plugin with `sudo apt install certbot python3-certbot-nginx`, generate the certificate.
**Note**: For Fedora Linux distributions (e.g. CentOS 8) use `sudo dnf install python3-certbot-nginx` to install the Nginx plugin.
```sh
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email YOUR_EMAIL -d DOMAIN_NAME
```
Add the `--rsa-key-size 4096` parameter if you want a 4096 bit key instead.
Copy and paste the whole Nginx sample configuration file from above, changing the parameters according to your setup and uncommenting the lines.
Add a job to cron so the certificate will be renewed automatically.
```sh
echo "0 0 * * * root certbot renew --quiet --no-self-upgrade --post-hook 'systemctl reload nginx'" | sudo tee -a /etc/cron.d/renew_certbot
```
### Let's Encrypt and Docker
This section assumes that Jellyfin is running in a Docker container (on Linux). This section also assumes that you wish to run Let's Encrypt in a Docker container as well. The Linuxserver/swag Docker container has a built-in nginx webserver to handle the reverse proxy.
Linuxserver/letsencrypt is deprecated in favor of linuxserver/swag, see [here](https://github.com/linuxserver/docker-swag#migrating-from-the-old-linuxserverletsencrypt-image) for information on how to migrate if needed.
First, you need to determine a few things.
1. **MAKE SURE YOU HAVE A CNAME FOR JELLYFIN WITH YOUR DNS PROVIDER BEFORE PROCEEDING**
2. Where you wish to store information regarding Let's Encrypt (docker calls these "volumes")
3. What subdomain or subfolder you wish to use with Let's Encrypt (ex. jellyfin.example.com)
4. What timezone you wish to use
5. If you'll be using either HTTP-01 or DNS-01 for challenges.
6. What network you'll be running on (I'd recommend the default macvlan network called "br0")
7. What IP you want your container running on
8. What ports you'll be using (ex. 180 for port 80, and 1443 for 443)
9. Make sure ports 80 (if using http validation) and 443 are forwarded to the docker container from your router (instructions vary upon manufacturer)
10. What user will the container be running as (you can determine the PUID and PGID by running `id` (replacing "user" with the username of the user the container will be running as)
List of DNS Plugins [here](https://certbot.eff.org/docs/using.html#dns-plugins) if using DNS-01 challenge.
Then, depending on what those settings are, you'll need to adjust the values below as needed.
For example, the docker create command from the LinuxServer team for the Swag Docker container:
```sh
docker create \
--name=swag \
--cap-add=NET_ADMIN \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/London \
-e URL=example.com \
-e SUBDOMAINS=www, \
-e VALIDATION=http \
-e DNSPLUGIN=cloudflare `#optional` \
-e DUCKDNSTOKEN=<token> `#optional` \
-e EMAIL=<e-mail> `#optional` \
-e DHLEVEL=2048 `#optional` \
-e ONLY_SUBDOMAINS=false `#optional` \
-e EXTRA_DOMAINS=<extradomains> `#optional` \
-e STAGING=false `#optional` \
-p 443:443 \
-p 80:80 `#optional` \
-v </path/to/appdata/config>:/config \
--restart unless-stopped \
linuxserver/swag
```
Assuming I follow this template and adjust for my region, ports, and path, it would look like this (with personal information redacted):
```sh
docker create --name=swag --cap-add=NET_ADMIN -e PUID=1000 -e PGID=1000 -e TZ=America/Chicago -e URL=example.com -e SUBDOMAINS=jellyfin -e VALIDATION=http -e EMAIL=email@email.com -e DHLEVEL=2048 -e ONLY_SUBDOMAINS=false -e STAGING=false -p 443:443 -p 80:80 -v /path/to/appdata/swag/:/config --restart unless-stopped linuxserver/swag
```
This will pull down the linuxserver/letsencrypt container, and then create it with the variables specified. You'll then want to start the docker container with `docker start swag`. You can verify this is started by running `docker ps`, which will produce an output like this:
```text
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09346434b8ea linuxserver/swag "/init" 2 minutes ago Up 5 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp swag
```
At this point, navigate to what volume you selected (in my example, it's `/mnt/swag`). You'll then need to navigate to `nginx/proxy-confs` within that directory. If you list the contents of that directory, you'll see a lot of files.
The one we're interested in for jellyfin is `jellyfin.subdomain.conf.sample` (if using a subdomain) or `jellyfin.subfolder.conf.sample` (if using a subfolder). You'll want to copy the file needed, removing the .sample (ex. `cp jellyfin.subdomain.conf.sample jellyfin.subdomain.conf`). Open the file in your text editor of choice.
It should look like this (this file is `jellyfin.subdomain.conf`, although `jellyfin.subfolder.conf` looks very similar):
```nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name jellyfin.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app jellyfin;
set $upstream_port 8096;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
}
location ~ (/jellyfin)?/socket/ {
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app jellyfin;
set $upstream_port 8096;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
}
```
The lines we're interested in is `set $upstream_app jellyfin`. Now, assuming Jellyfin and Let's Encrypt are on the same network within Docker, it *should* see it and start handling reverse proxy without much issue. If it doesn't however, you'll just need to change `jellyfin` in that line to whatever the IP of your Jellyfin server is. We'll also look at the line `location ~ (/jellyfin)?/socket` and add a slash after socket, so the line should look like this `location ~ (/jellyfin)?/socket/`.
Then, within Jellyfin settings (Dashboard -> Networking), scroll down to "Public HTTP port number" and "Public HTTPS port number", and make sure HTTP Port number is 8096, while HTTPS port number is 8920.
Restart your Let's Encrypt docker container by running `docker restart swag`, and then you can follow the logs with `docker logs -f swag`. Assuming everything works, you should see `Server Ready` at the very end of the logs. This tells you Lets Encrypt is running without issue.

View File

@ -0,0 +1,28 @@
---
uid: monitoring
title: Monitoring
---
## Monitoring
Jellyfin has two monitoring and metrics endpoints built-in: a basic health check endpoint and a Prometheus-compatible metrics endpoint.
### Health check endpoint
Jellyfin exposes the `/health` endpoint designated for checking the status of the underlying service. Currently this will verify HTTP and database connectivity and return a `200 OK` response if successful. You can see this for yourself by using `curl`:
```sh
curl -i http://myserver:8096/health
```
The `-i` option tells `curl` to also print the HTTP response code and headers.
### Prometheus metrics
Jellyfin can make [Prometheus](https://prometheus.io/) metrics available at `/metrics`, but this is turned off by default to avoid unintentionally leaking this information on the public internet. To enable it, you will need to edit `/etc/jellyfin/system.xml` and change this line from `false` to `true`:
```xml
<EnableMetrics>false</EnableMetrics>
```
If you have a [reverse proxy](xref:network-index#running-jellyfin-behind-a-reverse-proxy) configured, you can configure it to block access to the `/metrics` endpoint except for your internal network.

View File

@ -0,0 +1,366 @@
---
uid: network-reverse-proxy-nginx
title: Nginx
---
## Nginx
"[Nginx](https://www.nginx.com/) (pronounced "engine X") is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The software was created by Igor Sysoev and first publicly released in 2004.[9] A company of the same name was founded in 2011 to provide support and Nginx plus paid software." - [Wikipedia](https://en.wikipedia.org/wiki/Nginx)
## Nginx from a subdomain (jellyfin.example.org)
> [!WARNING]
> HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS. [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/). Using only HTTP will expose passwords and API keys.
> [!TIP]
> The default X-Frame-Options header may cause issues with the webOS app, causing it to remain stuck at a black screen. If enabled, the default Content Security Policy may also cause issues.
Create the file `/etc/nginx/conf.d/jellyfin.conf` which will forward requests to Jellyfin.
```config
# Uncomment the commented sections after you have acquired a SSL Certificate
server {
listen 80;
listen [::]:80;
# server_name DOMAIN_NAME;
# Uncomment to redirect HTTP to HTTPS
# return 301 https://$host$request_uri;
#}
#server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
server_name DOMAIN_NAME;
## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc.
client_max_body_size 20M;
# use a variable to store the upstream proxy
# in this example we are using a hostname which is resolved via DNS
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`)
set $jellyfin jellyfin;
resolver 127.0.0.1 valid=30;
#ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem;
#include /etc/letsencrypt/options-ssl-nginx.conf;
#ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
#add_header Strict-Transport-Security "max-age=31536000" always;
#ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem;
#ssl_stapling on;
#ssl_stapling_verify on;
# Security / XSS Mitigation Headers
# NOTE: X-Frame-Options may cause issues with the webOS app
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
# Content Security Policy
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
# Enforces https content and restricts JS/CSS to origin
# External Javascript (such as cast_sender.js for Chromecast) must be whitelisted.
# NOTE: The default CSP headers may cause issues with the webOS app
#add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com/cv/js/sender/v1/cast_sender.js https://www.gstatic.com/eureka/clank/95/cast_sender.js https://www.gstatic.com/eureka/clank/96/cast_sender.js https://www.gstatic.com/eureka/clank/97/cast_sender.js https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'";
location = / {
return 302 http://$host/web/;
#return 302 https://$host/web/;
}
location / {
# Proxy main Jellyfin traffic
proxy_pass http://$jellyfin:8096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
}
# location block for /web - This is purely for aesthetics so /web/#!/ works instead of having to go to /web/index.html/#!/
location = /web/ {
# Proxy main Jellyfin traffic
proxy_pass http://$jellyfin:8096/web/index.html;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
}
location /socket {
# Proxy Jellyfin Websockets traffic
proxy_pass http://$jellyfin:8096;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
}
}
```
## Nginx with Subpath (example.org/jellyfin)
When connecting to server from a client application, enter `http(s)://DOMAIN_NAME/jellyfin` in the address field.
Set the [base URL](xref:network-index#base-url) field in the Jellyfin server. This can be done by navigating to the Admin Dashboard -> Networking -> Base URL in the web client. Fill in this box with `/jellyfin` and click Save. The server will need to be restarted before this change takes effect.
### HTTP config example
> [!WARNING]
> HTTP is insecure. The following configuration is provided for ease of use only. If you are planning on exposing your server over the Internet you should setup HTTPS (see below for HTTPS configuration example). [Let's Encrypt](https://letsencrypt.org/getting-started/) can provide free TLS certificates which can be installed easily via [certbot](https://certbot.eff.org/).
```conf
# Jellyfin hosted on http://DOMAIN_NAME/jellyfin
server {
listen 80;
listen [::]:80;
server_name DOMAIN_NAME;
# You can specify multiple domain names if you want
#server_name jellyfin.local;
# use a variable to store the upstream proxy
# in this example we are using a hostname which is resolved via DNS
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`)
set $jellyfin jellyfin;
resolver 127.0.0.1 valid=30;
# Uncomment and create directory to also host static content
#root /srv/http/media;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Jellyfin
location /jellyfin {
return 302 $scheme://$host/jellyfin/;
}
location /jellyfin/ {
# Proxy main Jellyfin traffic
# The / at the end is significant.
# https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/
proxy_pass http://$jellyfin:8096/jellyfin/;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
}
}
```
### HTTPS config example
The following config is meant to work with Certbot / Let's Encrypt.
```conf
# Jellyfin hosted on https://DOMAIN_NAME/jellyfin
server {
listen 80;
listen [::]:80;
server_name DOMAIN_NAME;
# Uncomment to redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name DOMAIN_NAME;
# You can specify multiple domain names if you want
#server_name jellyfin.local;
ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem;
ssl_stapling on;
ssl_stapling_verify on;
# use a variable to store the upstream proxy
# in this example we are using a hostname which is resolved via DNS
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`)
set $jellyfin jellyfin;
resolver 127.0.0.1 valid=30;
# Jellyfin
location /jellyfin {
return 302 $scheme://$host/jellyfin/;
}
location /jellyfin/ {
# Proxy main Jellyfin traffic
# The / at the end is significant.
# https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/
proxy_pass http://$jellyfin:8096;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
}
}
```
## Extra Nginx Configurations
### Censor sensitive information in logs
This censors any <code>api_key</code> URL parameter from the logfile.
```conf
#Must be in HTTP block
log_format stripsecrets '$remote_addr $host - $remote_user [$time_local] '
'"$secretfilter" $status $body_bytes_sent '
'$request_length $request_time $upstream_response_time '
'"$http_referer" "$http_user_agent"';
map $request $secretfilter {
~*^(?<prefix1>.*[\?&]api_key=)([^&]*)(?<suffix1>.*)$ "${prefix1}***$suffix1";
default $request;
}
#Must be inside server block
#Insert into all servers where you want filtering (e.g HTTP + HTTPS block)
access_log /var/log/nginx/access.log stripsecrets;
```
### Cache Video Streams
```conf
# Must be in HTTP block
# Set in-memory cache-metadata size in keys_zone, size of video caching and how many days a cached object should persist
proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=90d max_size=35000m;
map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; }
map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; }
# Set in Server block
location ~* ^/Videos/(.*)/(?!live)
{
# Set size of a slice (this amount will be always requested from the backend by nginx)
# Higher value means more latency, lower more overhead
# This size is independent of the size clients/browsers can request
slice 2m;
proxy_cache jellyfin-videos;
proxy_cache_valid 200 206 301 302 30d;
proxy_ignore_headers Expires Cache-Control Set-Cookie X-Accel-Expires;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_connect_timeout 15s;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Transmit slice range to the backend
proxy_set_header Range $slice_range;
# This saves bandwidth between the proxy and jellyfin, as a file is only downloaded one time instead of multiple times when multiple clients want to at the same time
# The first client will trigger the download, the other clients will have to wait until the slice is cached
# Esp. practical during SyncPlay
proxy_cache_lock on;
proxy_cache_lock_age 60s;
proxy_pass http://$jellyfin:8096;
proxy_cache_key "jellyvideo$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level&slicerange=$slice_range";
# add_header X-Cache-Status $upstream_cache_status; # This is only for debugging cache
}
```
### Cache Images
```conf
# Add this outside of you server block (i.e. http block)
proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=30d use_temp_path=off;
# Cache images (inside server block)
location ~ /Items/(.*)/Images {
proxy_pass http://127.0.0.1:8096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_cache jellyfin;
proxy_cache_revalidate on;
proxy_cache_lock on;
# add_header X-Cache-Status $upstream_cache_status; # This is only to check if cache is working
}
```
Ensure that the directory /var/cache/nginx/jellyfin exists and the nginx user has write permissions on it! All the cache options used are explained on [Nginx blog](https://www.nginx.com/blog/nginx-caching-guide/) and [Nginx proxy module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html).
### Rate Limit Downloads
```conf
# Add this outside of you server block (i.e. http block)
limit_conn_zone $binary_remote_addr zone=addr:10m;
# Downloads limit (inside server block)
location ~ /Items/(.*)/Download$ {
proxy_pass http://127.0.0.1:8096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
limit_rate 1700k; # Speed limit (here is on kb/s)
limit_conn addr 3; # Number of simultaneous downloads per IP
limit_conn_status 460; # Custom error handling
# proxy_buffering on; # Be sure buffering is on (it is by default on nginx), otherwise limits won't work
}
# Error page
error_page 460 http://your-page-telling-your-limit/;
```
[See here for more](https://www.nginx.com/blog/rate-limiting-nginx/)

View File

@ -0,0 +1,180 @@
---
uid: network-reverse-proxy-traefik
title: Traefik v1.x
---
## Traefik v1.x
[Traefik](https://traefik.io/) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS, ...) and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the only configuration step you need. This configuration is A+. Test your setup here at [SSLlabs](https://www.ssllabs.com/ssltest/).
Create docker-compose.yml, traefik.toml and acme.json in the **same** directory or change their paths in the volume section.
> [!NOTE]
> Ensure you enable Basic Auth protection for Traefik or disable its Dashboard. Otherwise your Dashboard will be accessible from the internet.
```bash
sudo apt install apache2-utils
echo $(htpasswd -nb username mystrongpassword) | sed -e s/\\$/\\$\\$/g
```
This command automatically escapes all $ inside the password for the YML file. If using an environment file, it does not need the $ escaped since it will not be interpreted by the shell.
Create the docker network for traefik.
```bash
sudo docker network create traefik
```
### docker-compose.yml
```yml
version: '3.5'
networks:
traefik:
name: traefik
services:
traefik:
container_name: traefik
image: traefik:v1.7
networks:
- traefik
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
labels:
traefik.enable: "true"
traefik.backend: traefik
traefik.docker.network: traefik
traefik.port: 8080
traefik.frontend.rule: Host:traefik.example.com,
traefik.frontend.entryPoints: https
traefik.frontend.passHostHeader: "true"
traefik.frontend.headers.SSLForceHost: "true"
traefik.frontend.headers.SSLHost: traefik.example.com
traefik.frontend.headers.SSLRedirect: "true"
traefik.frontend.headers.browserXSSFilter: "true"
traefik.frontend.headers.contentTypeNosniff: "true"
traefik.frontend.headers.forceSTSHeader: "true"
traefik.frontend.headers.STSSeconds: 315360000
traefik.frontend.headers.STSIncludeSubdomains: "true"
traefik.frontend.headers.STSPreload: "true"
traefik.frontend.headers.customResponseHeaders: X-Robots-Tag:noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex
traefik.frontend.headers.frameDeny: "true"
traefik.frontend.headers.customFrameOptionsValue: 'allow-from https://example.com'
# traefik.frontend.auth.basic.users: xxx:xxx
restart: unless-stopped
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
network_mode: "host"
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
- /path/to/media:/media
restart: unless-stopped
```
This TOML file can't support environment variables, so don't attempt to use variables.
> [!WARNING]
> Due to a [bug](https://github.com/containous/traefik/issues/5559) in Traefik, you cannot dynamically route to containers when network_mode=host, so we have created a static route to the docker host (172.17.0.1:8096) in `traefik.toml`. Using host networking (or macvlan) is required to use DLNA or an HdHomeRun as it supports multicast networking.
### traefik.toml
```toml
logLevel = "WARN"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
minVersion = "VersionTLS12"
cipherSuites = [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
]
[retry]
[api]
[acme]
acmeLogging = true
email = "user@example.com"
storage = "acme.json"
entryPoint = "https"
[acme.dnsChallenge]
provider = "provider"
delayBeforeCheck = "60"
[[acme.domains]]
main = "*.example.com"
[docker]
domain = "example.com"
network = "traefik"
exposedbydefault = false
[file]
[backends]
[backends.backend-jellyfin]
[backends.backend-jellyfin.servers]
[backends.backend-jellyfin.servers.server-1]
url = "http://172.17.0.1:8096"
[frontends]
[frontends.jellyfin]
backend = "backend-jellyfin"
passHostHeader = true
[frontends.jellyfin.routes]
[frontends.jellyfin.routes.route-jellyfin-ext]
rule = "Host:jellyfin.example.com"
[frontends.jellyfin.headers]
SSLRedirect = true
SSLHost = "jellyfin.example.com"
SSLForceHost = true
STSSeconds = 315360000
STSIncludeSubdomains = true
STSPreload = true
forceSTSHeader = true
frameDeny = true
contentTypeNosniff = true
browserXSSFilter = true
customResponseHeaders = "X-Robots-Tag:noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
customFrameOptionsValue = "allow-from https://example.com"
```
Finally, create an empty acme.json file to handle the certificate.
```bash
touch acme.json
chmod 600 acme.json
```
> [!WARNING]
> Change example.com to your domain name and update the acme.json file with your email address. Let's Encrypt does not require a valid email but example.com will be flagged as fake.
Launch the Traefik and Jellyfin services.
```bash
docker-compose up -d
```
Congratulations, your stack with Traefik and Jellyfin is running!
Go to the domain you used earlier in the config file and your Jellyfin server will be running with HTTPS (AES 256) enabled.

View File

@ -0,0 +1,283 @@
---
uid: network-reverse-proxy-traefik2
title: Traefik v2.x
---
## Traefik v2.x
[Traefik](https://traefik.io/) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components (ie: Docker) and generally configures itself dynamically as services are added or removed.
This document provides a complete configuration of Traefik v2.x and Jellyfin. It uses a number of files including a `docker-compose.yml` file, `traefik.toml` (your Traefik static configuration), `traefik-provider.toml` (a file-based provider for Traefik), `traefik.log` (an optional log file), `.env` (the environment which may be needed for your ACME/LetsEncrypt providers), and `acme.json` (the state data for your ACME/LetsEncrypt certificate). The files should all be created in the **same** directory. Alternately, alter the paths in the volume section of the `traefik` service in `docker-compose.yml`. You can optionally jam some of the traefik.toml file into labels for the traefik service in `docker-compose.yml`, however this method is much clearer and easier to comment.
> [!NOTE]
> Ensure you enable some basic firewall or auth protection for Traefik or disable its dashboard. If you do not, your dashboard may be accessible from the internet. Pay attention to accessibility via IPv6, as even systems on an internal home network may be directly accessible over IPv6. See [api-insecure](https://docs.traefik.io/operations/api/#insecure) for more details on securing the dashboard.
> [!NOTE]
> Traefik has many options for the configuration of LetsEncrypt using your choice of challenges. If your server is accessible from the Internet via port 80 or 443, you can use the HTTP-01 or TLS-ALPN-01 challenges. If so, the certificatesresolvers.leresolver.acme.httpchallenge.entrypoint must be reachable by Let's Encrypt through port 80/443. You can also use a DNS-01 challenge via one of the available [providers](https://docs.traefik.io/https/acme/#providers). Configuration is beyond the scope of this guide. This guide can use both HTTP-01 and DNS-01 by commenting or uncommenting the various blocks. You are most likely to use HTTP-01 unless you have full access to your DNS configuration. The configuration below uses RFC2136 (as set by certificatesresolvers.leresolver.acme.dnsChallenge of `traefik.toml`) and the variables for that provider are shown in the `.env` file as a formatting guide. See provider documentation and comments about configuration of your ACME provider of choice, or change the configuration to HTTP-01 in `traefik.toml`'s comments.
The configuration below creates a Traefik v2.x installation with access at entryPoint ports 80 (labelled 'http'), 443 (labeled 'https'), and 9999 (labeled 'secure'). Unrelated to this Jellyfin configuration, it redirects all traffic from http (port 80) to https (port 443) to ensure all data is encrypted. As for Jellyfin, it makes the service accessible without a path on the secure entry point. This configuration is intended to be used as a starting point and some adaptation is likely required for your configuration. If you want Jellyfin to be accessible without using a port (using the default https port), simply change 'secure' to 'https' in `docker-compose.yml` where indicated and remove the ':9999' from the SSLHost parameter. If you want Jellyfin to be accessible with a path, simply add the PathPrefix (i.e. '/jellyfin') and see the note near the end of this document about configuring Jellyfin.
### docker-compose.yml
```yml
version: '2.4'
services:
traefik:
container_name: traefik
image: traefik:chevrotin # the chevrotin tag refers to v2.2.x
restart: unless-stopped
volumes:
# So that Traefik can listen to the Docker events (read-only)
- /var/run/docker.sock:/var/run/docker.sock:ro
# TOML Configuration with global options
- /srv/traefik.toml:/traefik.toml
# Configuration for the file provider (needed for host networking and default TLS Options)
- /srv/traefik-provider.toml:/traefik-provider.toml
# LetsEncrypt ACME Configuration
- /srv/acme.json:/acme.json
# Log File (optional)
- /srv/traefik.log:/traefik.log
ports:
# The Web UI (enabled by --api.insecure=true in traefik.toml)
- 8080:8080
# The Available Ports (forward your router's incoming ports to the ports on the host)
- 80:80
- 443:443
- 9999:9999
env_file: .env
jellyfin:
image: jellyfin/jellyfin
container_name: "jellyfin"
user: 1000:1000
group_add: # by id as these may not exist within the container. Needed to provide permissions to the VAAPI Devices
- "107" #render
- "44" #video
# Network mode of 'host' exposes the ports on the host. This is needed for DLNA access.
network_mode: "host"
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
# Update this configuration as desired
- /path/to/media:/media
restart: always
devices:
# VAAPI Devices
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card0:/dev/dri/card0
labels:
- "traefik.enable=true"
## HTTP Router
#### Entry point where Jellyfin is accessible via
#### Change secure to https in the line below to have accessible without needing to specify a port and change the SSLHost option below
- "traefik.http.routers.jellyfin.entryPoints=secure"
#### Host or Path where Jellyfin is accessible
#### Remove (or change) this rule if you'd rather have Jellyfin accessible at a PathPrefix URI
- "traefik.http.routers.jellyfin.rule=Host(`HOST_NAME.DOMAIN_NAME`)" # OPTIONAL: && PathPrefix(`/jellyfin`)
#### Enable TLS with the ACME/LetsEncrypt resolver for HOSTNAME.DOMAIN_NAME
- "traefik.http.routers.jellyfin.tls=true"
- "traefik.http.routers.jellyfin.tls.certResolver=leresolver"
- "traefik.http.routers.jellyfin.tls.domains=HOSTNAME.DOMAIN_NAME"
## Middleware
- "traefik.http.routers.jellyfin.middlewares=jellyfin-mw"
#### The customResponseHeaders option lists the Header names and values to apply to the response.
- "traefik.http.middlewares.jellyfin-mw.headers.customResponseHeaders.X-Robots-Tag=noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
#### The sslRedirect is set to true, then only allow https requests.
- "traefik.http.middlewares.jellyfin-mw.headers.SSLRedirect=true"
#### The sslHost option is the host name that is used to redirect http requests to https.
#### This is the exact URL that will be redirected to, so you can remove the :9999 port if using default SSL port
- "traefik.http.middlewares.jellyfin-mw.headers.SSLHost=HOST_NAME.DOMAIN_NAME:9999"
#### Set sslForceHost to true and set SSLHost to forced requests to use SSLHost even the ones that are already using SSL.
#### Note that this uses SSLHost verbatim, so add the port to SSLHost if you are using an alternate port.
- "traefik.http.middlewares.jellyfin-mw.headers.SSLForceHost=true"
#### The stsSeconds is the max-age of the Strict-Transport-Security header. If set to 0, would NOT include the header.
- "traefik.http.middlewares.jellyfin-mw.headers.STSSeconds=315360000"
#### The stsIncludeSubdomains is set to true, the includeSubDomains directive will be
#### appended to the Strict-Transport-Security header.
- "traefik.http.middlewares.jellyfin-mw.headers.STSIncludeSubdomains=true"
#### Set stsPreload to true to have the preload flag appended to the Strict-Transport-Security header.
- "traefik.http.middlewares.jellyfin-mw.headers.STSPreload=true"
#### Set forceSTSHeader to true, to add the STS header even when the connection is HTTP.
- "traefik.http.middlewares.jellyfin-mw.headers.forceSTSHeader=true"
#### Set frameDeny to true to add the X-Frame-Options header with the value of DENY.
- "traefik.http.middlewares.jellyfin-mw.headers.frameDeny=true"
#### Set contentTypeNosniff to true to add the X-Content-Type-Options header with the value nosniff.
- "traefik.http.middlewares.jellyfin-mw.headers.contentTypeNosniff=true"
#### Set browserXssFilter to true to add the X-XSS-Protection header with the value 1; mode=block.
- "traefik.http.middlewares.jellyfin-mw.headers.browserXSSFilter=true"
#### The customFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This
#### overrides the FrameDeny option.
- "traefik.http.middlewares.jellyfin-mw.headers.customFrameOptionsValue='allow-from https://DOMAIN_NAME'"
## HTTP Service
# We define the port here as a port is required, but note that the service is pointing to the service defined in @file
- "traefik.http.routers.jellyfin.service=jellyfin-svc@file"
- "traefik.http.services.jellyfin-svc.loadBalancer.server.port=8096"
- "traefik.http.services.jellyfin-svc.loadBalancer.passHostHeader=true"
## Redirection of HTTP on port 9999 to HTTPS on port 9999 (consistent protocol)
- "traefik.http.routers.jellyfin-insecure.entryPoints=secure"
- "traefik.http.routers.jellyfin-insecure.rule=Host(`HOST_NAME.DOMAIN_NAME`)" # OPTIONAL: && PathPrefix(`/jellyfin`)
- "traefik.http.routers.jellyfin-insecure.middlewares=jellyfin-insecure-mw"
- "traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.scheme=https"
- "traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.port=9999" # remove if you are using a default port
- "traefik.http.middlewares.jellyfin-insecure-mw.redirectscheme.permanent=false"
- "traefik.http.routers.jellyfin-insecure.service=noop@internal"
```
> [!WARNING]
> TOML files can't support environment variables, so all values must be hard coded.
### traefik.toml
```toml
[log]
# By default, the level is set to ERROR. Alternative logging levels
# are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO.
level = "DEBUG"
filePath = "/traefik.log"
[docker]
# Defines a default docker network to use for connections to all
# containers. This option can be overridden on a container basis
# with the traefik.docker.network label.
network = "traefik"
# Expose containers by default through Traefik. If set to false,
# containers that don't have a traefik.enable=true label will be
# ignored from the resulting routing configuration.
exposedbydefault = false
[api]
# Enable the API in insecure mode, which means that the API will be
# available directly on the entryPoint named traefik. If the entryPoint
# named traefik is not configured, it will be automatically created on
# port 8080.
insecure = true
[providers]
# Connection to docker host system (docker.sock)
# Attach labels to your containers and let Traefik do the rest!
# Traefik works with both Docker (standalone) Engine and Docker Swarm Mode.
# See: https://docs.traefik.io/providers/docker/
[providers.docker]
# Traefik requires access to the docker socket to get its dynamic
# configuration.
endpoint = "unix:///var/run/docker.sock"
[providers.file]
filename = "/traefik-provider.toml"
# EntryPoints are the network entry points into Traefik. They define
# the port which will receive the packets, and whether to listen for
# TCP or UDP.
# See: https://docs.traefik.io/routing/entrypoints/
# NOTE: If a TLS section (i.e. any of its fields) is defined in your docker-compose.yml file,
# then the default configuration does not apply at all.
[entryPoints]
# Standard HTTP redirects to HTTPS
[entryPoints.http]
address = ":80"
[entryPoints.http.http]
[entryPoints.http.http.redirections]
[entryPoints.http.http.redirections.entrypoint]
to = "https"
scheme = "https"
# Standard HTTPS
[entryPoints.https]
address = ":443"
[entryPoints.https.http.tls]
certResolver = "leresolver"
[[entryPoints.https.http.tls.domains]]
main = "HOST_NAME.DOMAIN_NAME"
# SANS are any other hostnames which Traefik should obtain a certificate for.
# If you are using DNS for LetsEncrypt, you can set a wildcard.
# Include all possible hostnames of this server.
#sans = ["*.DOMAIN_NAME"]
# Alternate HTTPS Port (for services - accepts both HTTP and HTTP by not defining a TLS configuration here)
[entryPoints.secure]
address = ":9999"
# Enable ACME (Let's Encrypt): automatic SSL.
[certificatesresolvers.leresolver.acme]
email = "YOU@DOMAIN_NAME"
storage = "acme.json"
# Use HTTP-01 ACME challenge
#[certificateresolvers.leresolver.acme.httpChallenge]
# entryPoint = "http"
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Mandatory for wildcard certificate generation.
[certificatesresolvers.leresolver.acme.dnsChallenge]
# Update this to your provider of choice and then ensure necessary variables are in the .env file to support it.
provider = "rfc2136"
delayBeforeCheck = 0
# A DNS server used to check whether the DNS is set up correctly before
# making the ACME request. Ideally a DNS server that isn't going to cache an old entry.
resolvers = ["8.8.8.8:53"]
[retry]
```
Due to a [quirk](https://github.com/containous/traefik/issues/5559) in Traefik, you cannot dynamically route to containers when network_mode=host. We have created a static route to the docker host (192.168.1.xx:8096) in `traefik-provider.toml`. The use of host networking (as in this doc) or macvlan are required to use DLNA or an HdHomeRun so it can utilize the multicast network. `traefik-provider.toml` defines the jellyfin-svc@file service which we are pointing the router to in the `docker-compose.yml` file. You can not set a URL in `docker-compose.yml` which is why we set up this service externally. Be sure to update the IP address below to the IP address of the host on the local network (in this case, 192.168.1.xx).
### traefik-provider.toml
```toml
[http]
[http.services]
[http.services.jellyfin-svc]
[[http.services.jellyfin-svc.loadBalancer.servers]]
url = "http://192.168.1.xx:8096"
# Set secure options by disabling insecure older TLS/SSL versions
# and insecure ciphers. SNIStrict disabled leaves TLS1.0 open.
# If you have problems with older clients, you can may need to relax
# these minimums. This configuration will give you an A+ SSL security
# score supporting TLS1.2 and TLS1.3
[tls.options]
[tls.options.default]
sniStrict = true
minVersion = "VersionTLS12"
curvePreferences = [
"secp521r1",
"secp384r1"
]
cipherSuites = [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
]
[tls.options.mintls13]
minVersion = "VersionTLS13"
```
### .env
```bash
RFC2136_NAMESERVER=...
RFC2136_TSIG_ALGORITHM=hmac-sha512.
RFC2136_TSIG_KEY=...
RFC2136_TSIG_SECRET=...
```
Finally, create an empty acme.json and traefik.log file to handle the certificate and log file for any logging
```bash
touch acme.json traefik.log
chmod 600 acme.json traefik.log
```
> [!WARNING]
> These configurations use DOMAIN_NAME (i.e.: example.com) and HOST_NAME (i.e.: servername) throughout it. You should replace these with your server's name. HOST_NAME.DOMAIN_NAME refers to the machine itself (ie: servername.example.com). Don't forget to update `traefik.toml`'s YOU@DOMAIN_NAME with your email address. Let's Encrypt does not require a valid email but invalid e-mails may be flagged as fake.
Launch the Traefik and Jellyfin services.
```bash
docker-compose up -d
```
If you set a PathPrefix (i.e. /jellyfin), you need to configure Jellyfin to expect it. After starting the service, access Jellyfin directly (via the host's IP at port 8096) and change the 'Base URL' in Dashboard / Advanced / Networking to match the '/jellyfin' path (if you used one in this configuration). Afterward, you may wish to create a firewall rule to prevent direct access to Jellyfin at port 8096 on the host, or simply ensure the port is not accessible via the Internet.
Congratulations, your stack with Traefik 2.x and Jellyfin is (hopefully) running! Check the log file or run without the '-d' parameter to review any errors that may come up, particularly with respect to the LetsEncrypt configuration.

View File

@ -0,0 +1,28 @@
---
uid: quick-start
title: Quick Start
---
# Quick Start
1. Install Jellyfin on [your system](xref:admin-installing) with the installation method for your platform.
1. Edit the [web configuration](xref:clients-web-config) and adjust the options to fit your desired privacy level.
* Our defaults sacrifice some absolute self-hosting for often requested features.
* If this is concerning, please review the documentation and edit accordingly.
1. Browse to `http://SERVER_IP:8096` to access the included web client.
1. Follow the initial setup wizard.
* Libraries and users can always be added later from the dashboard.
* Remember the username and password so you can login after the setup.
1. Secure the server with a method of your choice.
* Create an SSL certificate and add it on the **Networking** page.
* Put your server behind a [reverse proxy](networking/index.md#running-jellyfin-behind-a-reverse-proxy).
* Only allow local connections and refrain from forwarding any ports.
1. Enjoy your media!

View File

@ -0,0 +1,16 @@
---
uid: server-devices
title: Devices
---
# Devices
You can view all devices that have connected to the server from the settings. This will include both currently connected devices and any that have connected in the past. At the moment this page is really only useful to see connected devices and what users are registered to them.
## Options
The only option available at the moment is editing the display name. This can be useful for adding names that can better identify devices. The original name will stay visible in the options if you modify the value.
## Remove
If you don't want to keep old devices on the server you can remove them from this page. Please note that if a device connects again it will show up here. Removing a device does not hide the device forever, it simply cleans out old entries.

View File

@ -0,0 +1,27 @@
---
uid: server-libraries
title: Libraries
---
# Libraries
Libraries are virtual collections of media and can contain files from several different locations on the server.
You will see a page to add libraries when you first create the server, but they can also be added or removed at any time from the settings.
1. Log in to the Jellyfin web interface in your web browser.
2. On the menu that appears, click `Admin` > `Dashboard`.
3. Then again on the left side menu go to `Server` > `Libraries`.
4. Click "Add Media Library".
5. The server will now add your new media. There will be a progress bar at the top of the page indicating its progress.
## Content
The three most common types of content are movies, shows, and music. These will have the best support in client apps. You can also add other types of media such as books or photos. If you have several types of media in a single folder you can also label it as mixed, which will be a generic folder view that displays all files in the library.
> [!NOTE]
> Use of the mixed library type is currently discouraged due to unreliable metadata results. We encourage the use of the dedicated library types.
## Paths
You can add multiple paths that will all be shown under the same library. The path selection dialog will allow you to select folders visually, but if you can't find the exact location you can also just enter the path manually.

View File

@ -0,0 +1,43 @@
---
uid: server-live-tv-index
title: Live TV
---
# Live TV
Jellyfin allows you to watch and record live television using supported hardware. The first step is setting up a tuner to send data to Jellyfin, and then configure a source for the program guide data.
[Click here](xref:server-live-tv-setup-guide) for the general setup guide.
## Tuner
Jellyfin has support for the following tuners:
* HDHomeRun
* M3U
HDHomeRun is a special case because they will usually get detected automatically by the server. Otherwise you can manually add tuners by navigating to **Live TV** in the settings and adding one there.
> [!NOTE]
> Docker users using HDHomeRun devices should set networking to host mode as Jellyfin needs to connect to a changing UDP port.
M3U allows you to add IPTV channel playlists which you can view and record.
Additional tuner types are available via plugins.
## Guide
Guide data will need to be mapped to their corresponding channels after a guide data provider is configured. The guide data formats below are included with the server:
* Schedules Direct
* XMLTV
[Schedules Direct](http://www.schedulesdirect.org) is a paid service providing electronic program guide data to the United States and Canada.
[XMLTV](http://wiki.xmltv.org/index.php/Main_Page) is "... an XML based file format for describing TV listings. IPTV providers use XMLTV as the base reference template in their systems, and extend it internally according to their business needs."
## Status
You can view the status of each tuner connected to the server in the settings. There are also buttons to manually refresh the tuners if they experience problems.
The guide data can be refreshed manually if you run into problems. This isn't normally required since the data is refreshed periodically.

View File

@ -0,0 +1,85 @@
---
uid: server-live-tv-post-process
title: Live TV Post Processing
---
# Live TV Post Processing
## Recording Post Processing
Jellyfin supports Post Processing of recorded Live TV shows. This can be used to transcode the recording to a specific format that does not require transcoding on the fly when playing back, extract subtitles, remove commercials, and more.
> [!NOTE]
> There are several different ways to set up your post-processing script, and this largely will need to be changed to your individual use case.
>
>Described below is one way to do post processing, there may be other ways (other ways may be more efficient, too) to run your post-processor.
Mess around with this to change to your needs. Search around, post questions to the [Jellyfin Reddit Forum](https://www.reddit.com/r/jellyfin) or elsewhere, and others may be able to help. Logging is your friend! Make sure your script(s) logs adequately to a file or elsewhere in order to troubleshoot any issues you may encounter, as any output to stdout/stderror will not be seen in the Jellyfin logs.
## Jellyfin Dashboard/DVR/Recording Post Processing Settings
Jellyfin runs the script you specify in the Admin Dashboard DVR settings with a command line parameter of the filepath automatically when recording finishes.
In Jellyfin Dashboard/DVR/Recording Post Processing settings:
Set "Post-processing application" to your shell script which calls your actual post processor (details of this 'actual' post processor script below). In this example, that would be `/path/to/run_post_process.sh`
Set "Post-processor command line arguments" to `"{path}"`.
![Live TV post process DVR Settings](~/images/live-tv-post-process_dvr-settings.png)
With the settings above, the server executes this command when running the post processor:
````bash
"/path/to/run_post_process.sh" "\"/path/to/LiveTV/Shows/Series/Season/Episode.ts\""
````
## Run Post Processor Shell Script (to be run directly by Jellyfin Server)
Quote interpretation is one of the hardest things to manage when using a post-processor script. Because of this, one easy way to run your post-processor is to have Jellyfin start a "runner" shell script, which then calls your actual post-processor script. This shell script then can be put into Jellyfin settings, and have a "clean" shell environment where it is easier to configure, look at logs, and more.
In the sample script below:
- Logging is enabled, and a logfile is created at some location accessible by your Jellyfin instance.
- The first command line argument, `$1` is written to the logfile (majorly for debugging purposes). This argument will be a path to the show to be post-processed. This argument is in the format of `/path/to/LiveTV/Shows/Series/Season/Episode.ts`
- The actual post processor Python script `record_post_process.py` is then called with s command line argument of the file name.
### An example `run_post_processor.sh` script
[GitHub Gist link to `run_post_processor.sh`](https://gist.github.com/AndrewBreyen/0fc36c868486d48583a369b657e22c69)
````bash
#!/bin/sh
exec > "/path/to/logging/directory/logs/$(date +"%Y-%m-%d_%H-%M-%S")-run_post_process-sh.log" 2>&1
echo $1
/usr/local/bin/python3 /path/to/record_post_process.py "$1"
````
## Post Processor Python Script (to be run by `run_post_processor.sh`)
In this example, a python script is where it all goes down. I chose to use Python primarilly because of how adaptable it is, and various third party extensions and packages that make it ideal for a post-processing script. This script can be customized to fit your individual requirements.
In the sample script:
- Logging is enabled, and a logfile is created at some location accessible by your Jellyfin instance.
- Command line arguments are checked, if no argument provided, script exits.
- Variables are determined for things such as the full non-transcoded file path, the basename, the file to be transcoded with extension, transcoded file name and path, and more.
- FFMPEG command is created and ran.
- In this example, the `h264_videotoolbox` video codec is used, and the audio is copied from source. Change the ffmpeg command to fit your requirements.
- Nontranscoded file is moved out of the Series/Season directory, into a folder not accessible by Jellyfin, called OLDFILES (This portion could also be configured to delete the non-transcoded file)
### An example `record_post_process.py` script
This script is too much to post here, so a link to a GitHub Gist is provided.
Comments are listed that describes what each section does.
[GitHub Gist Link to `record_post_process.py`](https://gist.github.com/AndrewBreyen/1ac109bb485d8523e28fe98b3a222602)
## Diving Deeper
Once you have post processing working in a basic format, there is loads more that can be done!
Some ideas:
- [Commercial Skipping with comskip](https://www.reddit.com/comments/jvzxnd/comment/hh6zwdn/)
- Post transcode progress to a Slack/Discord channel for notifications when transcoding starts/finishes

View File

@ -0,0 +1,88 @@
---
uid: server-live-tv-setup-guide
title: Setup Guide
---
# Setup Guide
## Add a TV Tuner to Jellyfin (Automatic Discovery)
Click on the Admin Panel Icon in the top right corner (1)
Click 'Live TV' (2) under the 'Live TV' section
Click the '+' button (3) next to 'Tuner Devices'
![How to access the 'Tuner Devices' page](~/images/live-tv-setup-tuner1.png)
Click 'Detect My Devices' from the 'Live TV Tuner Setup' page that opens
Jellyfin will search and hopefully find your tuner automatically:
![An example of detected TV tuner devices](~/images/live-tv-setup-tuner2.png)
Click on the device you'd like to set up then set any options then click 'Save'
![Saving TV tuner setup](~/images/live-tv-setup-tuner3.png)
## Add a TV Tuner to Jellyfin (Manual Setup)
You can set up your tuners manually if they were not automatically discovered. Click the 'Tuner Type' pull down. Choose between 'HD Homerun', 'M3U Tuner', and 'Other'
![Manually adding a TV tuner](~/images/live-tv-setup-tuner4.png)
### HDHomeRun Specific Options
* Tuner IP Address is the URL of your HDHomeRun device. The format will be `http://YOUR.IP.ADDRESS`
* Allow hardware transcoding will allow the tuner to transcode the video on the fly which can reduce server load. Not all HDHomeRun devices support hardware transcoding.
* Restrict to channels marked as favorite will only import channels that are designated as favorite channels on the tuner. This helps if your tuner autoscans and adds new channels that you do not want and/or adds channels that you are able to receive due to atmospheric conditions but later are not accessible.
To set a favorite, go to the [HDHomeRun website](http://my.hdhomerun.com), select your tuner and then click on the grey star next to the channel name to change the star to yellow. The yellow star indicates a favorited channel. In this example, only the channels with yellow stars will be imported into Jellyfin
![Selecting favorites in HDHomeRun](~/images/live-tv-setup-hdhr_opt1.png)
### M3U Tuner Specific Options
This tuner allows you to add IPTV channel to Jellyfin by using the appropriate M3U8 playlist file.
* File or URL is the location of the M3U8 playlist. The file can either be stored online at a web (HTTP) address or stored locally.
* User agent is needed in special cases where you need to supply a custome HTTP header to access the remotely stored M3U8 playlist
* Simultaneous stream limit will restrict the number of streams the server can have open at one time. Setting this value to '0' will allow for unlimited streams
* Auto-loop live streams is sometimes necessary for some IPTV channels. Turn this on only if your streams are not playing correctly
> [!NOTE]
> Here is a list of legal samples to use to test connectivity.
>
> [LegalStream Live News Playlist](https://raw.githubusercontent.com/notanewbie/LegalStream/master/packages/news/live.m3u8)
## Adding Guide Data
Guide data is necessary for scheduling tv recordings and for browsing what's currently playing and what will air later. Follow these steps once you have a tuner device set up. Click on the Admin Panel Icon in the top right corner, Click 'Live TV' (2) under the 'Live TV' section, Click the '+' button next to 'TV Guide Data Providers' :
![How to add guide data](~/images/live-tv-setup-guide1.png)
Choose between 'Schedules Direct' and 'XMLTV'. You currently cannot use both at the same time.
**Schedules Direct:**
Schedules Direct is a paid service that provides U.S. and Canadian guide data for use in OSS projects. The price is $25 a year and has not increased since it began in 2007. The guide data is highly reliable. You will have to create an account at their [website](http://www.schedulesdirect.org).
**XMLTV:**
This option allows for downloading of guide data in the [XMLTV](http://wiki.xmltv.org/index.php/XMLTVFormat) format.
To create an XML file with guide data, there are several different methods. A reliable way to do this is to use [shuaiscott's zap2xml Docker container](https://github.com/shuaiscott/zap2xml).
## Mapping Channels
Guide data from the 'TV Guide Data Providers' will need to be mapped to the physical channel from the tuner. Click the '...' next to the guide provider you set up and select 'Map Channels'
![Step 1 of mapping channels](~/images/live-tv-setup-channels1.png)
The list of physical channels will be displayed. Click the pencil icon to the right of the channel and then select the corresponding channel from the guide provider to map the channel. Do this for all channels. Click the left arrow at the top left of the window to exit and save the information.
![Step 2 of mapping channels](~/images/live-tv-setup-channels2.png)
The guide data will now automatically imported. You can check that the data has been imported correctly by going to the 'Live TV Guide' page from the main Jellyfin web page on your server.

View File

@ -0,0 +1,55 @@
---
uid: server-media-books
title: Books
---
# Books
The most common organization scheme for books is separation by Audiobook then by Author.
```txt
Books
├── Audiobooks
│ ├── Author
│ │ ├── Book1.flac
│ │ └── Book2.flac
│ └── Book
│ ├── Chapter1.flac
│ └── Chapter2.flac
└── Books
└── Author
├── Book1.epub
├── Book2.epub
├── Book
│ ├── Book1.epub
│ ├── cover.ext
│ └── metadata.opf
└── Book3.mp3
```
File extensions supported include azw, azw3, cb7, cbr, cbt, cbz, epub, mobi, and pdf.
## Local Metadata
In case the book is stored in the epub format, internal metadata can be provided. For every other format, metadata has to be provided externally in a `content.opf` or `metadata.opf` file. When multiple books have been published by the same author, it is recommended to place each book into a seperate folder. This allows to provide local metadata for every book.
Either the `content.opf` or the `metadata.opf` file can tell Jellyfin which file should be used for the books cover. Usually, this is the `cover.ext` file. The abbreviation `ext` stands for extension, e.g. `.png` or `.jpg`.
## Primary
* folder
* poster
* cover
## Banner
* banner
## Logo
* logo
## Thumb
* thumb
* landscape

View File

@ -0,0 +1,58 @@
---
uid: server-media-comics
title: Comics
---
# Comics / Mangas
Comics and mangas, from now on referred to as comics, should usually be in the library root directory or in a subfolder for the individual comics. The subfolders allow for organization of metadata and images. They use the "Books" library type and metadata is provided with the Bookshelf plugin.
> [!Note]
> For the best reading experience, it is recommended to store comics in the comic book archive or pdf format. This is due to issues when trying to read comics stored in the epub format. Please note, that Jellyfin 10.8 and later saves your reading position for comics in the comic book archive format, but does not save whether you finished the comic or not.
## Naming
> [!Note]
> The Bookshelf plugin does not provide an online metadata provider that is specific to comics. Metadata can either be provided from the same providers used for books or from local files.
For best results, it is recommended to name the files similar to the following schema where the volume number and issue number are used **interchangeable**.
```txt
Series_Name #IssueNumber (of Count) (PubYear).ext
Series_Name (SeriesYear) #IssueNum (of Count) (PubYear).ext
```
- Count = Total number of issues
- PubYear = Publication year of the issue
- SeriesYear = Start year of the series
- .ext = file extension, e.g. `.cbz` or `.cbr`. For a list of supported file extensions, please refer to the [section on books](xref:server-media-books).
Take a look at the following example:
```txt
Comics
├── Plastic Man #002 (1944).cbz
├── Attack on Titan #001 (2012).cbz
└── Comic (2008)
├── ComicInfo.xml
└── Comic #001 (2008).cbr
```
Placing comics into a subfolder allows the placement of a `ComicInfo.xml` file for metadata parsing. Currently, Jellyfin does not support this for a series as a whole, but only for individual comics.
## Local Metadata for "Comic Book Archive's"
Should your files **not** correspond to either `.cbz` or `.cbr` files, please refer to the [section on books](xref:server-media-books) to see what is supported.
The following metadata formats are supported:
- ComicInfo (from ComicRack)
- ComicBookInfo (from ComicBookLover)
> [!Note]
> The ComicBookInfo format is supported when using the Bookshelf plugin version 8 or later.
Should the ComicInfo be used, please make sure that the comic provides the metadata. If it does not, a `ComicInfo.xml` file can be placed in the same folder as the comic and the metadata will be parsed from this file.
> [!Note]
> For comics using the `.cbr` format, it is required to place a `ComicInfo.xml` file inside the folder. This file should contain the metadata of that comic.

View File

@ -0,0 +1,54 @@
---
uid: server-media-external-files
title: External files
---
# External files
Audio and subtitles will usually be embedded within your video container file (e.g. mkv), but the server also supports loading audio and subtitle streams from external files.
The server supports reading either single files or containers like mka (Matroska Audio) or mks (Matroska Subtitle) with one or more streams.
> [!Note]
> External audio files and containers are supported on Jellyfin 10.8 and later.
## Naming
Jellyfin will search for external files that exactly match the video filename.
They can optionally include a language which will only be used if the language cannot be determined from the file metadata.
They can also include the `forced` (or `foreign`) and `default` flags to mark the streams accordingly.
Those flags are ignored on containers with more than one stream.
Flags and language need to be appended to the video filename with `.` as delimiter.
If multiple languages are defined within the filename the last one will be used and the others ignored.
Any arbitrary text not parsable to a language or flag will be combined and used as the title of the stream.
### Simple example
```txt
/Movies
/Film (1946)
Film.mkv
Film.vtt
Film.aac
Film.de.srt
Film.en.dts
Film.german.ac3
```
## Extended example with flags and stream title
```txt
/Movies
/Film (1986)
Film.mkv
Film.mka
Film.mks
Film.en.ac3
Film.default.srt
Film.default.en.forced.ass
Film.forced.forced.en.dts
Film.English Commentary.en.mp3
```
> [!Note]
> The last file will parse to an English mp3 audio stream with the title `English Commentary`.

View File

@ -0,0 +1,22 @@
---
uid: server-media-internet-radio
title: Internet radio
---
# Internet radio
It is possible to add Internet radio stations (e.g. shoutcast) to Jellyfin by utilizing the Live TV M3U Tuner device type. Directly entering links into the M3U tuner is supported, but it depends on the provider.
If the M3U is not supported, it is most like due to missing headers in the link. Create a new M3U file containing the following data.
```#EXTM3U
#EXTINF:0,Radio Freccia
https://streamingv2.shoutcast.com/radiofreccia
```
Note that the line that starts with `#EXTINF:0,<title>` is needed for each radio URL to give it a 'channel' entry under Live TV \ Channels. Failing to add this line will cause the station to not show up under Live TV \ Channels.
Next, head over to the Jellyfin administration page, go to Live TV, add new tuner device, choose M3U Tuner as Tuner type and navigate to your M3U file. Hit Save and let Jellyfin complete the Refresh Guide task (automatically started when saving a new tuner). You should now be able to play your radio station from under Live TV \ Channels.
> [!NOTE]
> Adding an M3U HTTP link instead of a locally created M3U file will almost certainly fail, in part because the `#EXTINF:` directive is part of the IPTV standard, which is required to name the channel for Jellyfin to list it under Live TV \ Channels. Pretty much no Internet radio will include this directive in their M3U files. Besides that, many radio stations use AJAX to dynamically update the M3U-files while listening, something that is not handled by Jellyfin.

View File

@ -0,0 +1,196 @@
---
uid: server-media-movies
title: Movies
---
# Movies
Movies should usually be in the library root directory or in a subfolder for the individual films. The subfolders allow for organization of metadata and images. Adding the year at the end in parentheses will yield the best results when scraping metadata.
> [!TIP]
> In order to help with identifying a movie, Jellyfin can make use of media provider identifiers. This can be specified in your movie's folder name, for example: `Film (2010) [imdbid-tt0106145]` or `Film (2018) [tmdbid-65567]`
```txt
Movies
├── Film (1990).mp4
├── Film (1994).mp4
├── Film (2008)
│   └── Film.mkv
└── Film (2010)
├── Film-cd1.avi
└── Film-cd2.avi
```
## Multiple Versions of a Movie
Multiple versions of a movie can be stored together and presented as a single title. Place each movie version in the same folder and give each version a name with the folder name as a prefix as seen below.
```txt
Movies
└── Best_Movie_Ever (2019)
├── Best_Movie_Ever (2019) - 1080P.mp4
├── Best_Movie_Ever (2019) - 720P.mp4
└── Best_Movie_Ever (2019) - Directors Cut.mp4
```
To distinguish between versions, each filename needs to have a space, hyphen, space, and then a label. Labels are not predetermined and can be made up by the user.
> [!Note]
> The hyphen is required. Periods, commas and other characters are not supported.
Additionally, labels can be placed between brackets with the same result as seen below.
```txt
Movies
└── Best_Movie_Ever (2019)
├── Best_Movie_Ever (2019) - [1080P].mp4
├── Best_Movie_Ever (2019) - [720P].mp4
└── Best_Movie_Ever (2019) - [Directors Cut].mp4
```
If labels are not added to the end of filenames, as shown above, each file will be treated as a unique movie and not a version of the same movie.
### Order of Versions
Movie versions are presented in an alphabetically sorted list. An exception applies to resolution names, which are sorted in descending order from highest to lowest resolution. A version name qualifies as a resolution name when ending with either a `p` or an `i`.
> [!Note]
> The first movie version in the list is the one selected by default.
#### Examples of Sorting
* `1080p`, `2160p`, `360p`, `480p`, `720p``2160p`, `1080p`, `720p`, `480p`, `360p`
* `Extended Cut`, `Cinematic Cut`, `Director's Cut``Cinematic Cut`, `Director's Cut`, `Extended Cut`
> [!Note]
> To group media manually, long-click or right-click media to highlight then select additional media to merge. Use the new bar that appears to 'Group Versions'.
## Movie Extras
Movie extras can include deleted scenes, interviews, and other various things that you would want to include alongside your movie. Jellyfin supports several different methods of adding these files.
### Extras Folders
One of the cleanest ways of adding extras is to place them in subfolders within your movie folder.
Supported folder types are:
* `behind the scenes`
* `deleted scenes`
* `interviews`
* `scenes`
* `samples`
* `shorts`
* `featurettes`
* `extras` - Generic catch all for extras of an unknown type.
* `trailers`
```txt
Movies
└── Best_Movie_Ever (2019)
├── Best_Movie_Ever (2019) - 1080P.mp4
├── Best_Movie_Ever (2019) - 720P.mp4
├── Best_Movie_Ever (2019) - Directors Cut.mp4
├── behind the scenes
│ ├── Making of the Best Movie Ever.mp4
│ └── Finding the right score.mp4
├── interviews
│ └── Interview with the Director.mp4
└── extras
└── Home recreation.mp4
```
### File Name
Some types of extras support a special option if you only have a single of that type. These options are to name the filename a specific word when stored in the same folder as the movie.
Supported filenames are:
* `trailer`
* `sample`
* `theme` - Audio file of the theme song
```txt
Movies
└── Best_Movie_Ever (2019)
├── Best_Movie_Ever (2019) - 1080P.mp4
├── sample.mp4
├── theme.mp3
└── trailer.mp4
```
### File Suffix
If you would rather keep everything in a single folder, you can append special suffixes to the filename which Jellyfin picks up and uses to identify the file as an extra. Note that, with a few noted exceptions, these suffexes **DO NOT** contain any spaces.
<!-- markdownlint-disable MD038 -->
* `-trailer`
* `.trailer`
* `_trailer`
* ` trailer` - This is a space followed by the word `trailer`
* `-sample`
* `.sample`
* `_sample`
* ` sample` - This is a space followed by the word `sample`
* `-scene`
* `-clip`
* `-interview`
* `-behindthescenes`
* `-deleted`
* `-featurette`
* `-short`
<!-- markdownlint-enable MD038 -->
```txt
Movies
└── Best_Movie_Ever (2019)
├── Best_Movie_Ever (2019) - 1080P.mp4
├── That clip that I want everyone to see-clip.mp4
├── Release Trailer-trailer.mp4
├── Preview Trailer.trailer.avi
├── Release Trailer 2_trailer.avi
├── Teaser.sample.mp4
├── Favorite Scene-scene.mp4
├── The Best Ever-clip.mp4
├── Making of The Best Movie Ever-behindthescenes.mp4
├── Not the best scene-deleted.mp4
├── Theme Song Music Video-featurette.mp4
└── Art of the Best Movie Ever-short.mp4
```
## Images
### Poster
* folder.ext
* poster.ext
* cover.ext
* default.ext
* movie.ext
Examples:
Movie (2010)/poster.jpg
### Backdrop
* backdrop.ext
* fanart.ext
* background.ext
* art.ext
* extrafanart/*.ext
Examples:
Movie (2010)/fanart.jpg *for the first backdrop image*
Movie (2010)/extrafanart/fanart1.jpg, Movie (2010)/extrafanart/fanart2.jpg, *etc for additional backdrop images*
### Logo
* logo.ext
* clearlogo.ext
Example:
Movie (2010)/logo.png

View File

@ -0,0 +1,94 @@
---
uid: server-media-music
title: Music
---
# Music
The most common organization scheme for music is separation by artist and then album.
```txt
/Music
/Artist
/Album
01 - Song.mp3
02 - Song.mp3
```
You can also separate your music into artist folders or with no folder structure at all.
```txt
/Music
/Artist
01 - Song.flac
02 - Song.flac
08 - Song.ogg
09 - Song.ogg
```
Individual songs have no required parameters for filenames since the information will be scraped from metadata.
## Discs
Albums with several discs will be fine with the metadata tags, but you can also use subfolders for the discs. The number can be appended after a space, hyphen, or directly after one of the following keywords.
* Disc
* Disk
* CD
* Vol
* Volume
```txt
/Music
/Artist
/Album
/Disc 1
01 - Song.mp3
02 - Song.mp3
/Disc 2
01 - Song.mp3
02 - Song.mp3
```
## Images
Images will be scraped from album or artist folders, and they can also be embedded in the music files themselves. The supported filenames are listed below for each respective image.
### Primary
* folder
* poster
* cover
* default
### Art
* clearart
### Backdrop
Multiple backdrop images can be used to cycle through several over time. Simply append a number to the end of the filename directly after or after a hyphen.
* backdrop
* fanart
* background
* art
* extrafanart
### Banner
* banner
### Disc
* disc
* cdart
### Logo
* logo
### Thumb
* thumb
* landscape

View File

@ -0,0 +1,129 @@
---
uid: server-media-shows
title: Shows
---
# Shows
The most common naming scheme for shows is categorizing the files by series and then season. Another common method is simply using series folders, especially for shows that are organized by air date and those without seasons. Adding the year at the end in parentheses will yield the best results when scraping metadata.
> [!TIP]
> In order to help with identifying a series, Jellyfin can make use of media provider identifiers. This can be specified in your show's folder name, for example: `Series (2010) [imdbid-tt0106145]` or `Series (2018) [tmdbid-65567]`
```txt
Shows
├── Series (2010)
│ ├── Season 00
│ │ ├── Some Special.mkv
│ │ ├── Episode S00E01.mkv
│ │ └── Episode S00E02.mkv
│ ├── Season 01
│ │ ├── Episode S01E01-E02.mkv
│ │ ├── Episode S01E03.mkv
│ │ └── Episode S01E04.mkv
│ └── Season 02
│ ├── Episode S02E01.mkv
│ └── Episode S02E02.mkv
└── Series (2018)
├── Episode S01E01.mkv
├── Episode S01E02.mkv
├── Episode S02E01-E02.mkv
└── Episode S02E03.mkv
```
> [!NOTE]
> Avoid special characters such as \* in M\*A\*S\*H, use MASH instead.
> [!NOTE]
> Season folders shouldn't contain the series name, otherwise Jellyfin can in certain cases (Stargate SG-1 due to the dash and one, for instance) misdetect your episodes and put them all under the same season.
## Show Extras
Show extras, sometimes called specials, can be added in the `Season 00` folder. If supported by your metadata provider those files will be matched. In case your metadata provider does not provide information about the extra, it is recommended to use a name which describes the content of the special instead of naming it `Episode S00Exy.mkv`. This is done to avoid wrong metadata being pulled for the extra and to provide a proper presentation.
> [!NOTE]
> Episode numbering for specials may vary from metadata provider to metadata provider.
## Images
### Poster
* folder.ext
* poster.ext
* cover.ext
* default.ext
* show.ext
Examples:
* Series:
* Series (2010)/poster.jpg
* Season posters:
* Numbered seasons:
* Series (2010)/Season 01/cover.jpg
* Series (2010)/season1-poster.jpg
* Specials:
* Series (2010)/season-specials-poster.jpg
### Backdrop
* backdrop.ext
* fanart.ext
* background.ext
* art.ext
* extrafanart/*.ext
Examples:
Series (2010)/fanart.jpg *for the first backdrop image*
Series (2010)/extrafanart/fanart1.jpg, Series (2010)/extrafanart/fanart2.jpg, *etc for additional backdrop images*
### Banner
* banner.ext
Example:
Series (2010)/banner.jpg
### Thumb
* thumb.ext
* landscape.ext
Examples:
Series (2010)/landscape.jpg
Series (2010)/Season 01/episode filename-thumb.jpg *for the thumbnail of an episode named "episode filename.mkv"*
### Logo
* logo.ext
* clearlogo.ext
Example:
Series (2010)/logo.png
## Other
### Theme Videos
* backdrops/*
Example:
Series (2010)/backdrops/S1Intro.ext
### Theme Music
* theme.ext
* theme-music/*
Examples:
Series (2010)/theme.ext
Series (2010)/theme-music/intro-song.ext

View File

@ -0,0 +1,16 @@
---
uid: server-notifications
title: Notifications
---
# Notifications
You can use notifications to get alerts when certain events happen on your server. Some common notifications include plugin installations and different user events.
## Services
Notifications can be sent using different services depending on what kind of integration you want. Jellyfin will show notifications on the dashboard by default, but you can install alternative services on the **Plugins** page. Most services will require additional configuration but can be extremely useful for those who want instant updates for activity on their server.
## Configuration
You can properly configure this feature on the **Notifications** page in the settings. All notification types will be shown in a list as well as their current status. They can be enabled individually and can be set to only monitor specific users. Any installed notification services will show up in a list in this section.

View File

@ -0,0 +1,365 @@
---
uid: server-plugins-index
title: Plugins
---
# Plugins
Jellyfin has a collection of optional plugins that can be installed to provide additional features. To create a plugin, see the [plugin template](https://github.com/jellyfin/jellyfin-plugin-template) repository.
## Installing
### Catalog
Many plugins are available in a repository hosted on our servers, which can be easily installed using the plugin catalog in the settings. At the moment many of these are still being updated frequently so the version number may not be accurate. There are several different categories that can indicate what kind of functionality the plugins may provide.
**Note to Windows Users:**
Due to currently unresolved permission issues on Jellyfin Windows installs it is not possible to update and/or uninstall plugins from the UI.
To update and/or uninstall plugins you must stop Jellyfin, navigate to the local *plugins folder* and delete the `.dll` files for the plugins you want to update and/or uninstall.
The *plugins folder* is located in different locations depending on your install:
* `%UserProfile%\AppData\Local\jellyfin\plugins` for direct installs
* `%ProgramData%\Jellyfin\Server\plugins` for tray installs
After that start Jellyfin back up, and reinstall each plugin you want to update using the above method from the catalog.
Plugin settings should be retained if you do not delete the `.xml` files from the `<direct or tray path>\plugins\configurations` folder.
**Authentication:** Add new authentication providers, such as LDAP.
**Channels:** Allow streaming remote audio or video content.
**General:** Plugins that serve general purposes, such as sync with Trakt.tv, or Kodi.
**Live TV:** Plugins that help with connecting to tuners, such as NextPVR, or TVHeadend.
**Metadata:** Scrape metadata from a new source or modify existing metadata.
**Notifications:** Allow notifications to connect to many different services, including Gotify and Slack.
### Manual
All plugins hosted on the repository can be built from source and manually added to your server as well. They just need to be placed in the plugin directory, which is something like `/var/lib/jellyfin/plugins/` on most Linux distributions. Once the server is restarted any additions should automatically show up in your list of installed plugins. If you can't see the new plugin there may be a file permission issue.
## List
### Official Plugins
#### Metadata Plugins
Manage your Anime in Jellyfin with several different metadata providers and options for organizing your collection.
##### Anilist
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
Provides metadata support from [Anilist](https://anilist.co/).
**Link:**
* [Github](https://github.com/jellyfin/jellyfin-plugin-anilist)
##### Anidb
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
Provides metadata support from [Anidb](https://anidb.net/).
**Link:**
* [Github](https://github.com/jellyfin/jellyfin-plugin-anidb)
##### Anisearch
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
Provides metadata support from [Anisearch](https://www.anisearch.com/).
**Link:**
* [Github](https://github.com/jellyfin/jellyfin-plugin-anisearch)
##### Bookshelf
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
Supports several different metadata providers and options for organizing your collection.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
##### Kitsu
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
Provides metadata support from [Kitsu](https://kitsu.io/).
* [Github](https://github.com/jellyfin/jellyfin-plugin-kitsu)
#### Fanart
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
Scrape poster images for movies, shows, and artists in your library from [fanart.tv](https://fanart.tv).
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-fanart)
#### Kodi Sync Queue
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
Helps keep Jellyfin for Kodi in sync with the library without needing to run periodic full scans.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
#### LDAP
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
Authenticate your Jellyfin users against an LDAP database, and optionally create users who do not yet exist automatically. Allows the administrator to customize most aspects of the LDAP authentication process, including customizable search attributes, username attribute, and a search filter for administrative users (set on user creation). The user, via the "Manual Login" process, can enter any valid attribute value, which will be mapped back to the specified username attribute automatically as well.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
#### NextPVR
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
Provides access to Live TV, Program Guide, and Recordings from [NextPVR](https://www.nextpvr.com/).
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
#### [Open Subtitles](xref:server-plugins-open-subtitles)
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
Download subtitles from the internet to use with your media files from [Open Subtitles](https://www.opensubtitles.org/). You can configure the languages it downloads on a per-library basis.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
#### Playback Reporting
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
Collect and show user playback statistics, such as total time watched, media watched, time of day watched and time of week watched. Can keep information for as long as you want, or can cull older information automatically. Also allows you to manually query the data collected so you can generate your own reports.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
#### Reports
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
Generate reports of your media library.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-reports)
#### TMDb Box Sets
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
Automatically create movie box sets based on TMDb collections. Configerable minimum number of films to be considered a boxset. Boxsets are created as collections, and includes a schedueld task to ensure that new media is automatically put into boxsets.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
#### Trakt
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
Record your watched media with [Trakt](https://trakt.tv).
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-trakt)
#### TVHeadend
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
Manage TVHeadEnd from Jellyfin. Click [here](xref:server-plugins-tvheadend) for plugin support.
**Links:**
* [GitHub](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
### 3rd-Party Plugins
#### Antennas
Takes your tuners in TVHeadEnd and emulates a HDHomeRun, in order to connect to Jellyfin's Live TV and DVR features. It requires additional setup and configuration, but is a useful alternative to the TVHeadEnd plugin.
**Links:**
* [GitHub](https://github.com/TheJF/antennas)
#### Merge Versions
Automatically group every repeated movie.
**Links:**
* [GitHub](https://github.com/danieladov/jellyfin-plugin-mergeversions)
#### Skin Manager
Download and manage the most popular skins.
**Links:**
* [GitHub](https://github.com/danieladov/jellyfin-plugin-skin-manager)
#### Intros
Download flashy intros from prerolls.video for your movies.
**Links:**
* [GitHub](https://github.com/dkanada/jellyfin-plugin-intros)
#### YouTube Metadata
Downloads metadata of YouTube videos with a YouTube API key.
**Links:**
* [GitHub](https://github.com/ankenyr/jellyfin-youtube-metadata-plugin)
#### Last.FM
Enables audio scrobbling to Last.FM as well as a metadata fetcher source.
**Links:**
* [GitHub](https://github.com/jesseward/jellyfin-plugin-lastfm)
#### Kinopoisk metadata plugin
Fetches metadata from <https://kinopoisk.ru>. This site is popular in the Russian-speaking community and contains almost no English-language information. Can provide movies and series rating, description, actors and staff, trailers and so on.
**Links:**
* [GitHub](https://github.com/LinFor/jellyfin-plugin-kinopoisk)
#### Shokofin
A plugin to integrate your Shoko database with the Jellyfin media server.
**Links:**
* [GitHub](https://github.com/ShokoAnime/Shokofin)
#### Ani-Sync
Ani-Sync lets you synchorinze/scrobble your Jellyfin Anime watch progress to popular services like MyAnimeList, AniList, Kitsu.
**Links:**
* [GitHub](https://github.com/vosmiic/jellyfin-ani-sync)
## Repositories
### Official Jellyfin Plugin Repositories
#### Default Repository
* Manifest
* [https://repo.jellyfin.org/releases/plugin/manifest-stable.json](https://repo.jellyfin.org/releases/plugin/manifest-stable.json)
### 3rd-Party Plugin Repositories
#### dkanada's Repo
* Manifest
* [https://raw.githubusercontent.com/dkanada/jellyfin-plugin-intros/master/manifest.json](https://raw.githubusercontent.com/dkanada/jellyfin-plugin-intros/master/manifest.json)
* Included Plugins
* [Intros](https://github.com/dkanada/jellyfin-plugin-intros)
#### danieladov's Repo
* Manifest
* [https://raw.githubusercontent.com/danieladov/JellyfinPluginManifest/master/manifest.json](https://raw.githubusercontent.com/danieladov/JellyfinPluginManifest/master/manifest.json)
* Included Plugins
* [Merge Versions](https://github.com/danieladov/jellyfin-plugin-mergeversions)
* [Skin Manager](https://github.com/danieladov/jellyfin-plugin-skin-manager)
* [Theme Songs](https://github.com/danieladov/jellyfin-plugin-themesongs)
#### k-matti's Repo
* Manifest
* [https://raw.githubusercontent.com/k-matti/jellyfin-plugin-repository/master/manifest.json](https://raw.githubusercontent.com/k-matti/jellyfin-plugin-repository/master/manifest.json)
* Included Plugins
* [SMS Notifications](https://github.com/k-matti/jellyfin-plugin-sms)
* [NapiSub](https://github.com/k-matti/jellyfin-plugin-napi)
#### LinFor's Repo
* Manifest
* [https://raw.githubusercontent.com/LinFor/jellyfin-plugin-kinopoisk/master/dist/manifest.json](https://raw.githubusercontent.com/LinFor/jellyfin-plugin-kinopoisk/master/dist/manifest.json)
* Included Plugins
* [Kinopoisk metadata plugin](https://github.com/LinFor/jellyfin-plugin-kinopoisk)
#### ShokoAnime's Repo
* Manifest
* [https://raw.githubusercontent.com/ShokoAnime/Shokofin/master/manifest.json](https://raw.githubusercontent.com/ShokoAnime/Shokofin/master/manifest.json)
* Included Plugins
* [Shokofin](https://github.com/ShokoAnime/Shokofin)
#### 9p4's Single-Sign-On (SSO) Repo
* Manifest
* [https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/manifest-release/manifest.json](https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/manifest-release/manifest.json)
* Included Plugins
* [9p4's Single Sign On Plugin](https://github.com/9p4/jellyfin-plugin-sso)
#### Ani-Sync Repo
* Manifest
* [https://raw.githubusercontent.com/vosmiic/jellyfin-ani-sync/master/manifest.json](https://raw.githubusercontent.com/vosmiic/jellyfin-ani-sync/master/manifest.json)
* Included Plugins
* [Ani-Sync](https://github.com/vosmiic/jellyfin-ani-sync)

View File

@ -0,0 +1,8 @@
---
uid: server-plugins-open-subtitles
title: Open Subtitles
---
# Open Subtitles
This plugin will allow your server to download subtitles from OpenSubtitles.com for any video file on your server. The plugin can be installed from the catalog page and once enabled you will need to enter your OpenSubtitles.com account info in the plugin configuration page.

View File

@ -0,0 +1,73 @@
---
uid: server-plugins-tvheadend
title: TVHeadend
---
# TVHeadend
The objective of the guide is to configure the Jellyfin TVHeadend plugin to backend a TVHeadend server.
## Requirements
* TVHeadend server
* Jellyfin server
* TVHeadend plugin installed in Jellyfin
## Configuration
<!-- markdownlint-disable MD029 ol-prefix -->
1. Create a user for Jellyfin in TVHeadend: it is convenient to create a specific user for Jellyfin.
* Go to Configuration > Users > Access Entries > Add
* Give the user parameters
* Enabled: ✔
* Username: *Username* (for example: Jellyfin)
* Change parameters: Rights,Channel number range,Channel tags,DVR configurations,Streaming profiles,Connection limits
* Web interface: ✔
* Streaming: Basic,Advanced,HTSP
* Video recoder: Basic,HTSP,View all
* (Optional) Comment: Comment for the user (for example: User used by Jellyfin)
* (Optional) Allowed networks: *Network address with network mask to allow* (for example 127.0.0.1/32)
* Press Save
* Go to Configuration > Users > Passwords > Add
* Give the user parameters
* Enabled: ✔
* Username *The user created previously* (for example: Jellyfin)
* Password: *The password for the user created previously* (for example: Jellyfin_password)
* Press Save
> [!NOTE]
> The parameters Change parameters, Streaming and Video recoder must be marked as shown. Otherwise, Jellyfin can connect to TVHeadend but problems may arise when reproducing the content.
2. Adjust the Jellyfin TVHeadend plugin to establish the connection.
* Go to Dashboard > Plugins > TVHeadend > Settings
* Provide creator access data previously:
* TVHeadend Hostname or IP Address: *IP address of the TVHeadend server* (for example: 127.0.0.1)
* Username: *The user created previously* (for example: Jellyfin)
* Password: *The password created previously* (for example: Jellyfin_password)
> [!NOTE]
> By default the the *TVHeadend Hostname or IP Address* section is configured by default with the hostname *localhost*, it is preferable to use the IP address *127.0.0.1* instead of *localhost*. [Reference](https://emby.media/community/index.php?/topic/55768-tv-headend-plugin-where-does-it-store-data/#entry542181)
3. Configure the channels for viewing in Jellyfin: even if Jellyfin manages to connect to TVHeadend, the guide will not be synchronized because there has to be a number assigned to the channels in TVHeadend. [Reference](https://emby.media/community/index.php?/topic/64583-no-channels-with-tvheadend-plugin/#entry642268)
* Manual mode
* Go to Configuration > Channel/EPG > Channels
* Select the channel to be changed and press Edit
* In the option *Number* we enter the number that we are going to assign to the channel (for example: 1), this number must be nonzero
* Press save
* Automatic mode
* Go to Configuration > DVB Inputs > Networks
* Select the network you want and press Edit
* In the option *Channel numbers from* we enter the number so we want the numbering of the channels to start (for example: 1), this number must be nonzero
* Press save
4. Update the data from the TVHeadend guide to Jellyfin
* Go to Dashboard > Live TV
* Refresh guide data
<!-- markdownlint-enable MD029 ol-prefix -->
> [!NOTE]
> If the guide is not updated, restart the Jellyfin server.
Once the update of the guide is finished, the Live TV will already be able to see the guide related to the synchronized channels and will be able to visualize the content.

View File

@ -0,0 +1,28 @@
---
uid: server-quick-connect
title: Quick Connect
---
# Quick Connect
Starting with Jellyfin server version 10.7.0 and supported clients, you can use Quick Connect to sign in to your account without the need of a password. You need to previously be logged into a supported client, like the default Jellyfin Web Client.
## Enabling Quick Connect
To use Quick Connect, the Jellyfin server admin has to enable this feature in the server dashboard.
Settings > Dashboard > General > Enable Quick Connect on this server
## Using Quick Connect
To sign in to a supported client, you have to enter the Quick Connect code in your user settings.
Settings > Quick Connect
![image](https://user-images.githubusercontent.com/12074633/115973526-aecc6000-a523-11eb-9ed6-59bee41bac7b.png)
If the code is validated successfully, your new device will be signed in without entering your Jellyfin username or password on the new device.
The client will generate a 6 digit code, which you have to enter in the already signed in client in your user settings.
![image](https://user-images.githubusercontent.com/12074633/115973542-c99ed480-a523-11eb-9d61-17ccd628e123.png)

View File

@ -0,0 +1,20 @@
---
uid: server-settings
title: Settings
---
# Settings
The general settings include options that don't require their own link in the sidebar. Most of these are items that will change the interface or user experience.
## Server Name
This name will be displayed to users when they select a server, and clients might use it in other locations as well. The default value will be the hostname of the computer.
## Login Disclaimer
This message will be shown to users when they login on your server.
## Custom Style
You can add custom CSS rules for minor changes to the web interface that don't require their own theme.

View File

@ -0,0 +1,42 @@
---
uid: server-storage
title: Storage
---
## Storage
Jellyfin is designed to directly read media from the filesystem. This means to pass a network storage device that is using samba or NFS must be directly mounted to the OS. The Jellyfin database also should be stored locally and not on a network storage device.
### NFS
In case you encounter performance issues where files take a long time to start playing while using NFSv3, you might be running in a issue with .NET locking without NFSv3 having locking enabled.
To solve this you have the following options:
- Disable .NET locking using DOTNET_SYSTEM_IO_DISABLEFILELOCKING (introduced in .NET 6).
- Disable locking for the mount using the nolock option.
- Enable the lock service.
- Use NFSv4 which has built-in lock support.
## Docker or VM's
For storage, a moderate size library database can grow anywhere from 10 to 100 GB. The [transcoding](xref:server-transcoding) folder needs roughly the same size as the original media if it's being transcoded at the same bitrate. A single 50GB Blu-Ray Remux by itself can take up to approximately 60GB or as little as 15GB, depending on the quality selected. If the transcoding folder is held on the same storage as the database, this must be taken into consideration.
## Cloud
A popular choice for cloud storage has been the program [rclone](https://rclone.org/downloads/). It is supported on most Operating Systems. To facilitate combining local and cloud filesystems, rclone can be paired with another program such as [mergerfs](https://github.com/trapexit/mergerfs). For cloud storage, it is recommended to disable image extraction as this requires downloading the entire file to perform this task.
> [!NOTE]
> The image extractor can't be [turned off](https://github.com/jellyfin/jellyfin/issues/2355) in Jellyfin at the moment which is causing [performance issues](https://github.com/jellyfin/jellyfin/issues/2600).
- animostiy22's [repo](https://github.com/animosity22/homescripts) about rclone and mergerfs.
- animosity22's [rclone config](https://github.com/animosity22/homescripts/blob/master/systemd/rclone.service).
### MergerFS
MergerFS isn't meant for everything, [see here](https://github.com/trapexit/mergerfs#what-should-mergerfs-not-be-used-for) for more.
- rclone recommended [config](https://forum.rclone.org/t/my-best-rclone-config-mount-for-plex/7441).
- animosity22's [mergerfs config](https://github.com/animosity22/homescripts/blob/master/systemd/gmedia.service).
To modify and examine your mergerfs mount, here's a quick [guide](https://zackreed.me/mergerfs-neat-tricks).

View File

@ -0,0 +1,12 @@
---
uid: server-tasks
title: Tasks
---
# Tasks
Tasks include any operations that are either too time consuming to always run within a library scan or not directly related to scanning media. One such example of a task is the option to clean out old log files. They can either be run on demand by clicking the run button on the right of a task or at specific times by creating a trigger.
The triggers can be set daily or weekly to run at a set time or on a specific interval if the former two are insufficient. There is also an option to simply run the task every time the server starts running. You can add more than one trigger depending on how often you want to run the task.
Plugins can add their own tasks if they include operations that need to be run at specified intervals. These will also show up in the settings for you to configure.

View File

@ -0,0 +1,28 @@
---
uid: server-transcoding
title: Transcoding
---
# Transcoding
These settings will relate to backend options that modify how the server transcodes media. Some improve or change the media quality while others reduce the resources required to transcode the media from its original format.
## Hardware Acceleration
If your hardware supports this you can enable [hardware acceleration](xref:admin-hardware-acceleration) for much faster transcoding. Some of the supported methods are listed below.
* VAAPI
* NVENC
## Thread Count
This option will manually set the amount of threads to use when transcoding. If you're not using the server for anything else it's best to leave this option alone.
## Types of Transcoding
There are three types of transcoding. The type being used will be listed in the dashboard when playing a file. They are ordered below from lowest to highest load on the server:
* Direct Play: Delivers the file with no modifications. Almost no additional load on the server.
* Remux: Changes the container but leaves both audio and video streams untouched.
* Direct Stream: Transcodes audio but leaves original video untouched.
* Transcode: Transcodes the video stream.

View File

@ -0,0 +1,136 @@
---
uid: server-users-managing
title: Managing Users
---
# Managing Users
User management can be done under `Users` in the `Dashboard`. Here you can see your current users or add new ones. And manage your users' settings.
## Adding a User
To add a new user, click the `+` symbol at the top of the page. This will open a new page where you can enter the user's name as it will be either displayed on, or has to be typed into login screen. By default, this will be displayed, but this can be changed at any point by modifying the user, explained further down.
### Manage User Library Access
By default the `enables access to all libraries` option will be enabled, disabling this option will enable you to give the user access rights per library, libraries can consist of several folders. When adding new libraries any user that did not have access to `all libraries` will not receive the rights to open the new library, but this can be changed at any point by modifying the user, explained further down.
## Manage a User
To manage a user either click on their portrait to go straight to their `Profile` tab, or click the `...` symbol inside that user's portrait. The later will open a small submenu with the options `Open` `Library access` `Parental control`, and `delete`. Except for delete, which does the obvious, these options will lead to different tabs but are otherwise all on the same page. `Open` corresponds to the Profile tab, `Library access` to access, `Parental control` to Parental Control, and there is an additional fourth tab `Password` for Password control. Changes to any option on any of these tabs need to be saved using `Save` at the bottom of the page.
### Profile
Directly under the tabs you have a link to `Edit this user's profile, image and personal preferences.` Clicking that allows you to change the user's personal settings, any setting here can be changed by both user and admin.
Under `name` you can change the user's name as it will be either displayed on, or has to be typed into login screen.
Under `Authentication Provider` you have the option to change the backend that handles the login, by default the only option here will be `default` which means Jellyfin will handle this user, this option is sufficient for most use cases. Currently, the only other possibility is to have a LDAP server handle the login by installing the LDAP-Auth plugin. Note that if you wish to change a user's provider to LDAP after creating it in Jellyfin the username needs to be identical to the user's UID in LDAP, including capitalization.
`Allow remote connections to this Jellyfin Server.` Unchecking this option will block login attempts this user makes from outside the networks defined as local, by default this will only be the subnet assigned to your network. But more can be added.
#### Feature Access
For the following options it should be noted that if you never set up Live TV, users are blocked regardless of the state. See [the docs page for `Live TV` » `Live TV`](xref:server-live-tv-index) for more information.
`Allow Live TV access` Unchecking this option will block the user's access to watch Live TV.
`Allow Live TV recording management` Unchecking this option will block the user's access to set recording schedules.
#### Media Playback
`Allow media playback` Unchecking this option will block the user's access to media libraries, this does not include Live TV.
> [!NOTE]
> More information about transcoding can be found [here](xref:server-transcoding).
`Allow audio/video playback that requires transcoding` Unchecking this option will block the user's access to video playback that requires transcoding.
`Allow video playback that requires conversion without re-encoding` Unchecking this option will block the user's access to video playback that requires conversion without re-encoding.
`Internet streaming bitrate limit (Mbps)` Under this option you can set an per stream bitrate limit for all out of network devices.
#### Allow Media Deletion From
These checkboxes allow a user to remove media for either `All libraries`, or per Library. Be careful when enabling these as some plugins enable automatic removal of media after watching.
#### Remote Control
These allow a user to control other devices that are currently logged into Jellyfin, for example if you run a separate client on a HTPC without remote control.
`Allow remote control of other users` Allows this user to control what other users are playing and send messages, but does not give them administrative rights.
`Allow remote control of shared devices` Allows this user to control unclaimed DLNA devices, and devices they are logged in to at the moment.
#### Download & Sync
These allow a user to download media. Syncing and Transcoding are currently not available.
#### Additional options
`Allow media conversion` This option is currently not available.
`Allow social media sharing` Allows this user to share the url to web pages containing media information, for example when viewing information about a movie, series, season, or episode.
`Disable this user` Blocks the user from logging in, existing connections will be abruptly terminated.
`Hide this user from login screens` Useful for private or hidden administrator accounts. The user will need to sign in manually by entering their username and password. All newly created users are hidden by default.
#### Locking and Unlocking users
Locking
`Failed login attempts before user is locked out` Determines how many incorrect login attempts can be made before lockout occurs, disabling the user. 0 means inheriting the default of 3 for non-admin and 5 for admin, -1 disables lockout
When a user is locked out after the set amout of attempts the admin has determined for that account, the user will recieve the following message when trying to login to the Jellyfin instance:
```sh
Connection Failure
We\'re unable to connect to the selected server right now. Please ensure it is running and try again.
```
Unlocking
The unlocking of a user is a manual process for the Jellyfin administrator. When a user is locked out a message of the lockout appears on the activity feed on the administrator dashboard. To unlock the user, the administrator needs to navigate to the profile of the locked out user. When on the profile of the locked out user, the following message should appear:
```sh
This user is currently disabled
See below to reenable
```
To reenable the user the administrator must navigate to the `Disable this user` option in the Additional options section uncheck the checkmark and hit `Save`. The disabled user should be able to login again.
### Library Access
These options allow you to restrict access to libraries, or from devices.
`Enable access to all libraries` By default the `Enable access to all libraries` option will be enabled, disabling this option will enable you to give the user access rights per library, libraries can consist of several folders. When adding new libraries any user that did not have access to `all libraries` will not receive the rights to open the new library.
`Enable access from all devices` By default the `Enable access from all devices` option will be enabled, disabling this option will enable you to give the user access rights per device and logins from new devices are blocked until they've been approved here.
### Parental Control
These options allow you to restrict access to specific content by this user or the timeframe in which they may access. Content that matches these restrictions will be hidden, while the timeframe effectively disables the user.
`Maximum allowed parental rating` Allows you to select the highest rating **allowed to show up** for this user.
`Block items with no or unrecognised rating information` Allows you to always hide items with no or unrecognised rating information.
`Block items with tags` Allows you to always hide items when they contain specific tags, you can add tags to items by editing their metadata.
`Access Schedule` Allows you to set the timeframe(s) where this user is allowed to login, media can only play during the timeframe and will be stopped past it.
### Password
Allows you to set or change the user's password. Note that users can change their own passwords in their personal settings.
`Reset Password` will allow the user to log in without giving a password.
If the user has a password, additional options are shown.
`Easy Pin Code` The user's easy pin code is used for offline access with supported clients, and can also be used for easy in-network sign in.
`Enable in-network sign in with my easy pin code` If enabled, the user will be able to use their easy pin code to sign in to Jellyfin apps from inside the local network. Their regular password will only be needed outside the local network. If the pin code is left blank, they won't need a password within the local network. By default, the local network will only be the subnet assigned to your network, but more can be added.
> [!NOTE]
> [Pin-less Sign in Bug](https://github.com/jellyfin/jellyfin/issues/2125#issuecomment-566400711)

View File

@ -0,0 +1,34 @@
---
uid: server-users-index
title: Users
---
# Users
Many features are configurable for each user individually to allow administrators more granular control over a Jellyfin server. Keep in mind that Jellyfin users are entirely local and no information or metadata will ever be sent to remote servers during the login process.
## Basic Overview
### Administrators
To add another administrator you can simply check the box labeled `allow this user to manage the server` at the top of the user options. This will give someone full access to all pages and features on the site so be careful who gets access.
### Playback
You can allow transcoding for audio and video individually to prevent certain people from using too much system resources. There is also an option to enable video playback that doesn't require encoding. This is much less CPU intensive and will often fix playback issues on devices that don't support newer video formats.
### Deletion
Users can delete media from the library with this option, which will also remove them from the filesystem. If your server doesn't have write permission to the media files they will be removed temporarily but picked up on the next library scan. You can also enable this option for individual libraries.
### Locking/Unlocking
You can set a maximum of failed login attempts before a user gets locked out. This means that if a user tries to login but fails an x amount of times. The user will no longer be able to login until the server administrator manually unlocks the account.
### Other
If you disable a user they will be kicked off the server immediately and unable to login until the option is deselected. This is useful if you don't want to expose unused credentials on a public server but might want to keep the account around for a while. You can also hide a user from the login screen and require manual entry of both the username and password. This will prevent users from knowing what accounts have been created on the server when they login.
## Advanced Overview
For more in-depth information on all user settings, see [Managing Users](xref:server-users-managing).

View File

@ -0,0 +1,10 @@
---
uid: style-guides
title: Style Guides
---
# Style Guides
This section documents the code style used for the different languages used by Jellyfin.
If the language you're looking for doesn't have a style guide yet, respect the style of the surrounding code in the files you are editing.

View File

@ -0,0 +1,54 @@
---
uid: style-guides-javascript
title: JavaScript
---
# JavaScript
## Filenames
Filenames must be camel case and may not include underscores (`_`) or dashes (`-`). The filename's extensions must be `.js`.
## File Structure
All files must abide by the following general structure, with JSDoc comments being optional but preferred.
```javascript
/**
* This module documents the structure used by Javascript code in Jellyfin.
*
* @module path/to/this/module
*/
import module from 'dependency';
import { myFunction, myClass } from 'dependency/submodule';
import 'otherDependency';
/**
* Defines a non-exported function, accessible only from this module.
*
* @param {Object} argument - The argument to pass to the function.
* @returns {Int|null} The resulting object from the function.
*/
function privateFunction (argument) {
// Code ommitted
}
export publicFunction (argument) {
// Code ommitted
}
export default { publicFunction }
```
## Miscellaneous
### File Encoding
All files must be encoded in UTF-8 and use LF line endings when committed.
### Non-ASCII Characters
For printable characters, use the actual Unicode character directly in your code.
For non-printable characters, use the hexadecimal or Unicode escape.

63
docs/index.md Normal file
View File

@ -0,0 +1,63 @@
---
uid: home
title: Home
---
# Welcome to the Jellyfin Documentation
<p align="center">
<a href="https://github.com/jellyfin/jellyfin"><img class="badge" alt="GPL 2.0 License" src="https://img.shields.io/github/license/jellyfin/jellyfin.svg"/></a>
<a href="https://github.com/jellyfin/jellyfin/releases"><img class="badge" alt="Current Release" src="https://img.shields.io/github/release/jellyfin/jellyfin.svg"/></a>
<a href="https://translate.jellyfin.org/engage/jellyfin/?utm_source=widget"><img class="badge" alt="Translations" src="https://translate.jellyfin.org/widgets/jellyfin/-/svg-badge.svg"/></a>
<a href="https://cloud.drone.io/jellyfin/jellyfin"><img class="badge" alt="Build Status" src="https://cloud.drone.io/api/badges/jellyfin/jellyfin/status.svg"/></a>
<a href="https://hub.docker.com/r/jellyfin/jellyfin"><img class="badge" alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg"/></a>
<br/>
<a href="https://opencollective.com/jellyfin"><img class="badge" alt="Donate" src="https://img.shields.io/opencollective/all/jellyfin.svg?label=backers"/></a>
<a href="https://matrix.to/#/+jellyfin:matrix.org"><img class="badge" alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"/></a>
<a href="https://www.reddit.com/r/jellyfin/"><img class="badge" alt="Join our Subreddit" src="https://img.shields.io/badge/reddit-r%2Fjellyfin-%23FF5700.svg"/></a>
</p>
Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it. We welcome anyone who is interested in joining us in our quest!
You can find a list of all available clients [here](xref:clients-index). For more information please see our [about page](xref:about) or the [FAQ](xref:faq). If you are looking for help, check out [this page](xref:getting-help) for all the different communication channels we use.
Note: Jellyfin is a fast moving project that is in its early stages, and this documentation as well as the code may change frequently. Please check back often and don't hesitate to contact us via our Matrix channels or the subreddit!
## Getting Started
Want to get starting using Jellyfin right now? Check out the pages below for how to [install Jellyfin](xref:admin-installing) on your machine.
* [Arch](xref:admin-installing#arch-linux)
* [Debian](xref:admin-installing#debian)
* [Ubuntu](xref:admin-installing#ubuntu)
* [Fedora](xref:admin-installing#fedora)
* [CentOS](xref:admin-installing#centos)
* [Docker](xref:admin-installing#docker)
* [unRaid](xref:admin-installing#unraid-docker)
* [Kubernetes](xref:admin-installing#kubernetes)
* [Windows](xref:admin-installing#windows-x86x64)
* [MacOS](xref:admin-installing#macos)
* [Generic Linux](xref:admin-installing#linux-generic-amd64)
* [Portable DLL](xref:admin-installing#portable-dll)
Alternatively, Jellyfin may be built directly from the [source code](xref:admin-building).
## Administrator Documentation
Want to know more about administering a Jellyfin server? Check out these pages!
* [Quick-Start Guide](xref:quick-start): What to do after you've installed Jellyfin to get it up and running.
* [Migrating](xref:admin-migrate): How to migrate Jellyfin.
* [Plugins](xref:server-plugins-index): How to install and manage plugins.
* [Networking](xref:network-index): Networking settings and troubleshooting.
* [Monitoring](xref:monitoring): Integration with external monitoring software.
* [Hardware Acceleration](xref:admin-hardware-acceleration): Improve transcoding performance on supported hardware.
## Contributing to Jellyfin
Want to help out? Check out the pages below for how to contribute.
* [Contribution Guide](xref:contrib-index): General information on contributing to Jellyfin.
* [Plugin Guide](https://github.com/jellyfin/jellyfin-plugin-template): Documentation and resources to get started writing a plugin to extend Jellyfin functionality.
* [Reporting Bugs](xref:contrib-issues#reporting-bugs): How to use our issue tracker on GitHub to report bugs.
* [Requesting Features](xref:contrib-issues#requesting-features): How to use our issue tracker on GitHub to request new features or enhancements.

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB