Merge branch 'master' into patch-1

This commit is contained in:
felix920506
2026-06-10 17:47:33 +08:00
committed by GitHub
269 changed files with 15739 additions and 8719 deletions
+24
View File
@@ -0,0 +1,24 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:4-22-bookworm",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3000]
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
-20
View File
@@ -1,20 +0,0 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-34
View File
@@ -1,34 +0,0 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended"
],
"globals": {
"JSX": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "jsx-a11y"],
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
},
"settings": {
"react": {
"version": "detect"
}
}
}
+2
View File
@@ -1,5 +1,7 @@
.github/ @jellyfin/core
blog/ @jellyfin/core
src/data/ @jellyfin/core
docs/general/contributing/direct-donations.mdx @jellyfin/core
docs/general/about.md @jellyfin/core
docs/general/community-standards.md @joshuaboniface
docs/general/contributing/ @jellyfin/core
+24
View File
@@ -0,0 +1,24 @@
<!--
Thank you for contributing to our documentation. We receive a lot of pull requests here, so we want to streamline this process.
-->
**Changes**
<!-- Describe a little about what you've changed and why. -->
**Copyediting**
To avoid "nitpicky" reviews, please ensure all of the following have been done for any non-trivial changes.
- [ ] I have run this PR [through a spellchecker](https://jellyfin.org/docs/general/contributing/documentation#please-self-review) (e.g. `aspell`).
- [ ] I have re-read my PR at least twice and fixed any obvious mistakes I see.
- [ ] I have received [out-of-band peer copyediting](https://jellyfin.org/docs/general/contributing/documentation#peer-copyediting) from someone in [#jellyfin-documentation](https://matrix.to/#/#jellyfin-documentation:matrix.org).
While you're waiting for someone to look at your pull request, How about looking at another one? You do not have to do this, but it will help ensure your PR is reviewed quickly in turn.
- [ ] I have provided [a *substantive* review of another documentation PR](https://jellyfin.org/docs/general/contributing/documentation#peer-reviews).
**Issues**
<!-- If applicable, please list any open issues that this PR addresses -->
<!-- e.g. -->
<!-- - closes #1234 -->
+10 -3
View File
@@ -1,11 +1,18 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>jellyfin/.github//renovate-presets/nodejs", ":semanticCommitsDisabled"],
"extends": [
"github>jellyfin/.github//renovate-presets/nodejs",
":semanticCommitsDisabled"
],
"packageRules": [
{
"description": "Disable major updates for React",
"matchPackagePrefixes": ["react"],
"matchPackageNames": ["@types/react", "@types/react-helmet", "@types/react-router-dom"],
"matchPackageNames": [
"@types/react",
"@types/react-helmet",
"@types/react-router-dom",
"react{/,}**"
],
"matchUpdateTypes": "major",
"enabled": false
}
+7 -103
View File
@@ -5,125 +5,29 @@ concurrency:
cancel-in-progress: true
on:
pull_request_target:
branches: [master]
pull_request:
push:
branches: [master]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
name: Build
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: npm
node-version: 20
- uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
node-version-file: .nvmrc
- name: Run build
run: |
npm ci --no-audit
npm run build
- name: Upload artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: jellyfin-org__build
path: build
- name: Upload pages artifact
if: github.event_name == 'push'
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
with:
path: build
deploy:
if: github.event_name == 'push'
name: Deploy to GitHub Pages
concurrency: build-deploy-pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
publish:
if: github.event_name != 'push' && github.repository == 'jellyfin/jellyfin.org'
name: Deploy to Cloudflare Pages
runs-on: ubuntu-latest
needs: build
steps:
- name: Add comment
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
if: github.event_name == 'pull_request_target'
with:
github-token: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | 🔄 Deploying... |
| **Preview URL** | Not available |
| **Type** | 🔀 Preview |
pr-number: ${{ github.event.pull_request.number }}
comment-tag: CFPages-deployment
mode: recreate
- name: Download workflow artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: jellyfin-org__build
path: build
- name: Publish to Cloudflare
id: cf
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3.14.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy build --project-name=jellyfin-org --branch=${{
(github.event_name != 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository)
&& (github.event.pull_request.head.ref || github.ref_name)
|| format('{0}/{1}', github.event.pull_request.head.repo.full_name, github.event.pull_request.head.ref)
}} --commit-hash=${{ github.event.pull_request.head.sha || github.sha }}
- name: Update status comment (Success)
if: ${{ github.event_name == 'pull_request_target' && success() }}
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
github-token: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | ✅ Deployed! |
| **Preview URL** | ${{ steps.cf.outputs.deployment-url != '' && steps.cf.outputs.deployment-url || 'Not available' }} |
| **Type** | 🔀 Preview |
pr-number: ${{ github.event.pull_request.number }}
comment-tag: CFPages-deployment
mode: recreate
- name: Update status comment (Failure)
if: ${{ github.event_name == 'pull_request_target' && failure() }}
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
github-token: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | ❌ Failure. Check workflow logs for details |
| **Preview URL** | Not available |
| **Type** | 🔀 Preview |
pr-number: ${{ github.event.pull_request.number }}
comment-tag: CFPages-deployment
mode: recreate
+148
View File
@@ -0,0 +1,148 @@
name: deploy
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
cancel-in-progress: true
on:
workflow_run:
workflows:
- build
types:
- completed
jobs:
metadata:
name: Metadata
if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository == 'jellyfin/jellyfin.org' }}
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.pr_number.outputs.pr_number }}
steps:
- name: Get Pull Request Number
id: pr_number
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
API_RESPONSE=$(gh pr list --repo "${GITHUB_REPOSITORY}" --search "${HEAD_SHA}" --state open --json number)
PR_NUMBER=$(echo "${API_RESPONSE}" | jq -r '.[0].number // ""')
echo "repository: ${GITHUB_REPOSITORY}"
echo "sha: ${HEAD_SHA}"
echo "response: ${API_RESPONSE}"
echo "pr: ${PR_NUMBER}"
echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'master' && github.repository == 'jellyfin/jellyfin.org' }}
name: Deploy to GitHub Pages
permissions:
actions: read
pages: write
id-token: write
concurrency: build-deploy-pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Configure Pages
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
- name: Download workflow artifact
env:
GH_TOKEN: ${{ github.token }}
run: |
gh run download "${{ github.event.workflow_run.id }}" \
--repo "${GITHUB_REPOSITORY}" \
-n "jellyfin-org__build" \
-D build
- name: Create pages artifact
run: |
tar --dereference --hard-dereference \
--directory build \
-cvf "$RUNNER_TEMP/artifact.tar" \
--exclude=.git --exclude=.github .
- name: Upload pages artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: github-pages
path: ${{ runner.temp }}/artifact.tar
retention-days: 1
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
preview:
needs: [metadata]
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch != 'master' }}
name: Deploy to Cloudflare Pages
permissions:
actions: read
runs-on: ubuntu-latest
steps:
- name: Set PR metadata
id: pr
run: |
echo "number=${{ needs.metadata.outputs.pr_number }}" >> $GITHUB_OUTPUT
echo "sha=${{ github.event.workflow_run.head_sha }}" >> $GITHUB_OUTPUT
- name: Download workflow artifact
env:
GH_TOKEN: ${{ github.token }}
run: |
gh run download "${{ github.event.workflow_run.id }}" \
--repo "${GITHUB_REPOSITORY}" \
-n "jellyfin-org__build" \
-D build
- name: Add comment
if: ${{ needs.metadata.outputs.pr_number != '' }}
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
github-token: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ steps.pr.outputs.sha }}</code> |
|-------------------|:-:|
| **Status** | 🔄 Deploying... |
| **Preview URL** | Not available |
| **Type** | 🔀 Preview |
pr-number: ${{ steps.pr.outputs.number }}
comment-tag: CFPages-deployment
mode: recreate
- name: Publish to Cloudflare
id: cf
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: >
pages deploy build
--project-name=jellyfin-org
--branch=${{ github.event.workflow_run.head_repository.full_name }}/${{ github.event.workflow_run.head_branch }}
--commit-hash=${{ steps.pr.outputs.sha }}
- name: Update status comment
if: ${{ needs.metadata.outputs.pr_number != '' }}
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
with:
github-token: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ steps.pr.outputs.sha }}</code> |
|-------------------|:-:|
| **Status** | ${{ job.status == 'success' && '✅ Deployed!' || '❌ Failed!' }} |
| **Preview URL** | ${{ steps.cf.outputs.deployment-url || 'Not available' }} |
| **Type** | 🔀 Preview |
pr-number: ${{ steps.pr.outputs.number }}
comment-tag: CFPages-deployment
mode: recreate
+30 -8
View File
@@ -2,7 +2,6 @@ name: lint
on:
pull_request:
branches: [master]
push:
branches: [master]
@@ -13,13 +12,12 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node.js
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20
check-latest: true
node-version-file: .nvmrc
cache: npm
- name: Install Node.js dependencies
@@ -28,13 +26,37 @@ jobs:
- name: Run eslint
run: npm run lint
lint:
markdownlint:
name: Lint Markdown
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up problem matcher
uses: xt0rted/markdownlint-problem-matcher@1a5fabfb577370cfdf5af944d418e4be3ea06f27 # v3.0.0
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: .nvmrc
cache: npm
- name: Install Node.js dependencies
run: npm ci --no-audit
- name: Run markdownlint
run: npx --package markdownlint-cli markdownlint '**/*.md' --ignore node_modules
run: npm run lint:markdown
cspell:
name: Check spelling
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run cspell
uses: streetsidesoftware/cspell-action@de2a73e963e7443969755b648a1008f77033c5b2 # v8.4.0
with:
config: ./cspell.json
+3 -5
View File
@@ -2,7 +2,6 @@ name: test
on:
pull_request:
branches: [master]
push:
branches: [master]
@@ -21,13 +20,12 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node.js
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 20
check-latest: true
node-version-file: .nvmrc
cache: npm
- name: Build and start test server
+3
View File
@@ -17,3 +17,6 @@ MD026:
# MD028/no-blanks-blockquote
MD028: false
# MD060/table-column-style
MD060: false
+1
View File
@@ -0,0 +1 @@
26
+2
View File
@@ -15,6 +15,8 @@
.env.test.local
.env.production.local
CODEOWNERS
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+6 -1
View File
@@ -1,3 +1,8 @@
{
"recommendations": ["esbenp.prettier-vscode", "davidanson.vscode-markdownlint", "unifiedjs.vscode-mdx"]
"recommendations": [
"esbenp.prettier-vscode",
"davidanson.vscode-markdownlint",
"unifiedjs.vscode-mdx",
"streetsidesoftware.code-spell-checker"
]
}
+9 -1
View File
@@ -16,7 +16,7 @@ This project includes a combination of content from:
- [jellyfin-blog](https://github.com/jellyfin/jellyfin-blog) &mdash; The current source for the main website and blog content built using Hugo.
- [jellyfin-docs](https://github.com/jellyfin/jellyfin-docs) &mdash; The current source for the documentation content built using DocFX.
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
## Installation
@@ -26,10 +26,18 @@ npm install
## Local Development
To run locally, please use:
```console
npm start
```
To run within a dev container we have to instruct the built-in host check to bind against all addresses:
```console
npm run start -- --host 0.0.0.0
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
+2
View File
@@ -36,4 +36,6 @@ Full release notes available on [GitHub](https://github.com/jellyfin/jellyfin-ko
If you have the Jellyfin for Kodi addon repository installed and updates enabled, this version will automatically be installed for you.
<!-- markdownlint-disable MD059 -->
If you have installed the addon manually, the new zip file is available [here](https://repo.jellyfin.org/releases/client/kodi/plugin.video.jellyfin/plugin.video.jellyfin-0.5.0.zip).
+6 -4
View File
@@ -1,11 +1,13 @@
---
title: "Packaging Updates for 10.6.0"
description: "Some backend packaging changes are here: what you should know"
title: 'Packaging Updates for 10.6.0'
description: 'Some backend packaging changes are here: what you should know'
authors: joshuaboniface
date: 2020-06-21
slug: packaging-updates
---
<!-- markdownlint-disable MD001 -->
Packaging and building binaries for releases and testing has long been an issue for us. From fighting with duct-tape-and-coat-hanger scripts, to testing breaking changes, to massaging official releases, how we were doing things for the last year-and-a-half needed some improvements.
Luckily, today they are all completed. In this post, I'll detail the changes as well as what the entail for our users.
@@ -24,7 +26,7 @@ The main difference is the naming - the `jellyfin-web` repository binaries are n
### Azure Pipelines builds
Our previous build infrastructure consisted of a veritable spaghetti factory of Bash, Python, and Docker scripts that were executed on our build server, a DigitalOcean droplet. For the most part, it worked, but the process was very fragile, opaque (I'm not even sure *I* understand how it all worked all the time, and I wrote it all!), and resource-intensive.
Our previous build infrastructure consisted of a veritable spaghetti factory of Bash, Python, and Docker scripts that were executed on our build server, a DigitalOcean droplet. For the most part, it worked, but the process was very fragile, opaque (I'm not even sure _I_ understand how it all worked all the time, and I wrote it all!), and resource-intensive.
As we've moved more and more functions to Azure for testing, verification, linting, etc. in the various repositories, it became obvious that Azure Pipelines had a lot of flexibility, and would be able to perform nearly all of our build steps for us. This eliminated at least 2/3 of the build server, and gives us another cool option - unstable builds, which I'll touch on shortly.
@@ -48,7 +50,7 @@ For the remaining platforms, including the archive packages for Windows, MacOS,
One of the cool things that this new setup enables is "unstable" builds. For quite a while now, we've been providing (when not broken) "nightly" builds, which as their name implies are build every night if there were merged PRs from the previous day. However, these had a number of drawbacks. First, they broke a lot; second, on a busy day it would be possible for there to be up to a dozen separate PRs that made up the nightly changeset; third, they could often be totally messed up in terms of contents, for instance if the unsplit build grabbed the wrong version of Web.
The new split builds, Azure builds, and metapackages/metaimages instead let us do something far superior: build "unstable" releases for *every merged PR*. We don't have to worry about resource usage (Azure provides this), disk space, or other aspects of the build process. We can know immediately if something breaks. And most importantly, it lets anyone test our master branch in a very clear way, knowing *exactly* what version of the repository you are using and what the last merged PR was if something goes wrong.
The new split builds, Azure builds, and metapackages/metaimages instead let us do something far superior: build "unstable" releases for _every merged PR_. We don't have to worry about resource usage (Azure provides this), disk space, or other aspects of the build process. We can know immediately if something breaks. And most importantly, it lets anyone test our master branch in a very clear way, knowing _exactly_ what version of the repository you are using and what the last merged PR was if something goes wrong.
Unstable builds are versioned based on the Azure build ID, which is in the format "[date].[id]", for example "20200620.12" for the 12th build on June 20th 2020. Thus this version string will tell you exactly which Azure build generated the binary, and thus which PR in which repository triggered it. For those binaries with changelogs (`.deb` and `.rpm` packages only for now), the changelog data includes the PR ID explicitly as well.
+2
View File
@@ -6,6 +6,8 @@ date: 2020-10-05
slug: android-next
---
<!-- markdownlint-disable MD001 -->
This will be a net benefit for users and developers alike!
<!-- truncate -->
@@ -44,7 +44,7 @@ The downside of this is, though, that we might not be able to cleanly implement
1. This blog post starts the process to provide the warning to all unstable users that this is coming. Note that as of posting, unstable builds are disabled due to the recent 10.10.0 release, and will remain off for a little while.
2. About 1-2 weeks after this blog post, we will merge the Library EFCore migration into our `master` branch and begin preliminary testing. If you want to help here, you will have to [build Jellyfin from source](/docs/general/installation/source), and the more people who can help here the better!
2. About 1-2 weeks after this blog post, we will merge the Library EFCore migration into our `master` branch and begin preliminary testing. If you want to help here, you will have to [build Jellyfin from source](/docs/general/installation/advanced/source), and the more people who can help here the better!
3. About 2 weeks after merging, assuming everything looks generally OK, we will **re-enable unstable builds for the general public**. At this point, all unstable builds will apply the initial migrations on startup. That will bring us to about 4 weeks (give or take a week) from the 10.10.0 release.
@@ -60,4 +60,4 @@ Third, **ensure you disable automatic upgrades**. We generally recommend this an
Fourth, **if you run into trouble, please ensure you report the bug with a title containing `[EFCore Library]`**. This will help us find and fix the bugs.
Fifth and finally, **if you have a failing migration, restore an older database version first and try to re-run it**. If it still fails, try your oldest (ideally, 10.9.11 or 10.10.0 stable) backup as well. If *that* one doesn't work, it's a new bug to report.
Fifth and finally, **if you have a failing migration, restore an older database version first and try to re-run it**. If it still fails, try your oldest (ideally, 10.9.11 or 10.10.0 stable) backup as well. If _that_ one doesn't work, it's a new bug to report.
+91
View File
@@ -0,0 +1,91 @@
---
title: Jellyfin for iOS 1.6.0
authors:
- thornbill
slug: ios-v1.6.0
tags: [release, ios]
---
Jellyfin for iOS is back with the first release in nearly 3 years!
{/* truncate */}
Version 1.6.0 of the Jellyfin app for iOS marks a new milestone for the development of the app. A complete list of changes, including their
respective pull requests, can be found on [GitHub](https://github.com/jellyfin/jellyfin-expo/releases/tag/v1.6.0). An update on the
development of the app, a summary of included changes, and some future plans can be found below.
### Renewed development with more frequent releases
I'm sure a lot of people are curious why it has been so long since the last app release. There are a few reasons for this. First, we have
not released any breaking changes to Jellyfin that required an app update. Perhaps most significantly the toolkit we use to build the app
made some changes that essentially prevented my continued development of the app without access to a modern Mac. However, thanks to the
generosity of contributors to [Jellyfin's open collective](https://opencollective.com/jellyfin), I was able to expense the majority of the
cost to purchase a new Mac Mini for development. Finally, the build system provided by the toolkit we were using had been discontinued. We
have now replaced that build system with a fully automated GitHub Action workflow that builds and publishes the app to
[TestFlight](https://testflight.apple.com/join/jJP75akQ) on demand.
### Longstanding bugs squashed
This release features fixes for the following longstanding bugs:
- Improved video player UI by allowing the video to cover the entire screen and hiding the home screen indicator.
- Removed an incorrect check for (e)ac3 audio support.
- Fixed an issue that caused the app to display a blank screen sometimes when left open in the background.
- Added user device name entitlement so the app can report the correct device name on iOS 16+.
- Excluded unused features from the build so the app no longer requests access to permissions it doesn't need (like fitness data).
### What is next?
While the primary focus of the next couple releases will be to do some dependency maintenance and updates, you can also expect work to
continue on some exciting new features. Few people are probably aware that I started working on offline support
[3 years ago](https://github.com/jellyfin/jellyfin-expo/pull/366)! Unfortunately it
[wasn't quite ready](https://github.com/jellyfin/jellyfin-expo/issues/372) for this release, but my goal is to make it available as a
general alpha/beta feature later this year. I have some other ideas to address some well-known limitations of the app and a new contributor
has expressed interest in developing some new features also. You can track all new developments on the
[project roadmap](https://github.com/orgs/jellyfin/projects/40/views/4) on GitHub.
### Supported iOS versions
The Jellyfin app currently supports iOS versions as old as iOS 12. Over the next few releases, we will be updating our core dependencies
which will force us to increase our minimum supported version to iOS 15.1. If you are using a device that cannot be updated to a newer
iOS version, you will still be able to use the Jellyfin web interface but future app updates will be unavailable.
## Contributors
Jellyfin is completely developed by volunteers, and couldn't be made without their great skills and dedication. Consider donating if you
appreciate their work. A big shout-out to all contributors that made this release possible:
**Jellyfin Team**
- [@thornbill](https://github.com/thornbill) - Donate via [GitHub sponsors](https://github.com/sponsors/thornbill)
- [@anthonylavado](https://github.com/anthonylavado) - Donate via [GitHub sponsors](https://github.com/sponsors/anthonylavado)
- [@Bond-009](https://github.com/Bond-009) - Donate via [GitHub sponsors](https://github.com/sponsors/Bond-009)
- [@JPKribs](https://github.com/JPKribs)
**Other contributors**
- [@Drew-Daniels](https://github.com/Drew-Daniels)
- [@fidoriel](https://github.com/fidoriel)
- [@Cyberbeni](https://github.com/Cyberbeni)
And finally a big thank you to everyone who contributed translations, reported bugs, provided feedback and participated in beta testing!
### Helping out
If you have experience with React Native development and are interested in contributing yourself, feel free to dive into the
[source code](https://github.com/jellyfin/jellyfin-expo) and open a pull request. Likewise, if you have experience with
JavaScript/TypeScript and React, [jellyfin-web](https://github.com/jellyfin/jellyfin-web) is always looking for additional contributors.
Alternatively, you can help with translating the app into your own language on our
[Weblate](https://translate.jellyfin.org/engage/jellyfin-expo/) instance.
## Downloads
Update your app now to check out all these changes! The AppStore will auto-update your Jellyfin app if you're already using the app. For
new users, you can find the app on the Apple App Store.
<a href='https://apps.apple.com/us/app/jellyfin-mobile/id1480192618'>
<img width='153' alt='Download on the App Store' src='/images/store-icons/app-store.svg' />
</a>
You can also join our [TestFlight](https://testflight.apple.com/join/jJP75akQ) and help test new versions before they're released to the
public.
Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

+144
View File
@@ -0,0 +1,144 @@
---
title: Roku Version 3.0.0
description: You Wanted the Best, You Got the Best!!
authors: 1hitsong
slug: roku-300
tags: [release, roku]
---
You know the feeling when the assignment was to write a 500 word paper, but you have so much to cover that your first draft is 25,000 words?
...what? Just me?
That's exactly how I feel attempting to condense all the new features, bug fixes, refreshed UI components, and improvements found in Jellyfin for Roku 3.0.0 into a single blog post.
But I'll do my best, here goes.
\- 1hitsong
{/* truncate */}
### Trickplay Images
![Screenshot of trickplay images in the Jellyfin Roku channel](./trickplay.jpg)
When seeking through your videos, if you've enabled and generated trickplay images on your server, you will see a small still frame image from the video at that timestamp. This image allows you to easily find the exact time in the video you're looking for.
**Note:** Older Roku devices and lower powered Roku devices (such as Roku TVs) will likely require your trickplay tiles be a 5x5 grid and not the default 10x10 grid. [Click here](https://github.com/jellyfin/jellyfin-roku/issues/14) for more information and detailed instructions.
### Timed Lyrics
![Screenshot of a song playing and displaying lyrics timed with the audio track](./timedLyrics.jpg)
Support for timed lyrics has been added. If you have lrc files with timestamps, the music player will display the lyrics and move the highlight along automatically. Just in time for your next karaoke party!
### Media Segments
![Skip Intro button displayed over TV show introduction](./skipIntro.jpg)
Stop manually skipping intros and outros! Jellyfin on Roku now supports media segments. If you have media segments configured on your server, the video player will recognize the segments and take whatever action you set in the Roku settings. Auto-skip? Display a skip button? Nothing? You have the power to decide.
### Audio Mini Player
![Audio mini player on the bottom of the home screen](./audioMiniPlayer.jpg)
You can now play audio and navigate around the channel. Simply start playing audio and press the back button. The audio mini player will appear at the bottom of your screen and continue playing the audio queue.
To move your cursor into the audio mini player, press the replay button on your remote. You can then select the playback buttons to move back/forward, play/pause, or stop. You can also return to the full audio player screen by selecting the music note icon.
To move the cursor back out of the audio mini player, simply press the replay button again. Your cursor will then move back to the last item you had focused.
**Note:** The audio mini player will only appear if only audio media is in the queue. If any other type of media is in the queue it will not appear and pressing back will simply stop playback.
### My List - Your Own Personal \"Watch Later\" list
![Home screen showing the My List row](./myList.jpg)
Want to mark a video to watch later? Add it to your list. From the detail screen click on the add to My List button or using the new item option menu, move the cursor over an item on the home screen or in a library and press the \* button on your remote and choose add to My List.
There are two easy ways to view your list. On the home screen, scroll down to the My List row, or select the My List item from the my media row.
Currently, only video files are supported by My List.
### Item Option Menu
![Option menu displayed when you have an item focused and press the * button](./itemOptionMenu.jpg)
On Roku you can't right-click on an item to get an option menu, so we made one using the \* button.
With the cursor on an item, press \* on your remote to get the option menu. Depending on the context of the screen you are on, an assortment of functions will be presented to you.
Options such as add to My List, add to playlist, mark as played/unplayed, go to series/season, remove from playlist, and more.
### Audio/Subtitle Track Selection Updates
![Popup dialog showing user selecting subtitles prior to playing a movie](./selectSubtitles.jpg)
A much requested feature, you can now select your subtitle and audio tracks prior to playing a video. Simply click on the options button from the detail screen and make your selections.
### Remote Subtitle Management
![Popup dialog showing user searching for subtitles to download to their server](./remoteSubtitles.jpg)
Ever start watching a movie and realize you need subtitles, but find you don't have any loaded in Jellyfin?
Previously you would either have to just watch without them, or get on your server to download them.
Now you can click the manage subtitles button on the detail screen and search for subtitle files to download and use.
Simply choose your language and press search. A list of found subtitles will display and allow you to choose one to download. The selected subtitle file will download to your server and will be selectable from the subtitle selection functions.
**Note:** The manage subtitles button will only display for users who are allowed to edit subtitles.
### Audiobook Support
![Audio player playing Salem's Lot (Part 2) audiobook](./audioBook.jpg)
Audiobooks are books (though there's [discussion](https://github.com/jellyfin/jellyfin-meta/discussions/87) about changing that in Jellyfin), but not all books are audiobooks. Jellyfin on Roku now has basic audiobook support so you can listen to your collection.
### Force Transcoding Options
![Popup dialog showing Force Transcoding option](./forceTranscoding.jpg)
Sometimes you have media Roku believes it can directplay, but can't. In the past the only method to get it to play was to force low bitrate limits, or other weird hurdles to make it transcode.
Now you can click the options button on the detail screen and force transcoding on this one item.
Or, if you prefer, you can enable the new user setting to force transcoding for all playback. _TRANSCODE ALL THE THINGS!_
### Search Updates
![Search results showing songs and people](./searchUpdates.jpg)
Live TV programs, people, and playlists are now included in search results.
### Refreshed UI on many screens
![Redesigned TV episode screen](./refreshedUI.jpg)
As you navigate around the channel you'll see both major and minor UI changes. Some were necessary to support new features. Some were necessary to remove minor annoyances. ...and some were necessary to stop all of us yelling at our TVs. 😆
There are simply too many amazing things in this release to name them all! To read the full list of changes, please read the full [release notes](https://github.com/jellyfin/jellyfin-roku/releases/tag/3.0.0).
## 👥 Contributors
Jellyfin is developed by volunteer contributors, and we couldn't do without their great skills and dedication.
They don't get paid by any organizations, so consider donating if you appreciate their work.
A big shout-out to all contributors that made this release possible:
**Jellyfin Team**
- [@1hitsong](https://github.com/1hitsong) - Sponsor via [GitHub sponsors](https://github.com/sponsors/1hitsong)
- [@jimdogx](https://github.com/jimdogx)
**Other contributors**
- [@K-Money](https://github.com/K-Money)
- [@Insprill](https://github.com/Insprill)
## 💾 Downloads & Changelog
The complete list of changes for this release, including all merged pull requests, can be found on
[GitHub](https://github.com/jellyfin/jellyfin-roku/releases/tag/3.0.0).
Your installed Jellyfin channel should automatically update once available or you can install Jellyfin
from the [Roku Channel Store](https://channelstore.roku.com/en-ca/details/4d9e526a7d972d4decf98ea6a84000f7:c617f4902629cc0bd1e1411db1775cf3/jellyfin).
Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

+33
View File
@@ -0,0 +1,33 @@
---
title: Jellyfin for Xbox 0.9.0
authors:
- JPVenson
slug: xbox-v0.9.0
tags: [release, xbox, uwp]
---
Better late then never. The Xbox app for Jellyfin now has a new maintainer and its first release in 5 years.
\- JPVenson
{/* truncate */}
The Jellyfin app on Xbox has been unmaintained for quite a while.
While it was on lifesupport for the last couple of years, we were occasionally fixing bugs.
With the last release now 5 years old, and the continued interest in Jellyfin being available on Xbox overall, I decided to take over at least the superficial duties of keeping it operational and releasing when there are new features or bug fixes.
# Xbox 0.9.0 release
This new release has now been approved and is available as a new version on the Microsoft store for up-to-date Xbox consoles.
It contains a number of bug fixes, but the main change is the switch of the web browser engine the Xbox app is using, to a newer and more feature rich Chromium-based browser implementation instead of the old, legacy Edge one.
This allows us to expand support to formats such as HEVC/4K and HDR on supported devices, in future releases after further testing.
# What to expect
I will be actively managing pull requests and try my best with bug reports, though we are still very reliant on your help with new features and bugfixes.
If there are enough features and bug fixes done and merged, you can expect more releases in the future, though I will not give a definitive timeline for that.
\- JPVenson.
Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

+104
View File
@@ -0,0 +1,104 @@
---
title: Jellyfin for iOS 1.7.0
authors:
- thornbill
slug: ios-v1.7.0
tags: [release, ios]
---
Download support is (finally) coming to Jellyfin for iOS!
{/* truncate */}
Jellyfin for iOS version 1.7.0 delivers the long-awaited downloads feature. This update introduces global download support complete with
Files app integration and sharing capabilities. Alongside this major new feature, the release brings additional technical improvements and
expanded localization support. A complete list of changes, including their respective pull requests, can be found on
[GitHub](https://github.com/jellyfin/jellyfin-expo/releases/tag/v1.7.0.8).
### Download support is here!
Direct downloads of all media types are now supported, working similarly to the Jellyfin web client and Android app. The download option
will be presented in the standard UI for users with appropriate server permissions. When selected, an entry will appear in the new
Downloads tab.
From the Downloads tab, users can:
- Open downloaded media in the Files app
- Share directly to other apps (like VLC) for viewing/playing
- Delete downloaded content
<center>
<img
src={require('./downloads.png').default}
alt='Downloads tab with context menu showing downloaded item options'
style={{ maxHeight: '600px' }}
/>
</center>
Additionally, downloaded media can be browsed directly from within the Files app by locating the Jellyfin directory under Downloads.
#### Transcoded downloads
Transcoded downloads have transitioned from an experimental to an alpha setting, allowing for broader community testing of this emerging
capability. This feature enables transcoding of audio and video that cannot be played directly by the iOS media engine. The Jellyfin server
will convert these files to a compatible format, also enabling playback of compatible videos directly within the app.
**Important notes for users:** Server-side support for transcoded downloads is currently very basic. You may encounter various issues, and
the feature should be approached with this in mind. Currently, there are no options to control download quality, and in some cases,
transcoded files may be significantly larger than the original source files. Please report any issues you encounter on
[GitHub](https://github.com/jellyfin/jellyfin-ios/issues).
### Technical improvements
This release features several technical enhancements:
- **State Management Upgrade**: State management within the app has been migrated to [zustand](https://github.com/pmndrs/zustand) from
mobx, resolving a major blocker for upgrading to the latest Expo and React Native versions.
- **TypeScript Migration**: Continued migration to TypeScript improves overall code quality and maintainability.
- **App Naming Consistency**: Updates made to the app name to ensure
[consistent branding](https://github.com/jellyfin/jellyfin-meta/discussions/100).
- **Expanded Localization**: Added support for Afrikaans and Basque languages, thanks to our community translators.
- **Code Optimization**: Removed unused resources from the app.
### Supported iOS versions
**This release of the Jellyfin app will be the last major update to support iOS 12.** The next major release is planned to include an
updated version of React Native, which will require us to increase the minimum supported iOS version to at least 15.1. Users with devices
running older iOS versions will still be able to use the Jellyfin web interface, though future app updates will not be available for these
devices.
## Contributors
Jellyfin is completely developed by volunteers, and could not be made without their great skills and dedication. Consider donating if you
appreciate their work. A big shout-out to all contributors that made this release possible:
**Jellyfin Team**
- [@thornbill](https://github.com/thornbill) - Donate via [GitHub sponsors](https://github.com/sponsors/thornbill) or
[BuyMeACoffee](https://coff.ee/thornbill)
**Other contributors**
- [@enigma0Z](https://github.com/enigma0Z)
And finally a big thank you to everyone who contributed translations, reported bugs, provided feedback and participated in beta testing!
### Helping out
If you have experience with React Native development and are interested in contributing, feel free to dive into the
[source code](https://github.com/jellyfin/jellyfin-ios) and open a pull request. Likewise, if you have experience with
JavaScript/TypeScript and React, [jellyfin-web](https://github.com/jellyfin/jellyfin-web) is always looking for additional contributors.
Alternatively, you can help with translating the app into your own language on our
[Weblate](https://translate.jellyfin.org/projects/jellyfin/jellyfin-expo/) instance.
## Downloads
Update your app now to check out these exciting new features! The AppStore will automatically update your Jellyfin app if you're already
using it. New users can find the app on the Apple App Store.
<a href='https://apps.apple.com/us/app/jellyfin-mobile/id1480192618'>
<img width='153' alt='Download on the App Store' src='/images/store-icons/app-store.svg' />
</a>
You can also join our [TestFlight](https://testflight.apple.com/join/jJP75akQ) and help test new versions before they're released to the
public.
+107
View File
@@ -0,0 +1,107 @@
---
title: SQLite concurrency and why you should care about it
authors:
- JPVenson
slug: SQLite-locking
tags: [SQLite, jellyfin, locked-database]
---
SQLite is a powerful database engine, but due to its design, it has limitations that should not be overlooked.
Jellyfin has used a SQLite-based database for storing most of its data for years, but it has also encountered issues on many systems. In this blog post, I will explain how we address these limitations and how developers using SQLite can apply the same solutions.
This will be a technical blog post intended for developers and everyone wanting to learn about concurrency.
Also Jellyfin's implementation of locking for SQLite should be fairly easy to be implemented into another EF Core application if you are facing the same issue.
\- JPVenson
{/* truncate */}
## The Premise
SQLite is a file-based database engine running within your application and allows you to store data in a relational structure.
Overall it gives your application the means of storing structured data as a single file and without having to depend on another application to do so.
Naturally this also comes at a price. If your application fully manages this file, the assumption must be made that your application is the sole owner of this file, and nobody else will tinker with it while you are writing data to it.
So an application that wants to use SQLite as its database needs to be the only one accessing it.
Having established this fact, an important thought arises: if only a single write operation should be performed on a single file at a time, this rule must also apply to operations within the same application.
## The W-A-L mode
SQLite has a feature that tries to get around this limitation: the Write-Ahead-Log (WAL).
The WAL is a separate file that acts as a journal of operations that should be applied to an SQLite file.
This allows multiple parallel writes to take place and get enqueued into the WAL.
When another part of the application wants to read data, it reads from the actual database, then scans the WAL for modifications and applies them on the fly.
This is not a foolproof solution; there are still scenarios where WAL does not prevent locking conflicts.
## SQLite transactions
A transaction is supposed to ensure two things.
Modifications made within a transaction can be reverted, either when something goes wrong or when the application decides it should and optionally a transaction may also block other readers from reading data that is modified within a transaction.
This is where it gets spicy and we come to the real reason why I am writing this blog post.
For some reason on some systems that run Jellyfin when a transaction takes place the SQLite engine reports the database is locked and instead of waiting for the transaction to be resolved the engine refuses to wait and just crashes.
This seems to be a not uncommon issue and there are many reports to be found on the issue.
The factor that makes this issue so bad is that it does not happen reliably. So far we only have one team member where this can be (somewhat) reliably be reproduced which makes this an even worse a bug.
From the reports this issue happens across all operating systems, drive speeds and with or without virtualization.
So we do not have any deciding factor identified that even contributes to the likelihood of the issue happening.
## The Jellyfin factor
Having established the general theory on how SQLite behaves, we also have to look at the specifics of Jellyfins usage of SQLite.
During normal operations on a recommended setup (Non-Networked Storage and preferably SSD) its unusual for any problems to arise, however the way Jellyfin utilises the SQLite db up to 10.11 is very suboptimal.
In versions prior to 10.11 Jellyfin had a bug in its parallel task limit which resulted in exponential overscheduling of library scan operations which hammered the database engine with thousands of parallel write requests that an SQLite engine is simply not able to handle.
While most SQLite engine implementations have retry behavior, they also have timeouts and checks in place to prevent limitless waiting so if we stress the engine enough, it just fails with an error.
That and very long running and frankly unoptimized transactions could lead to the database just being overloaded with requests and flaking out.
## The solution
Since we moved the codebase over to EF Core proper, we have the tools to actually do something about this as EF Core gives us a structured abstraction level.
EF Core supports a way of hooking into every command execution or transaction by creating [Interceptors](https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/interceptors).
With an interceptor we can finally do the straight forward idea of just "not" writing to the database in parallel in a transparent way to the caller.
The overall idea is to have multiple strategies of locking. Because all levels of synchronization will inevitably come at the cost of performance, we only want to do it when it is really necessary.
So, I decided on three locking strategies:
1. No-Lock
2. Optimistic locking
3. Pessimistic locking
As a default, the no-lock behavior does exactly what the name implies. Nothing. This is the default because my research shows that for 99% all of this is not an issue and every interaction at this level will slow down the whole application.
Both the optimistic and pessimistic behaviors use two interceptors—one for transactions and one for commands—and override `SaveChanges` in `JellyfinDbContext`.
### Optimistic locking behavior
Optimistic locking means to assume the operation in question will succeed and only handle issues afterwards. In essence this can be boiled down to "Try and Retry and Retry ..." for a set number of times until either we succeed with the operation or fail entirely.
This still leaves the possibility that we will not actually be able to perform a write, but the introduced overhead is far less than the Pessimistic locking behavior.
The idea behind how this works is simple: every time two operations try to write to the database, one will always win. The other will fail, wait some time, then retry a few times.
Jellyfin uses the `Polly` library perform the retry behavior and will only retry operations it will find have been locked due to this exact issue.
### Pessimistic locking behavior
Pessimistic locking always locks when a write to SQLite should be performed. Essentially every time an transaction is started or a write operation on the database is done though EF Core, Jellyfin will wait until all other read operations are finished and then block all other operations may they be read or write until the write in question has been performed.
This however means, that Jellyfin can only ever perform a single write to the database, even if it would technically does not need to.
In theory, an application should have no issue reading from table "Alice" while writing to table "Bob" however to eliminate all possible sources of concurrency related locking, Jellyfin will only ever allow a single write performed on its database in this mode.
While this will absolutely result in the most stable operation, it will undoubtedly also be the slowest.
Jellyfin uses a [ReaderWriterLockSlim](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-threading-readerwriterlockslim) to lock the operations, that means we allow an unlimited number of reads to happen concurrently while only one write may ever be done on the database.
### The future Smart locking behavior
In the future we might also consider combining both modes, to get the best of both worlds.
# The result
Initial testing showed that with both modes, we had great success in handling the underlying issue. While we are not yet sure why this happens only on some systems when others work, we at least now have an option for users previously left out of using Jellyfin.
When I was researching this topic, I found many reports all over the internet facing the same error but nobody was able to provide a conclusive explanation whats really happening here.
There have been similar proposals made to handle it but there wasn't a "ready to drop in" solution that handles all the different cases or only code that required massive modifications to every EF Core query.
Jellyfin's implementation of the locking behaviors should be a copy-paste solution for everyone having the same issues as its using interceptors and the caller has no idea of the actual locking behavior.
Best of luck,
\- JPVenson
Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

@@ -0,0 +1,152 @@
---
title: Jellyfin 10.11.0
authors:
- joshuaboniface
slug: jellyfin-release-10.11.0
tags: [release, server]
---
We are pleased to bring you Jellyfin 10.11.0, our new stable release. This is probably one of, if not the, biggest and most impactful releases we've done yet, with some massive backend changes to improve performance and long-term expandability and maintainability. This release has been a long time coming, with over 6 months of development and another 6 months of RC testing, throwing our planned 6-month release schedule completely out of whack, but we definitely think the results are worth it - both for users right now, and for the long-term health of the project.
If you just want a quick summary of what you **need to know** (and you **DO** need to know!) to get your system upgraded and running, please read on to the "TL; DR" section just below, or keep reading for a full explanation of all the major features and improvements in Jellyfin 10.11.0! You can also view full changelogs on the [server](https://github.com/jellyfin/jellyfin/releases/tag/v10.11.0) and [web](https://github.com/jellyfin/jellyfin-web/releases/tag/v10.11.0) GitHub releases.
\- Joshua
{/* truncate */}
## TL; DR
**IT IS VERY IMPORTANT THAT YOU READ THIS SECTION BEFORE UPGRADING TO JELLYFIN 10.11.0!** Failure to do so may cause issues! Always feel free to [ask for help in our chat](/contact) if you are unclear or run into trouble.
1. As always for major upgrades, ensure you **STOP Jellyfin and take a [FULL MANUAL BACKUP OF YOUR DATA AND CONFIG DIRECTORIES](/docs/general/administration/backup-and-restore/#manual-backup) before upgrading**! While the upgrade process _should_ be seamless and has guardrails, we've seen a lot of strange bugs during RC testing and it's better to be safe than sorry.
2. You **MUST** be running Jellyfin 10.10.7 before upgrading to 10.11.0! You **may** be fine with Jellyfin 10.9.11 but this is less-extensively tested. **Upgrading from any other versions is NOT supported and WILL fail**; upgrade to 10.10.7 **first**, then upgrade to 10.11.0.
3. The initial upgrade will include **MULTIPLE LONG-RUNNING MIGRATIONS** that may take up to several hours depending on your library size and state. **DO NOT CANCEL OR INTERRUPT THE SYSTEM** during these migrations; let them run overnight if possible on very large libraries. You can use the new Startup UI and Log Viewer (see below) from your local network to view the progress during the upgrade, and please see the section below for more details on "why".
4. The upgrade will make a backup of your existing `library.db` file named `library.db.old`. This file can be used to recover should the upgrade fail. Once you have successfully upgraded and Jellyfin 10.11.0 is running smoothly, you may delete this backup. If you need to try the migrations again due to a failure, stop Jellyfin, rename this file back to `library.db`, then start Jellyfin again, and the migration will be re-attempted.
5. If you have adjusted the Library Page Size to anything other than the default of 100, we recommend putting it back for performance reasons before upgrading.
6. After upgrading, we strongly recommend running a **full library scan** to ensure that all data is correctly populated. Failure to do so may result in weird bugs if any metadata entries were corrupt or not properly migrated (rare but possible). Additionally, users should also perform a scan for missing metadata on their Music libraries, as this may be necessary for proper music functionality after the upgrade. While it may not be strictly required, performing this additional scan on other libraries is recommended to ensure everything functions correctly.
7. Jellyfin 10.11.0 is **NOT** compatible with 32-bit ARM systems (`armhf`), like 1st and 2nd generation Raspberry Pis or other low-end or old SBCs, or any ARM system running a 32-bit operating system. You **must** be running an ARM64 operating system to run Jellyfin 10.11.0 on ARM systems. See below for more information.
8. This release also fixes several security bugs, both for ourselves and from upstream projects like DotNET. We do recommend upgrading to 10.11.0 **as soon as possible**.
9. As always with major Jellyfin releases, bugs will exist, even after 6 months of RC testing. This is a second reminder to **take a full backup before upgrading**, as this is the only way to downgrade back to a previous version if you find that you need to.
And now on to the cool new features!
## The Library Database conversion to EF Core is complete!
For this one, a bit of backstory is required. For a long time, the backend of Jellyfin has been a mess of spaghetti, as historically pre-Jellyfin very little thought was put into long-term best-practices during development of new features and functionality. This manifested as a codebase completely littered with database calls, written as raw SQLite statements inside of other code, with effectively zero centralization of the database management functionality into an ORM (object-relational model system).
This had three major negative effects: (1) doing any changes to the database schemas required complex, error-prone manual migrations that were bespoke for each change, with little in the way of safeguards or guardrails and no downgrade support; (2) it was very difficult to add new functionality or change existing functionality without rewriting large swaths of unrelated code to take the new changes into account; and (3) it completely locked the system into the file-based SQLite system with no ability to support other database engines.
Enter EF Core, an ORM for .NET and C#, the framework and language Jellyfin is written in, that simplifies and helps manage the database for us, allowing us to remove all this legacy spaghetti and massively simplify the database handling within Jellyfin. It includes things like an automatic migration handler with versioning, standardized interfaces to the database calls, and the flexibility to use other backend database engines in the future.
The initial conversion work was started almost 5 years ago with some of the simpler databases, such as Users and Authentication, but the elephant of the conversion was the Library database: its massive complexity, sprawling reach, and reliance not only on the database but also on static XML files on-disk, meant that it was quite a thing to tackle, and the project stalled out for several years. Cue @JPVenson, who with less than 6 months involved in the project took on this massive project and drove it to completion.
The end result might not seem like much to a normal user: queries do get faster, and future changes should be less error-prone, but mostly this change is transparent. But on the backend and for the continued long-term development of Jellyfin, this is huge. The simplified database access will let us write cleaner, less error-prone code, implement new features, perform complex migrations, and more, much faster and with a minimum of effort, opening up a lot of new opportunities for advancement. We can then finally start tackling the absolutely massive mountain of open feature requests, many of which were nearly impossible before this change. For administrators, it also opens up new possibilities - not officially yet, but soon - for running Jellyfin backed by "real" database systems like PostgreSQL, providing new options for redundancy, load-balancing, and easier maintenance and administration. The future looks very bright!
### Deduplication and Migrations
The core of the migration involves a transfer of all Library data from the legacy `library.db` to the new structures within `jellyfin.db`. While this seems simple on the surface, as part of the conversion process we decided to actively try to improve the schema while we were at it, allowing us to simultaneously clean up a lot of the aforementioned spaghetti code. Thus the migration itself creates proper relational cross-references in the database, including foreign keys, for the first time.
The downside however is that inconsistent and logically corrupt library data is prone to cause problems during the migration, and this has been a source of many issues. The migration must not only restructure the data but fix these logical corruptions and clean up any data that "doesn't make sense" anymore, for example Media items with no parent or duplicated People data for multiple sets of media.
This deduplication and cleanup is very time intensive, and the scale of the cleanup depends heavily on how many logically inconsistent entries are present in the existing database. This essentially means that, the older your database is, and the more logically corrupted entries it has, the more the migration needs to work to clean all of it up, prolonging the migration process. This also makes it very hard to estimate how long the migration can take: a database with 300,000 entries but no issues can migrate in a matter of minutes, while one with just 30 series but severe inconsistencies can take multiple hours.
Thus, when it comes to running the migration, we reiterate letting it run during an off-peak period like overnight, and simply letting it run to completion; if it completes quickly, you're golden, and if not, you will avoid delaying users' access.
### Startup UI and Log Viewer
One nice little feature that grew out of the migration work and the corresponding long-running initial migration was our new Startup UI and Log Viewer. Before this feature, while Jellyfin was starting up and running through e.g. migrations, the system would appear dead - the UI would not load, and it appeared like very little was happening unless you had your log level set to debug. The Startup UI changes this by providing a simple startup WebUI which is only accessible in your configured local networks, and which will display the current status of the startup process and log messages while the system gets ready, giving you more peace of mind about what's going on. For small instances this might not even be visible, but for slow-to-start large instances this can be invaluable for tracking progress and debugging issues.
![Startup UI](startup-ui.png)
### Internal Backup & Restore Support
One of the first big benefits of the new backend is a very eagerly-awaited feature: internal, live Backup and Restore support! You can now take a full snapshot of your metadata database, back it up to external storage, and restore from it in the event of a major fault. You can also take regular backups just in case. This will greatly help both normal day-to-day maintenance, as well as upgrades in the future, always knowing that you have a good copy of the data.
The backup and restore system can only restore systems on which the backup was originally made, so this is not a tool to migrate from other OS's or 3rd party containers.
![Backups](backups.png)
### Aggressive in-memory Database Caching
The new database engine is tuned to aggressively cache metadata in memory, to prevent slow disk reads from bottlenecking the system; this was a frequent problem in previous versions of Jellyfin and a point of regular complaint. In practice, this means that Jellyfin will use more RAM than before, up to the full size of your Library database. This RAM is not wasted however, as the speed-up is very noticeable, especially with large libraries, and the system will try to be as efficient as possible if other tasks require memory. This means that the memory will be given back when other programs need more memory. Be aware of this as you upgrade, as it will look like a lot more resource utilization.
### Improved Locking Behavior
The new database engine also enables several new locking modes; for most users, this is irrelevant, but users with frequent issues related to database locking can now tweak the settings. **More detail about this functionality can be found [in this blog post](/posts/SQLite-locking).**
## Removal of ARM32 (armhf) support
In Jellyfin 10.10.0, we deprecated ARM32 support and have fully removed it from Jellyfin 10.11.0; Jellyfin now requires an ARM64 operating system to run on ARM platforms. In practical terms, this means dropping support for very old or very low-end ARM SBCs (Raspberry Pi 1/2, etc.). We found consistently that these very old SBCs were absolutely terrible at running Jellyfin, even without transcoding, and we decided that dropping support would streamline our release processes and help ensure that users get the best experience out of the box. If you are still running on one of these systems, or on a newer ARM SBC that isn't running a 64-bit operating system, you will need to upgrade your hardware and/or reinstall a 64-bit operating system in order to upgrade to Jellyfin 10.11.0.
## Deprecation of internal TLS/SSL support
We are announcing the deprecation of internal TLS/SSL support in Jellyfin, which we are planning to remove in Jellyfin 10.12.0. The current internal TLS mechanisms are cumbersome and do not integrate well with external systems e.g. Let's Encrypt's `certbot`, which means manual work and manual restarts whenever a certificate needs to be updated. In addition, compiling in TLS support means dependencies on external libraries that complicate our packaged Linux binaries. We have always recommended [running Jellyfin behind a reverse proxy](/docs/general/post-install/networking/reverse-proxy/), all of which provide far better integration for TLS/SSL, so with our next release we will be removing this functionality. For anyone running a production-grade Internet-facing instance using TLS without a reverse proxy, now is the time to get that set up. Even with this removal, we are planning to still provide manual configuration options for the built-in Kestrel TLS system, which would serve as an alternative way to configure TLS, but it will not be exposed through the frontend UX and would be recommended only for very advanced, specific usecases; normal instances should move to reverse proxies.
## Free Space Checks
Jellyfin now actively checks the available free space for its configuration and data directories. If you have less than 2GB of free space in each data directory, Jellyfin now refuses to start to prevent data corruption. Additionally, checks are implemented to prevent certain path misconfigurations that are known to cause issues.
## New Features & Enhancements
We have several new features and enhancements to look forward to:
### User Experience
* Our search performance has been greatly improved, making it much quicker to find what you need.
* The Favorites page will now list Live TV channels, Music Videos, Photo Albums, Photos, and Seasons in addition to the existing media types.
* We now have HEVC decoding support for Firefox 134+. More info is available on the [client support page](/docs/general/clients/codec-support#video-compatibility).
* Native styling of subtitles can be disabled.
* Shows can be displayed grouped in collections when viewing libraries.
* Theme media will now play in random order.
* Guest stars can be assigned roles, e.g., Kelsey Grammer as Captain Morgan Bateson.
* A customizable "splash screen" image can be set as a background on the login page.
* The experimental layout has a redesigned navigation and controls for filtering and sorting libraries.
### Administrator Experience
* The dashboard now displays stats for the number of media items on the server and available storage space.
* Media segment providers can be configured per library similar to other metadata providers.
* AV1 decoding can be enabled for VideoToolbox hardware acceleration.
* M3U tuners can be configured to use the native framerate.
* Branding options are greatly expanded, including "splash screen" image support, extended disclaimer support, and custom CSS; even more is planned for the future to allow administrators to fully customize their user experience to your branding.
* The migration of dashboard pages to our new tech stack is nearly complete with most pages being converted, offering a much simpler and clearer organizational layout.
* When replacing files, Jellyfin will now recognize this and prune related data (chapters, trickplay files and extracted subtitles and attachments) on scan, making sure that these data will be re-generated, matching the new file.
### Transcoding and Media Handling
* We have moved to the new upstream FFmpeg 7.1, which brings many improvements.
* We now support 3D LUT-based HDR tone-mapping on Intel HD/UHD graphics and Rockchip RK3588, improving performance.
* We now support Dolby Vision Profile 5 tone-mapping on Rockchip RK3588.
* We now have more accurate rendering of ASS/SSA subtitles when using hardware transcoding.
* We now support AV1 hardware decoding for Apple VideoToolbox.
* We have improved our dynamic HDR metadata handling, which involves properly detecting HDR10+ videos and selectively removing DoVi or HDR10+ metadata to avoid black screen on devices that only support a single type of dynamic HDR metadata.
## Client Development Changes
The following changes apply to all client application developers. Please review thoroughly and update your applications as required.
### HTTP API
* We've added a new option for developers to test their client with deprecated authorization methods disabled. We're planning to remove old authorization methods in 10.12.0. More details about how to authorize and to test are available in [this document](https://gist.github.com/nielsvanvelzen/ea047d9028f676185832e51ffaf12a6f).
* The `OnPlaybackStart`, `OnPlaybackProgress` and `OnPlaybackStopped` operations are now deprecated. Use the `ReportPlaybackStart`, `ReportPlaybackProgress` and `ReportPlaybackStopped` operations instead, as the former will be removed in a future version.
* A new `GetSystemStorage` operation has been added to retrieve information about the server storage.
* A new `BackupApi` has been added to list, create, and restore backups.
* Lyrics now contain cues to allow timing for individual words.
* Parental ratings have now moved to the new `ratingScore` property which allows for subscores.
* The server may now return `503 Service Unavailable` when a server startup/shutdown/restart is in progress. Clients should expect this code, react to the `Retry-After: sec` header, and retry the operation as needed.
### Plugins
* All database access **must** now be done through EF Core. Raw SQL will no longer be accepted by the server.
* Plugins may now provide custom database access. This is a HIGHLY experimental API and is subject to changes, with a goal of stability in 10.12.0.
* Metadata plugins should use the new interface for external URL providers to supply better naming for external metadata links.
Happy Watching!
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

+133
View File
@@ -0,0 +1,133 @@
---
title: Jellyfin for Android TV 0.19
authors:
- nielsvanvelzen
slug: androidtv-v0.19.0
tags: [release, android-tv]
---
From refreshed user interface elements to playback improvements, there are many changes across the board in the latest update of Jellyfin
for Android TV.
{/* truncate */}
I'm glad to announce a brand new release of Jellyfin for Android TV. This time, we've made progress in many aspects of the app. Some more
visible than others. This blog post will highlight some of the most notable changes. A complete list is available in the
[GitHub changelog](https://github.com/jellyfin/jellyfin-androidtv/releases/tag/v0.19.0).
## 🔍 Search
![Screenshot of the new search with voice input active](./search.png)
The search functionality of the app was redesigned based on the new style of the app. This new look also introduces voice search! And
this is only a first step of many to come. Future updates are planned to add search suggestions, in-library search and a revamp of how
results are shown.
## 📺 Are you still watching?
![Screenshot of the inactivity popup asking if the user is still watching](./stillwatching.png)
By popular request, we now have a new inactivity popup. When enabled in the app preferences it will ask you if you're still watching TV when
no input has been detected for a configurable amount of time or number of episodes. If you don't choose to continue watching the app will
automatically close the video player, preventing entire series from being marked as watched overnight when you fall asleep!
## 📹 Video
A lot of effort was put into improving our video player. While not all our work was ready for this release yet, a lot of it was. We've
made significant improvements in the detection of device HDR capabilities to more accurately transcode or direct play content. For Dolby
Vision content we do require Jellyfin 10.11 and media has to be rescanned for these changes to fully work. Additionally we now support the
VobSub and DVDSub subtitle formats without transcoding.
To both improve our detection algorithms and help troubleshoot playback issues we added a new troubleshoot mechanic. You'll find a new
button in the advanced playback preferences to send a "media capability report" to the server. This report contains information about your
device and its capabilities, together with the "device profile" that is sent to the Jellyfin server to decide whether transcoding or
remuxing is necessary.
## 🎶 Music
![Screenshot of the music player to showcase the new fast forward and rewind buttons](./music.png)
It's now possible to fast forward, rewind or manually seek through your playing music. Various issues with managing the
queue have been fixed, including remote control support.
## 🖼️ Photos
![Screenshot of the new picture viewer](./pictures.png)
The photo viewer got upgrades with a fresh coat of paint. It now shows the file and album name too, making it easier to see what you're
looking at. This also gives a small glimpse of how the video player will look in the future.
## ✨ Jellyfin 10.11
Jellyfin server version 10.11 just released, but don't be alarmed: this app release supports both Jellyfin 10.10 and 10.11, giving you the
time to upgrade at your own pace. Some features, like the HDR improvement, do rely on Jellyfin 10.11, so upgrading is advised for
the best experience.
## 🫳 Android 5 and below
**The 0.19.x releases will be the last ones supporting Android 5 and Android 5.1** due to updated vendor requirements. Based on our limited
statistics, this affects less than 1% of our users. You will be able to keep using Jellyfin, but won't be able to receive future app
updates. We recommend upgrading your device or using an external Android TV set-top box to receive future app updates.
## Made possible by you
Jellyfin is completely developed by volunteers, and couldn't be made without their great skills and dedication. Consider donating if you
appreciate their work. A big shout-out to all contributors that made this release possible:
**Jellyfin Team**
- [@nielsvanvelzen](https://github.com/nielsvanvelzen) - Donate via [GitHub sponsors](https://github.com/sponsors/nielsvanvelzen) or
[Buy Me a Coffee](https://buymeacoffee.com/nielsvanvelzen)
- [@BotBlake](https://github.com/BotBlake)
- [@linkandzelda91](https://github.com/linkandzelda91)
**Other contributors**
- [@tal\-sarid](https://github.com/tal-sarid)
- [@dtrexler](https://github.com/dtrexler)
- [@hdweiss](https://github.com/hdweiss)
- [@kylep09](https://github.com/kylep09)
- [@RubenTeixeira](https://github.com/RubenTeixeira)
- [@clams4shoes](https://github.com/clams4shoes)
- [@owochle](https://github.com/owochle)
- [@ferrarimarco](https://github.com/ferrarimarco)
- [@conihorse](https://github.com/conihorse)
- [@ConnorS1110](https://github.com/ConnorS1110)
- [@vahtos](https://github.com/vahtos)
- [@claireratigan](https://github.com/claireratigan)
- [@cani1see](https://github.com/cani1see)
- [@osiris86](https://github.com/osiris86)
- [@bin101](https://github.com/bin101)
- [@EMohlin7](https://github.com/EMohlin7)
- [@mkst](https://github.com/mkst)
And finally a big thank you to everyone who contributed translations, reported bugs, provided feedback and participated in beta testing!
### Helping out
If you have experience with Android TV development or with Kotlin and are interested in contributing yourself, feel free to dive into the
[source code](https://github.com/jellyfin/jellyfin-androidtv) and open a pull request. Alternatively, you can help with translating the app
into your own language on our [Weblate](https://translate.jellyfin.org/engage/jellyfin-android/) instance.
## Downloads
Update your app now to check out all these changes! The app stores will auto-update your Jellyfin app if you're already using the app. For
new users, you can find the app on the app store of your platform.
<a className='margin-right--md' href='https://play.google.com/store/apps/details?id=org.jellyfin.androidtv'>
<img width='153' alt='Jellyfin for Android TV on Google Play' src='/images/store-icons/google-play.png' />
</a>
<a className='margin-right--md' href='https://www.amazon.com/gp/product/B07TX7Z725'>
<img width='153' alt='Jellyfin for Fire TV at Amazon Appstore' src='/images/store-icons/amazon.png' />
</a>
<a href='https://f-droid.org/en/packages/org.jellyfin.androidtv/'>
<img width='153' alt='Jellyfin for Android TV on F-Droid' src='/images/store-icons/fdroid.png' />
</a>
Direct downloads are available at [repo.jellyfin.org](https://repo.jellyfin.org/releases/client/androidtv/) or in the
[GitHub release](https://github.com/jellyfin/jellyfin-androidtv/releases/latest).
You can also join our [beta program on Google Play](https://play.google.com/apps/testing/org.jellyfin.androidtv) and help test new versions
before they're released to the public. [Read more](../../2021/07-24-android-betas.mdx) about our beta program.
Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

+150
View File
@@ -0,0 +1,150 @@
---
title: State of the Fin 2026-01-06
authors:
- thornbill
slug: state-of-the-fin-2026-01-06
tags: [state-of-the-fin]
---
Happy New Year and welcome to the State of the Fin!
This new blog series will regularly basis highlight the ongoing development of Jellyfin and our official clients.
We aim to keep our community informed and engaged, so feel free to share your feedback or thoughts on our progress!
{/* truncate */}
## Project Updates
### Jellyfin Turns 7
December marked Jellyfin's 7th anniversary!
A lot has changed in 7 years, but we remain steadfast in our commitment to Open Source and to being the best personal media server out there.
Special thanks to our developers, testers, moderators, and supporters for your invaluable contributions!
Here's to many more years of collaboration and streaming!
### Versioning
We received a substantial amount of feedback regarding our versioning scheme following the 10.11 release, particularly concerning the stability of what are perceived as 'minor' version updates.
This has prompted internal discussions about potentially revising our versioning scheme in the next major release.
While nothing has been finalized yet, we are considering 'dropping' the major version 10, which would make the next release 12.0.
Stay tuned for further updates as we navigate this feedback!
## Development Updates
### 10.11 Release Status
Jellyfin 10.11 introduced a major [EF Core refactor](https://jellyfin.org/posts/efcore-refactoring-incoming/), consolidating the legacy `library.db` into a single unified `jellyfin.db`.
Following more than six months of development and an additional six months of release candidate testing, version [10.11.0](https://jellyfin.org/posts/jellyfin-release-10.11.0/) was released last year.
This extended testing period allowed us to mitigate most [refactoring](https://github.com/jellyfin/jellyfin/issues/13047) and [RC](https://github.com/jellyfin/jellyfin/issues/14350)-related issues prior to release.
Even with this level of testing, issues were expected given the scale of the database change and the limited number of users reporting bugs.
These issues are currently being tracked on GitHub across three categories:
1. [General bugs](https://github.com/jellyfin/jellyfin/issues/15045)
2. [Performance bugs](https://github.com/jellyfin/jellyfin/issues/15685)
3. [Migration and database bugs](https://github.com/jellyfin/jellyfin/issues/15686)
We have been moving quickly to address these issues, delivering four additional point releases with over [100 changes](https://github.com/jellyfin/jellyfin/compare/v10.11.0...v10.11.5) since the initial 10.11.0 release.
To date, most point releases have focused on resolving general and migration-related issues.
The remaining migration issues are largely isolated, one-off cases and are unlikely to be resolved.
Most general issues have already been fixed, and the next bug-fix release is expected to include additional fixes for music metadata display issues and for watched status not being preserved when media is replaced or renamed.
We are continuing to investigate ways to mitigate performance issues caused by client-side enumeration and filtering of large datasets.
### Jellyfin Web vNext (aka 10.12 / 12.0)
- **Default 'Experimental' Layout**: The 'Experimental' layout is now enabled by default for all non-TV devices, introducing a new navigation layout and updated UI components.
- **Theming Support Overhaul**: We are improving theming support by enabling easier runtime customization of default themes through CSS variables and simplifying the process for creating new bundled themes.
- **Community Acknowledgment**: Huge thanks to those reviewing, testing, and providing feedback on web pull requests. Your contributions are immensely helpful, as the review burden largely falls on me alone!
\- [thornbill](https://github.com/thornbill)
## Client Corner
### Jellyfin Desktop
We're rebranding the desktop application from Jellyfin Media Player to Jellyfin Desktop.
The most noteworthy change is the migration from Qt 5 to Qt 6.
This seems to have improved overall performance, though we're still working out issues regarding memory leaks due to the migration.
Apart from the Qt migration, other noteworthy updates.
- Saved servers and settings will not be migrated from Jellyfin Media Player.
- We've laid the foundation for switching servers with the addition of profiles CLI options. The long-term goal is to have a UI for this as well, but the timeline is TBD.
- A slew of bug fixes are included.
The release is currently available on [Flathub](https://github.com/jellyfin/jellyfin-desktop) and in the [Arch Linux AUR](https://aur.archlinux.org/packages/jellyfin-desktop).
Stable builds for Windows and macOS builds are not currently available.
Other Linux distributions will likely be added, though we recommend using Flathub for the time being.
We are not currently supporting Ubuntu 24.04 LTS due to it being stuck on the older Qt 6.4 series, while our new dependency, mpvqt, requires at least Qt 6.5.
\- [Andrew Rabert](https://github.com/andrewrabert)
### Jellyfin for Android TV
Two versions of the Android TV app have been released: [v0.19.5](https://github.com/jellyfin/jellyfin-androidtv/releases/tag/v0.19.5) and [v0.19.6](https://github.com/jellyfin/jellyfin-androidtv/releases/tag/v0.19.6)!
These updates contain various improvements to music transcoding. The app now properly displays durations again and allows for seeking when music is transcoding. These changes also solve the issue of lyrics not scrolling in certain cases.
For video playback, we have improved the stability of Live TV and now support direct play for the VC-1 and AV1 codecs (if your device supports them). The AV1 support was already available on Android 10 and newer but now works on older Fire TV devices as well.
\- [Niels van Velzen](https://github.com/nielsvanvelzen)
### Jellyfin for Xbox
The last two updates brought the long awaited full gamepad support and fixes for 4K and HDR.
- **Gamepad support**: Gamepad navigation is now the default navigation type for the Jellyfin for Xbox app and requires a server version of 10.11 or higher to work. However as we cannot switch the input mode type while the app is running, the Jellyfin for Xbox app can no longer connect to older versions than 10.11. As this is a fundamental change in how the app works, there are still a few hiccups like the app not loading correctly and users reporting that the gamepad does not work at all. In those instances we recommend uninstalling and reinstalling the app.
- **Web UI TV mode**: For versions of Jellyfin earlier than 10.11.5 the web UI still runs in the desktop mode, which might look a bit odd. However, with Jellyfin 10.11.5, we have fixed a bug that now correctly sets the web UI to TV mode, so the UI should work a lot better.
- **4K and HDR**: For the last few versions, we have been working on enabling 4K and HDR for the app. This is done by integrating with the web UI and switching the HDMI modes. Sadly, this also comes at the cost of not being allowed to run in the background. To enable 4K support, we had to use a feature flag that allocates more video memory to the Jellyfin for Xbox app, making it incompatible with running in the background.
- **General Improvements**: Alongside the shiny new headline features, we have also been working on the code in general, adding small improvements and cleaning up a lot of code. The latest versions added log files and their upload to the Jellyfin server, tighter integrations with the web UI, a settings view that can be expanded for future features, version compatibility checking, a better server connection experience, and more.
- **Future**: When I took over the for the previous maintainer almost a year ago, I made a rough plan for the general development of the app. I always planned on keeping the app as a web wrapper because while the app is certainly more popular than most think, it does not have enough support in development to be a full UWP app. Nevertheless, there are a few features left on my to-do list:
- Localization to other languages
- Server discovery
- Desktop support
- Better decoder support
- Subtitle storage on-device
\- [JPVenson](https://github.com/JPVenson)
### Jellyfin for Roku
[3.0.15](https://github.com/jellyfin/jellyfin-roku/releases/tag/3.0.15) was released on 2025-12-18 and is our last release before Roku's year-end publishing blackout. It fixes a bug with HDHomeRun Tuners.
\- [1hitsong](https://github.com/1hitsong)
### Swiftfin
#### Swiftfin 1.4 is out now!
This is a large release with a lot of changes under the hood. Our three highlight changes are:
1. [Navigation & Routing Overhaul](https://github.com/jellyfin/Swiftfin/pull/1602)
2. [Jellyfin 10.11 Support](https://github.com/jellyfin/Swiftfin/pull/1772)
3. [Revamped Media Player Manager](https://github.com/jellyfin/Swiftfin/pull/1581)
#### Swiftfin Roadmap
A [roadmap / project board](https://github.com/orgs/jellyfin/projects/68) for Swiftfin is now available!
Follow [this discussion](https://github.com/jellyfin/Swiftfin/discussions/1294) for information about the next tvOS release.
To help organize Issues & PRs, Swiftfin now has milestones to help users identify which changes will be included in each release:
- [Version 1.5](https://github.com/jellyfin/Swiftfin/milestone/2)
- Contains issues that should be resolved in version 1.5 of Swiftfin iOS.
- [tvOS Resync](https://github.com/jellyfin/Swiftfin/milestone/3)
- Contains tvOS-specific issues that will be resolved as part of our next [tvOS Release](https://github.com/jellyfin/Swiftfin/discussions/1294).
- _Issues that impact tvOS but are part of 1.4 or 1.5 will end up in the version milestone instead of this one. Once tvOS is released, it should mirror our existing 1.X structure and iOS._
A more detailed post about these changes can be found [on GitHub](https://github.com/jellyfin/Swiftfin/discussions/1832)!
\- [JPKribs](https://github.com/JPKribs)
### Other TV Platforms
- The Tizen app was submitted for review, but unfortunately [failed testing](https://github.com/jellyfin/jellyfin-tizen/issues/222#issuecomment-3621581689). Additional work is needed to replicate the reported issues and correct them.
- Support for multiple **new** platforms is currently underway, and we will provide updates as progress is made.
Wishing you all happy streaming in 2026 and beyond!
We look forward to another year filled with exciting updates and features for Jellyfin.
\- thornbill and the Jellyfin Team
@@ -0,0 +1,117 @@
<svg viewBox="0 0 720 330" width="100%" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Activity by month">
<defs>
<linearGradient id="sotf-activity-grad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#AA5CC3" />
<stop offset="100%" stop-color="#00A4DC" />
</linearGradient>
</defs>
<path
d="M0.75,10.75 A10.0,10.0 0 0 1 10.75,0.75 L709.25,0.75 A10.0,10.0 0 0 1 719.25,10.75 L719.25,40.00 L0.75,40.00 Z"
fill="url(#sotf-activity-grad)"
/>
<text
x="360.0"
y="26.0"
text-anchor="middle"
font-size="17"
font-weight="700"
font-family="Plus Jakarta Sans, system-ui, -apple-system, Segoe UI, sans-serif"
fill="#ffffff"
>Activity by Month</text>
<rect x="0.75" y="0.75" width="718.5" height="328.5" rx="10" ry="10" fill="none" stroke="url(#sotf-activity-grad)" stroke-width="1.5" />
<line x1="56" y1="270.0" x2="660" y2="270.0" stroke="currentColor" stroke-width="0.5" opacity="0.15" />
<text x="48" y="274.0" text-anchor="end" font-size="10" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">0</text>
<line x1="56" y1="220.0" x2="660" y2="220.0" stroke="currentColor" stroke-width="0.5" opacity="0.15" />
<text x="48" y="224.0" text-anchor="end" font-size="10" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">150</text>
<line x1="56" y1="170.0" x2="660" y2="170.0" stroke="currentColor" stroke-width="0.5" opacity="0.15" />
<text x="48" y="174.0" text-anchor="end" font-size="10" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">300</text>
<line x1="56" y1="120.0" x2="660" y2="120.0" stroke="currentColor" stroke-width="0.5" opacity="0.15" />
<text x="48" y="124.0" text-anchor="end" font-size="10" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">450</text>
<line x1="56" y1="70.0" x2="660" y2="70.0" stroke="currentColor" stroke-width="0.5" opacity="0.15" />
<text x="48" y="74.0" text-anchor="end" font-size="10" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">600</text>
<text x="56.0" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">May</text>
<text x="110.9" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Jun</text>
<text x="165.8" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Jul</text>
<text x="220.7" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Aug</text>
<text x="275.6" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Sep</text>
<text x="330.5" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Oct</text>
<text x="385.5" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Nov</text>
<text x="440.4" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Dec</text>
<text x="495.3" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Jan</text>
<text x="550.2" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Feb</text>
<text x="605.1" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Mar</text>
<text x="660.0" y="288.0" text-anchor="middle" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.7">Apr</text>
<polyline
points="56.0,155.7 110.9,143.7 165.8,184.7 220.7,172.7 275.6,155.3 330.5,125.3 385.5,179.7 440.4,131.0 495.3,176.7 550.2,209.3 605.1,148.7 660.0,157.0"
fill="none"
stroke="#22c55e"
stroke-width="2"
stroke-linejoin="round"
stroke-linecap="round"
/>
<circle cx="56.0" cy="155.7" r="3" fill="#22c55e"><title>May: 343 prs merged</title></circle>
<circle cx="110.9" cy="143.7" r="3" fill="#22c55e"><title>Jun: 379 prs merged</title></circle>
<circle cx="165.8" cy="184.7" r="3" fill="#22c55e"><title>Jul: 256 prs merged</title></circle>
<circle cx="220.7" cy="172.7" r="3" fill="#22c55e"><title>Aug: 292 prs merged</title></circle>
<circle cx="275.6" cy="155.3" r="3" fill="#22c55e"><title>Sep: 344 prs merged</title></circle>
<circle cx="330.5" cy="125.3" r="3" fill="#22c55e"><title>Oct: 434 prs merged</title></circle>
<circle cx="385.5" cy="179.7" r="3" fill="#22c55e"><title>Nov: 271 prs merged</title></circle>
<circle cx="440.4" cy="131.0" r="3" fill="#22c55e"><title>Dec: 417 prs merged</title></circle>
<circle cx="495.3" cy="176.7" r="3" fill="#22c55e"><title>Jan: 280 prs merged</title></circle>
<circle cx="550.2" cy="209.3" r="3" fill="#22c55e"><title>Feb: 182 prs merged</title></circle>
<circle cx="605.1" cy="148.7" r="3" fill="#22c55e"><title>Mar: 364 prs merged</title></circle>
<circle cx="660.0" cy="157.0" r="3" fill="#22c55e"><title>Apr: 339 prs merged</title></circle>
<polyline
points="56.0,129.7 110.9,123.0 165.8,171.0 220.7,159.7 275.6,137.3 330.5,102.0 385.5,161.3 440.4,105.3 495.3,148.0 550.2,190.7 605.1,110.7 660.0,107.0"
fill="none"
stroke="#ef4444"
stroke-width="2"
stroke-linejoin="round"
stroke-linecap="round"
/>
<circle cx="56.0" cy="129.7" r="3" fill="#ef4444"><title>May: 421 issues closed</title></circle>
<circle cx="110.9" cy="123.0" r="3" fill="#ef4444"><title>Jun: 441 issues closed</title></circle>
<circle cx="165.8" cy="171.0" r="3" fill="#ef4444"><title>Jul: 297 issues closed</title></circle>
<circle cx="220.7" cy="159.7" r="3" fill="#ef4444"><title>Aug: 331 issues closed</title></circle>
<circle cx="275.6" cy="137.3" r="3" fill="#ef4444"><title>Sep: 398 issues closed</title></circle>
<circle cx="330.5" cy="102.0" r="3" fill="#ef4444"><title>Oct: 504 issues closed</title></circle>
<circle cx="385.5" cy="161.3" r="3" fill="#ef4444"><title>Nov: 326 issues closed</title></circle>
<circle cx="440.4" cy="105.3" r="3" fill="#ef4444"><title>Dec: 494 issues closed</title></circle>
<circle cx="495.3" cy="148.0" r="3" fill="#ef4444"><title>Jan: 366 issues closed</title></circle>
<circle cx="550.2" cy="190.7" r="3" fill="#ef4444"><title>Feb: 238 issues closed</title></circle>
<circle cx="605.1" cy="110.7" r="3" fill="#ef4444"><title>Mar: 478 issues closed</title></circle>
<circle cx="660.0" cy="107.0" r="3" fill="#ef4444"><title>Apr: 489 issues closed</title></circle>
<polyline
points="56.0,253.3 110.9,249.7 165.8,254.0 220.7,254.7 275.6,253.3 330.5,249.0 385.5,250.3 440.4,245.0 495.3,249.3 550.2,254.0 605.1,245.7 660.0,246.0"
fill="none"
stroke="#eab308"
stroke-width="2"
stroke-linejoin="round"
stroke-linecap="round"
/>
<circle cx="56.0" cy="253.3" r="3" fill="#eab308"><title>May: 50 contributors</title></circle>
<circle cx="110.9" cy="249.7" r="3" fill="#eab308"><title>Jun: 61 contributors</title></circle>
<circle cx="165.8" cy="254.0" r="3" fill="#eab308"><title>Jul: 48 contributors</title></circle>
<circle cx="220.7" cy="254.7" r="3" fill="#eab308"><title>Aug: 46 contributors</title></circle>
<circle cx="275.6" cy="253.3" r="3" fill="#eab308"><title>Sep: 50 contributors</title></circle>
<circle cx="330.5" cy="249.0" r="3" fill="#eab308"><title>Oct: 63 contributors</title></circle>
<circle cx="385.5" cy="250.3" r="3" fill="#eab308"><title>Nov: 59 contributors</title></circle>
<circle cx="440.4" cy="245.0" r="3" fill="#eab308"><title>Dec: 75 contributors</title></circle>
<circle cx="495.3" cy="249.3" r="3" fill="#eab308"><title>Jan: 62 contributors</title></circle>
<circle cx="550.2" cy="254.0" r="3" fill="#eab308"><title>Feb: 48 contributors</title></circle>
<circle cx="605.1" cy="245.7" r="3" fill="#eab308"><title>Mar: 73 contributors</title></circle>
<circle cx="660.0" cy="246.0" r="3" fill="#eab308"><title>Apr: 72 contributors</title></circle>
<circle cx="200" cy="316" r="4" fill="#22c55e" />
<text x="210" y="320" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.85">PRs Merged</text>
<circle cx="340" cy="316" r="4" fill="#ef4444" />
<text x="350" y="320" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.85">Issues Closed</text>
<circle cx="480" cy="316" r="4" fill="#eab308" />
<text x="490" y="320" font-size="11" font-family="system-ui, -apple-system, Segoe UI, sans-serif" fill="currentColor" opacity="0.85">Contributors</text>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

+265
View File
@@ -0,0 +1,265 @@
---
title: State of the Fin 2026-05-24
authors:
- jellyfin
slug: state-of-the-fin-2026-05-24
tags: [state-of-the-fin]
---
import ActivityChart from './activity-by-month.svg';
Welcome to the second edition of State of the Fin! This update will be slightly different to the previous one as we don't have as many large updates to announce (yet)! Still, we want to keep you informed on what is happening and what the Jellyfin development team are working on. Please enjoy, and contribute through our [standard channels](/contact) if you have questions or comments.
{/* truncate */}
## Project Updates
#### Versioning
As mentioned in the last [State of the Fin](/blog/2026/01-06-state-of-the-fin/index.mdx#versioning), we're dropping the major version "10" from our naming scheme. With 10.11.x being the final release branch to use it, the next major release will move directly to 12.0. The primary reason for this is to reduce confusion about what a "major" version is and eliminate the redundancy of a never-changing `10`. version prefix.
#### LLM/"AI" Policy
As with pretty much every open source project, we have been inundated with AI-authored pull requests of varying quality. This has vastly increased the amount of work the team has on their plate. To that end, an LLM/AI Policy has been created to try and help set standards. The tl;dr is **AI use isn't completely forbidden in pull requests/code submissions, however you must understand HOW it does what it does, and any posts to a pull request/issue should be written by the user. You cannot function as a go-between between your AI and our questions/comments, just copy-pasting whatever the AI tells you.** For more information, please read the [LLM/"AI" developmental policy](/docs/general/contributing/llm-policies) we have published.
The Jellyfin Team is made up of a lot of different people, and everyone has different levels of acceptance of/interest in code that an AI agent has contributed to. This policy has been made to try and help find a path that everyone can at least appreciate, even if they don't fully agree.
#### Burnout / Remember the Person
Jellyfin has been growing quickly as the landscape around us matures and changes. This is both a blessing and a curse. It is great that Jellyfin is so popular and loved by so many, however the increased support requests, combined with the AI code submissions, have led to burnout at various levels of the development and admin team. Abuse from users when something isn't working or a change isn't accepted only increases the loss of motivation. This has already led to delays in client and server improvements.
Please remember Jellyfin is open source and is written by volunteers. There are real people doing the work, and they're doing this for the love of the project. Yelling at them/insulting them will not make anything happen faster, and is actually more likely to delay fixes or improvements.
If you'd like to get involved in helping fellow users, hang out in the [standard Matrix/Discord channels](/contact), or look at the [forums](https://forum.jellyfin.org/)/[subreddit](https://reddit.com/r/jellyfin) and volunteer answers when you think the question is something you know. Straight AI searching and copy-paste answering aren't good responses and are explicitly banned by the aforementioned LLM policy, but if it's something you have dealt with, please contribute! The more people who help answer the easy questions, the more we can allow the devs to work on the hard stuff.
And of course, if you want to contribute code, we welcome it! Bug fixes are always welcome as-is; but features require a bit more work and a policy that we are still in the process of defining. But if you want to work on a feature, the short answer is: please ask us before you start implementing it and work with the team on a full design/scope discussion to help ensure your work will be accepted!
## Development Updates
<ActivityChart />
#### What's New
We've continued pushing bug and [security](https://github.com/jellyfin/jellyfin/security/advisories) fixes to the stable release. Following the 10.11.10 release, development attention has largely shifted toward finalizing 12.0 ahead of the upcoming release candidate phase. A few items still need to be addressed before we can ship RC1: [Jellyfin 12.0](https://github.com/orgs/jellyfin/projects/73)
The [Performance PR](https://github.com/jellyfin/jellyfin/pull/16062) which forms the foundation for much of the work in 12.0, has been merged into master and is now part of the weekly unstable releases. These are published every Monday, though we may push additional out-of-band builds for a while to support testing. Unstable builds can be accessed via Docker using the "unstable" tag or by selecting the unstable tab on our downloads page.
This PR addresses a number of slow queries in 10.11.x, particularly for folder-based libraries like home videos & photos, and books. Other areas have also seen improvements, including collections, music libraries, playlists, and homepage load times. For more details, see the PR description.
12.0 also includes a fix for EPG issues with the Schedules Direct API, as well as a fix for errors when restructuring media libraries. A long-requested feature, support for multiple versions of episodes in a series library, has also been added. While users may notice some incidental improvements in scanner performance as a result of other changes, scanner optimization itself was not a primary focus of this release. More substantial work in that area is planned for 13.0, which is currently in the early [planning phase](https://github.com/jellyfin/jellyfin-meta/discussions/125).
#### Testing
Before testing the unstable 12.0 build, please note the following:
Unstable builds are not guaranteed to work from one build to another. These builds should only be used for testing or evaluating new features, and running them as a daily driver is at your own risk.
If upgrading from an earlier version, a full backup of the data directory is strongly recommended, as this release includes database changes that prevent rolling back without a full restore.
Installed repository plugins (anything not built-in) should also be removed before migrating. Plugins will likely need time to adapt to the new database changes, so re-adding them afterward is the safest approach for testing.
Official plugins compatible with Jellyfin are available through the unstable plugin repository. To test plugins for 12.0:
- Go to Dashboard -> Plugins -> Manage Repositories
- Update the Plugin Repository URL to: https://repo.jellyfin.org/files/plugin-unstable/manifest.json
After migrating:
- Perform a full library scan to restore alternative versions
- Run the "Optimize database" scheduled task
If you run into issues, please prefix bug reports with "[12.0]".
#### Client Development Changes
As mentioned [before](/blog/2025/10-19-jellyfin-release-10.11.0/index.mdx#client-development-changes), the API will no longer allow deprecated authorization mechanisms by default, so clients and tooling that haven't already migrated will need to update. Any new API changes or breaking modifications not already in progress will now be deferred to 13.0, allowing client developers to begin targeting a stable API surface ahead of release.
That said, we've temporarily reverted the [default enforcement](https://github.com/jellyfin/jellyfin/pull/16754) during the testing phase, since some of our official clients are still in the process of completing the transition.
## Client Corner
### [Jellyfin for Android](https://github.com/jellyfin/jellyfin-android)
#### What's New
The mobile Android app stopped working after the recent 10.11.7 server update and was quickly resolved in 10.11.8. To keep the same problem from recurring, the app itself was also patched in the 2.6.4 release.
#### Notable Changes
- New patches in the 2.6.4 release to make sure a similar problem doesn't happen again.
- The 2.6.4 build is not available on the Google Play store for technical reasons.
#### What's Next
Work is ongoing for the upcoming 2.7.0 update. Recently we've finished the re-implementation of Android Auto support which was the major blocker for the next release. We'll likely start a beta cycle to collect feedback in the coming weeks/months. This version of the app will be compatible with Jellyfin 10.10 and newer.
*- [Niels van Velzen](https://github.com/nielsvanvelzen)*
### [Jellyfin for Android TV](https://github.com/jellyfin/jellyfin-androidtv)
#### What's New
Three updates to the app went live since our last State of the Fin, version 0.19.7 and 0.19.8 both fix numerous bugs. Most notably is a bug where our progress bar would be incorrect for some users. That's now fixed! In version 0.19.9 we made some improvements to the home screen to make it load faster and solved a long-term issue with the screensaver not working after playing a video.
#### What's Next
Work is still progressing on the next big Android TV release.
Version 0.20 will have a completely revamped look for the settings and also expands them to allow more customization and tweaking playback options. Work also continues on the new video player, with various features also made available to the current one, like support for SubStation Alpha subtitles and better handling of external apps for video playback.
This version of the app will require Jellyfin server 10.11 or newer. Due to community feedback, we have postponed the release until Jellyfin 12.0 is released. However, the beta versions of the app will likely start earlier and the app already notifies people about updating their server to 10.11.
*- [Niels van Velzen](https://github.com/nielsvanvelzen)*
### [Jellyfin for Desktop](https://github.com/jellyfin/jellyfin-desktop)
#### What's New
Jellyfin Desktop is being completely rewritten to address several performance, feature, and maintainability issues. Qt and its Chromium-based QtWebEngine have been replaced with Chromium Embedded Framework (CEF) to drastically improve responsiveness. The removal of Qt means we are no longer bound to a dependency that has historically been problematic when maintaining this project (Qt5->6, Qt WebEngine memory leaks). As for the audio/video side of things, we've switched from the legacy libmpv pipeline to the same modern pipeline that standalone mpv uses. This enables both better GPU acceleration (`vo=gpu-next`) and native HDR playback (Wayland/macOS/Windows). CEF and mpv are integrated via platform-native mechanisms that seamlessly overlay CEF on top of the video playback performance of standalone mpv. Long term, this should allow us to combine the functionality of Jellyfin MPV Shim into the Jellyfin Desktop codebase.
Although it's not yet ready for a stable v3.0.0 release, development builds are available in the [project's GitHub](https://github.com/jellyfin/jellyfin-desktop/). I actively welcome any bug reports or feature requests as they are incredibly helpful in prioritizing a sustainable, long-term codebase. To all early testers: thank you!
#### Notable Changes
- Completely rewritten without Qt/QtWebEngine
- Uses CEF as the browser engine
- Reworked audio/video pipeline to use the same as standalone mpv
- Supports mpv.conf and mpv plugins
- Linux AppImage support added
- Windows ARM support added
#### Known Issues
- Some features found in v1.x and v2.x are missing
#### What's Next
- Stabilize architecture to allow for better programmatic testing
- Formal v3.0.0 pre-release
*- [Andrew Rabert](https://github.com/andrewrabert)*
### [Jellyfin for Kodi](https://github.com/jellyfin/jellyfin-kodi)
#### What's New
A couple of long-requested features have been completed in this period along with bug fixes and general cleanup.
#### Notable Changes
- Media Segments are now supported.
- Quick Connect support has been merged and will be included in a future release.
*- [MCarlton00](https://github.com/mcarlton00)*
### [Jellyfin for Roku](https://github.com/jellyfin/jellyfin-roku)
#### Latest Release: 3.1.9
#### Minimum Server Version: 10.9.0
#### Highlights
- New setting allowing you to change the poster orientation in libraries
- New settings allowing you to change playback speed
- Choose between 1 or 5 displayed trickplay images
- OSD seekbar is now fully functional
- Custom subtitles now support font color tags
- Subtitle timing offset now available for custom subtitles
- Many more direct play profiles added
- Oh so many bug fixes
- And so much more!
#### What's Next
- More custom subtitle enhancements (bold & italic?!?! 😱 )
- Default subtitle selection improvements
- Default audio track selection improvements
*- [1hitsong](https://github.com/1hitsong)*
### [Jellyfin for Tizen](https://github.com/jellyfin/jellyfin-tizen)
#### What's New
The [Tizen Jellyfin client](https://github.com/jellyfin/jellyfin-tizen) for Tizen 6 and newer has been released to the Samsung Tizen Store! Tizen 5 and earlier should still be able to side-load the client.
*- [Eric Stacey](https://github.com/ejstacey)*
### [Jellyfin for Xbox](https://github.com/jellyfin/jellyfin-xbox)
#### What's New
Since the last State of the Fin, Jellyfin for Xbox has seen several new PRs for various fixes and improvements. We also checked off a major item from the previous State of the Fin todo list: Jellyfin for Xbox now supports translations!
#### Notable Changes
- **UI Refresh**: Various UX fixes and improvements throughout the app interface.
- **Log File Upload Dialog**: A new dialog allows uploading any of the last 6 log files directly from within the app.
- **Translation Support**: Jellyfin for Xbox now supports localization!
<img src="https://translate.jellyfin.org/widget/jellyfin-for-xbox/multi-auto.svg" alt="Translation support" style={{maxWidth: '300px', width: '100%'}} />
#### What's Next
A new v0.9.5 release incorporating these changes is coming soon!
*- [Jean-Pierre Bachmann](https://github.com/JPVenson)*
## Jellyfin Labs
### [Swiftfin](https://github.com/jellyfin/Swiftfin)
#### What's New
Swiftfin has had a lot of recent development in preparation for 1.5 and our next tvOS release. A lot of our recent work has been focused on utilizing new SwiftUI improvements to better unify work between iOS and tvOS. There is a lot of effort involved in this but this should help improve our release cadence moving forward.
#### Notable Changes
- Many iOS player bug fixes and additional supplement information & customization.
- Structural changes to better unify iOS and tvOS development moving forward.
- Lots of work towards our next [tvOS release](https://github.com/jellyfin/Swiftfin/discussions/1294) including the resolution of some [longstanding and high profile issues](https://github.com/jellyfin/Swiftfin/issues/776)!
#### Known Issues
- In the final version of Jellyfin 12.0, Swiftfin tvOS will not be able to authenticate without [enabling legacy authentication](https://gist.github.com/nielsvanvelzen/ea047d9028f676185832e51ffaf12a6f#disabling-deprecated-authorization-methods). This is resolved for iOS/iPadOS and will be resolved in the next tvOS release. _It is **our goal** to have a new tvOS release before 12.0 is out of testing._
#### What's Next
We are working hard on our next release! If you are interested in helping out, please see our [Help Wanted](https://github.com/jellyfin/Swiftfin/discussions/1503) post for details on getting started!
*- [Joe Kribs](https://github.com/JPKribs)*
### Jellyfin for Titan OS & Vega OS
Work has started on two new Jellyfin clients!
Currently in the prototype phase is a Jellyfin client for the new **Vega OS** platform from Amazon. This is the operating system used on the newer models of Fire TV Sticks released since 2025. We've seen a lot of requests for this as people buy the devices thinking they can use our Android TV app and end up not finding Jellyfin.
Further into development is our client for **Titan OS**. This smart TV platform is mainly found on Philips televisions. We're currently testing this client and hopefully have some news to share soon!
*- [Niels van Velzen](https://github.com/nielsvanvelzen)*
## [Documentation](https://github.com/jellyfin/jellyfin.org)
#### What's New
Documentation is always a work in progress but over this period Jellyfin's documentation has seen some notable changes:
- Improved CI to catch common issues and spelling errors
- A new feature proposal guideline
- Fish shell support added to the installer commands
- Cleanup of reverse proxy documentation
- The LLM policy made its way into the docs
#### Moving Forward
New contributors have been assisting, which has been a tremendous help! Thank you to everyone who has pitched in so far. If you are interested in getting involved, please feel free to create a PR.
*- [BotBlake](https://github.com/BotBlake)*
## Closing Thoughts
While this post isn't full of new announcements, it's worth posting so you know people are still working on things in the background. Jellyfin was originally forked from Emby, however the projects have different goals and directions. For Jellyfin, this includes some very deep rewrites of core code, which takes a lot of time and effort. It is necessary to help the codebase mature for the future of the project. We hope with the extra details given in this blog, which are public but generally not broadcasted, you can appreciate the scope and size of the Jellyfin work, and the people behind it. Thank you for using and supporting Jellyfin!
\- [Eric Stacey](https://github.com/ejstacey)
+19
View File
@@ -1,3 +1,9 @@
jellyfin:
name: Jellyfin Team
title: Jellyfin Team
url: https://jellyfin.org/
image_url: https://avatars.githubusercontent.com/u/45698031?s=200&v=4
1hitsong:
name: 1hitsong
title: Roku Team
@@ -33,6 +39,10 @@ joshuaboniface:
title: Project Leader
url: https://github.com/joshuaboniface
image_url: https://avatars.githubusercontent.com/u/4031396?v=4
socials:
github: joshuaboniface
mastodon: https://social.bonifacelabs.ca/@joshuaboniface
reddit: https://reddit.com/u/djbon2112
mcarlton00:
name: Matt Carlton
@@ -66,3 +76,12 @@ JPVenson:
title: Server Team
url: https://github.com/JPVenson
image_url: https://avatars.githubusercontent.com/u/6794763?v=4
thornbill:
name: Bill Thornton
page: true
title: Core Team, Web and iOS Lead
image_url: https://avatars.githubusercontent.com/u/3450688?v=4
socials:
github: thornbill
mastodon: https://fosstodon.org/@thornbill
+28
View File
@@ -0,0 +1,28 @@
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"language": "en, en-US, en-GB",
"allowCompoundWords": true,
"files": ["**/*.md", "**/*.mdx", "**/*.tsx"],
"dictionaryDefinitions": [
{
"name": "project-words",
"path": "./project-words.txt",
"addWords": true
}
],
"dictionaries": ["project-words"],
"ignorePaths": [
"node_modules",
"/project-words.txt",
"/src/components/common/PlatformIcon.tsx",
"/blog/2019/*",
"/blog/2020/*",
"/blog/2021/*",
"/blog/2022/*",
"/blog/2023/*",
"/blog/2024/*",
"/blog/2025/*"
]
}
+1
View File
@@ -1,6 +1,7 @@
---
uid: about
title: About Jellyfin
sidebar_position: 100
---
# About Jellyfin
@@ -11,37 +11,76 @@ This guide documents how to both back up and then restore the data in your Jelly
Backups are important in general for all digital data. There are myriad possible bugs and issues that can arise and cause data loss, especially when you upgrade major releases (for instance, from Jellyfin 10.9.x to Jellyfin 10.10.x).
In addition, Jellyfin does not have a downgrade mechanism. This is very important to understand; once your Jellyfin instance has been started with a new version, any pending migrations are immediately applied, and your Jellyfin data will no longer work with the old version. The **only** way to restore your active instance back to the old version is to restore a backup. Backups are thus critical if you want to test Unstable versions, or before upgradiing to the latest version. In fact, when testing Unstable, it is best to back up much more regularly, perhaps using a cron job or similar automatic mechanism, to ensure that your data can be recovered if you hit a major issue.
In addition, Jellyfin does not have a downgrade mechanism. This is very important to understand; once your Jellyfin instance has been started with a new version, any pending migrations are immediately applied, and your Jellyfin data will no longer work with the old version. The **only** way to restore your active instance back to the old version is to restore a backup. Backups are thus critical if you want to test Unstable versions, or before upgrading to the latest version. In fact, when testing Unstable, it is best to back up much more regularly, perhaps using a cron job or similar automatic mechanism, to ensure that your data can be recovered if you hit a major issue.
Backups may also come in handy if you hit a bug. For instance, if a bug in the new version causes corruption of some aspect of the Jellyfin data, restoring from a backup means you can quickly restore to good data and apply any fixes to avoid a repeat. Without a backup, you would be completely out of luck in this situation.
Finally, administrative mistakes, normal operation issues (e.g. filling up a disk), or general bit rot can cause corruption or issues that require a backup to be restored. It's always better to have one than not.
## Taking a Backup
There are two ways of backing up your Jellyfin data. One is with its built-in Backup/Restore system and the other is manually.
## Built-in Backup
Jellyfin's built-in backup system is able to create a backup while your system is online and running, as opposed to the manual process that **requires** you to stop Jellyfin beforehand.
However in 10.11 we still recommend performing the backup process during a time of low activity and while no scan is currently active.
### Create a Built-in Backup
To take a new Backup, enter the Jellyfin Dashboard, open the `Backups` tab and click on the `Create Backup` button. The popup will now ask you to select what data you want to backup.
- Database. Always enabled. Will contain all data from the jellyfin.db or used database provider.
- Metadata. The contents of the metadata folder and depending on your selected options may contain metadata images.
- Subtitles. All extracted subtitles including downloaded ones.
- Trickplay. All Trickplay data that is stored not alongside media.
The Backup system will check for at least 5GB of free space in the backup folder where backups a written to. However this can easily not be enough if you also backup Subtitles and Trickplay so ensure you have enough free space there.
The Backup folder is located within your Jellyfin data directory, by default:
- Official Docker: `<volume path>/config/data/backups` where `<volume path>` is where your `/config` volume is sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`.
- LinuxServer.io Docker: `<volume path>/config/data/data/backups` where `<volume path>` is where your `/config` volume is sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`.
- Debian/Ubuntu packages: `/var/lib/jellyfin/data/backups`.
- RPMFusion Fedora/CentOS packages: `/var/lib/jellyfin/data/backups`.
- Windows User Install: `%LOCALAPPDATA%\Jellyfin\data\backups` (`C:\Users\<Username>\AppData\Local\Jellyfin\data\backups`)
- Windows Service Install: `%PROGRAMDATA%\Jellyfin\Server\data\backups` (`C:\ProgramData\Jellyfin\Server\data\backups`)
- MacOS Installer (.dmg): Data is stored in one of these paths; back up whichever one(s) exist: `~/.config/jellyfin/data/backups`, `~/.local/share/jellyfin/data/backups`, `~/Library/Application Support/Jellyfin/data/backups`:
- Portable Installs:
- Linux: Data is stored in `~/.local/share/jellyfin/data/backups`.
- Windows: Data and config is in `C:\Users\<Username>\AppData\Local\jellyfin\data\backups`, using `%LOCALAPPDATA%`.
- MacOS: Data is stored in these paths; back up whichever one(s) exist: `~/.config/jellyfin/data/backups`, `~/.local/share/jellyfin/data/backups`, `~/Library/Application Support/Jellyfin/data/backups`.
After clicking on the `Create` button all data will be written into a new zip archive.
### Restore from a Built-in Backup
To restore from a Backup you can either use the webUI by navigating to the same view as for the step above and clicking on the restore button in the list of backups, or you can start jellyfin with the `--restore-archive PATH_TO_BACKUP_ZIP` argument. Note that when you start a restore from the webUI, your server will immediately restart for this process to take place and will be unavailable for that time.
## Manual Backup
Taking a manual Backup essentially involves you copying all the data jellyfin requires on your own.
### Create a Manual Backup
1. Stop the running Jellyfin server. This is extremely important, as otherwise the database will be locked and might not be recoverable when restoring. Note that this will interrupt any playback.
* Any platform: Within the Jellyfin Dashboard, click "Shutdown". This should cleanly stop the process on all platforms, but if not, try one of the following.
* Docker: `docker stop jellyfin`
* Debian/Ubuntu packages: `sudo systemctl stop jellyfin` or `sudo service jellyfin stop`
* Windows Installer: Right-click the Tray app, and select "Quit"; or, in Process Manager, find the Jellyfin process and terminate it.
* MacOS Installer (.dmg): In Activity Monitor, find the Jellyfin process and terminate it.
* Portable Installs (regardless of platform): Stop the running `jellyfin` or `jellyfin.exe` program, however it was started.
- Any platform: Within the Jellyfin Dashboard, click "Shutdown". This should cleanly stop the process on all platforms, but if not, try one of the following.
- Docker: `docker stop jellyfin`
- Debian/Ubuntu packages: `sudo systemctl stop jellyfin` or `sudo service jellyfin stop`
- Windows Installer: Right-click the Tray app, and select "Quit"; or, in Process Manager, find the Jellyfin process and terminate it.
- MacOS Installer (.dmg): In Activity Monitor, find the Jellyfin process and terminate it.
- Portable Installs (regardless of platform): Stop the running `jellyfin` or `jellyfin.exe` program, however it was started.
2. Copy your data and configuration directories to a destination of your choice. What you name the copies is up to you; personally, I like to use dated and versioned directory names e.g. `jellyfin.2024-05-01_10.8.13`. Where these files are also depends on the platform; generally these follow the [XDG Directory Specification](https://specifications.freedesktop.org/basedir-spec/latest/) for platforms that support it. For more information see [the configuration documentation](/docs/general/administration/configuration/#server-paths).
**NOTE**: These are default locations; if you've changed your data or config paths, use those instead.
* Official Docker: Wherever your `/data` and `/config` volumes are sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`.
* LinuxServer.io Docker: Data and config are wherever your `/config` volume is sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`.
* Debian/Ubuntu packages: Data is in `/var/lib/jellyfin` and config is in `/etc/jellyfin`; these are defined in `/etc/default/jellyfin`.
* RPMFusion Fedora/CentOS packages: Data is in `/var/lib/jellyfin` and config is in `/etc/jellyfin`; these are defined in `/etc/sysconfig/jellyfin`.
* Windows Tray/Installer (.exe): Data and config is in `%PROGRAMDATA%\Jellyfin\Server` (`C:\ProgramData\Jellyfin\Server`) or `%LOCALAPPDATA%\Jellyfin` (`C:\Users\<Username>\AppData\Local\Jellyfin`).
* MacOS Installer (.dmg): Data is stored in one of these paths; back up whichever one(s) exist: `~/.config/jellyfin/`, `~/.local/share/jellyfin/`, `~/Library/Application Support/Jellyfin/`.
* Portable Installs:
* Linux: Data is stored in `~/.local/share/jellyfin` and config in `~/.local/share/jellyfin`.
* Windows: Data and config is in `C:\Users\<Username>\AppData\Local\Jellyfin`, using `%LOCALAPPDATA%`.
* MacOS: Data is stored in these paths; back up whichever one(s) exist: `~/.config/jellyfin/`, `~/.local/share/jellyfin/`, `~/Library/Application Support/Jellyfin/`.
- Official Docker: The data directory is wherever your `/config` volume is sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`. This directory contains the config directory as well.
- LinuxServer.io Docker: The config directory is wherever your `/config` volume is sourced from; this is set in your `docker-compose.yml` or in your `-v` options to `docker run`. This directory contains the data directory as well.
- Debian/Ubuntu packages: The data directory is `/var/lib/jellyfin` and the config directory is `/etc/jellyfin`; these are defined in `/etc/default/jellyfin`.
- RPMFusion Fedora/CentOS packages: The data directory is `/var/lib/jellyfin` and the config directory is `/etc/jellyfin`; these are defined in `/etc/sysconfig/jellyfin`.
- Windows Tray/Installer (.exe): The data directory is `%PROGRAMDATA%\Jellyfin\Server` (`C:\ProgramData\Jellyfin\Server`) or `%LOCALAPPDATA%\Jellyfin` (`C:\Users\<Username>\AppData\Local\Jellyfin`). This directory contains the config directory as well.
- MacOS Installer (.dmg): Data is stored in one of these paths; back up whichever one(s) exist: `~/.config/jellyfin/`, `~/.local/share/jellyfin/`, `~/Library/Application Support/Jellyfin/`.
- Portable Installs:
- Linux: The data and config directories are both `~/.local/share/jellyfin`.
- Windows: The data directory is `%LOCALAPPDATA%\jellyfin` (`C:\Users\<Username>\AppData\Local\jellyfin`). This directory contains the config directory as well.
- MacOS: Data is stored in these paths; back up whichever one(s) exist: `~/.config/jellyfin/`, `~/.local/share/jellyfin/`, `~/Library/Application Support/Jellyfin/`.
As an example, on Debian, you can do this with these commands to make a copy of both directories into a single target directory:
@@ -55,7 +94,7 @@ Finally, administrative mistakes, normal operation issues (e.g. filling up a dis
3. Start up Jellyfin again, either after upgrading or on the current version. You now have a safe copy of your data in the path chosen in step 2.
## Restoring a Backup
### Restore from a Manual Backup
This process assumes you followed the steps above to take the backup.
@@ -68,7 +107,3 @@ This process assumes you followed the steps above to take the backup.
4. If required, downgrade Jellyfin to the same version as your backup now.
5. Start up Jellyfin again. It should start cleanly with the old data, assuming versions are correct. If you downgraded this may happen automatically.
## The Future
Long-term, we have plans to provide an official backup and restore plugin bundled with Jellyfin, however this requires the completion of our EFCore rewrite, which is currently slated for our next major release 10.11.0. Once that becomes available, this document will be updated to reflect the process using that plugin.
+7 -7
View File
@@ -19,7 +19,7 @@ Documentation for the available command line options can be obtained by adding t
## Server Paths
The file paths used by the server are determined according to the rules outlined below. In general, the [XDG specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) is followed by default for non-Windows systems.
The file paths used by the server are determined according to the rules outlined below. In general, the [XDG specification](https://specifications.freedesktop.org/basedir-spec/latest/) is followed by default for non-Windows systems.
### Data Directory
@@ -105,12 +105,12 @@ The main server configuration is built upon the ASP .NET [configuration framewor
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. |
| `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. |
| `PublishedServerUrl` | Server Url based on primary IP address | The Server URL to publish in udp Auto Discovery response. |
| Key | Default Value | Description |
| ------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `hostwebclient` | `True` | Set to `True` if the server should host the web client. |
| `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. |
| `PublishedServerUrl` | Server Url based on primary IP address | The Server URL to publish in udp Auto Discovery response. |
## Fonts
@@ -5,11 +5,11 @@ title: Hardware Selection
# Selecting Appropriate Hardware
This page covers what you need to know in order to select appropriate hardware for a Jellyfin server and take full advantage of its features (e. g. hardware acceleration).
The following is intended to help you choose appropriate hardware for a Jellyfin server and take full advantage of its features (e.g. hardware acceleration).
## TL;DR
## Simple Guide
Below is a list of recommended specs to run Jellyfin. Even though Jellyfin will work on even lower end hardware, the following specs are recommended for a good experience.
Below is a list of recommended specs to run Jellyfin. Whilst Jellyfin can work on relatively low-end hardware, the following specs are recommended for a good experience.
### Shared Items
@@ -17,45 +17,51 @@ Some component recommendations do not change regardless of the hardware configur
- Storage: 100GB SSD for your OS, Jellyfin files and transcoding cache.<sup>1</sup> Consider adding more on Windows 11, or if you have many large media files that need transcoding.
- Networking: Gigabit Ethernet Adapter or faster, WiFi or Powerline not recommended.
- Internet Connection: At least 20mbps upload bandwidth for remote access.<sup>2</sup>
- Internet Connection: At least 20 Mbps upload bandwidth for remote access.<sup>2</sup>
<sup>1</sup>Your largest media file times the max number of concurrent streams all your users will consume can be used as a rule of thumb for the transcoding file size. <br />
<sup>2</sup>If you have less than 100mbps of total upload bandwidth, a bandwidth limit of 70% of your upload speed for Jellyfin is recommended to avoid affecting normal internet usage. This option can be found in the dashboard.
<sup>2</sup>If you have less than 100 Mbps of total upload bandwidth, a bandwidth limit of 70% of your upload speed for Jellyfin is recommended to avoid affecting internet usage outside of Jellyfin. This option can be found in the Jellyfin Server `Dashboard`.
### Hardware Encoder Quality
Different vendors have different hardware encoder implementations and produce different results. Usually, newer generations within the same vendor will provide better results. The following is a quick comparison on the quality between vendors on modern products.
Apple ≥ Intel ≥ Nvidia >>> AMD<sup>\*</sup>
Apple ≥ Intel ≥ NVIDIA >>> AMD<sup>\*</sup>
<sup>\*</sup> This only represents the default Jellyfin settings. The quality may be different depending on your exact configuration.
### Server with Integrated Graphics
If you are not planning to use a dedicated graphics card, the following specs are recommended:
If you do not intend to use a dedicated graphics card, the following specs are recommended:
- CPU: Intel Core i5-11400, Intel Pentium Gold G7400, Intel N100, Apple M series or newer (excluding Intel J/M/N/Y series up to 11th gen)
- RAM: 8GB System RAM (Consider adding more on Windows 11)
- Graphics: Intel UHD 710, Apple M series or newer
AMD is **NOT** recommended if you plan to use integrated graphics for Jellyfin.
AMD is **NOT** recommended if you intend to use integrated graphics for Jellyfin.
:::caution
Intel 7-10th gen CPUs have been removed from this list, since the toolkit for these generations has been deprecated by Intel. If you own 7-10th gen CPUs with integrated graphics, please continue to use them for Jellyfin, as they are still perfectly capable of performing the task. If you are making a purchase decision, please consider something else instead.
Intel 7-10th gen CPUs have been removed from this list, since the toolkit for these generations has been deprecated by Intel. If you own a 7-10th gen CPU with integrated graphics, please continue to use them for Jellyfin, as they are still perfectly capable of performing the task. If you are making a purchase decision, you may wish to consider alternatives.
:::
### Server with Dedicated Graphics
If you are planning to use a dedicated graphics card (including upgrading an old system with a dedicated GPU), the following specs are recommended:
If you intend to use a dedicated graphics card (including upgrading an old system with a dedicated GPU), the following specs are recommended:
- CPU: Intel Core i5-2300 AMD FX-8100 or better (Geekbench 6 Multicore 1500 or better), CPU Vendor / Performance will **NOT** affect hardware encode speed or quality
- RAM: 8GB (4GB should be enough for a server running Linux without a GUI)
- Graphics: Intel Arc A series or newer, Nvidia GTX16/RTX20 series or newer (Excluding GTX1650), **AMD is NOT recommended**.
- CPU: Intel Core i5-2300AMD FX-8100 or better (Geekbench 6 Multicore 1500 or better), CPU Vendor / Performance will **NOT** affect hardware encode speed or quality
- RAM: 8GB. (4GB may be sufficient for a Linux server without its own GUI.)
- Graphics: Intel Arc A series or newer, NVIDIA GTX16/RTX20 series or newer (Excluding GTX1650), **AMD is NOT recommended**.
Intel Drivers are much easier to install on Linux, with many distributions including them by default. If you do not need CUDA for other applications, it is highly recommended that you stick with Intel Graphics on Linux.
:::caution
Intel ARC B-series cards require ReBar to be enabled. This means you must use it on a platform with Intel 10th gen, AMD Ryzen 3000 series or newer. Intel ARC A-series cards do not require ReBar to function, however, ReBar should be enabled for optimal performance.
:::
### Servers without GPUs
Not having a GPU is **NOT** recommended for Jellyfin, as video transcoding on the CPU is very performance demanding. HDR
@@ -64,21 +70,21 @@ where a Ryzen 9 5950X cannot handle even a single video stream. Please read [the
### Low Power Servers
For users with expensive power or running servers on battery power:
For users with expensive electricity, or running battery-powered servers:
- Intel 12th gen or above N series platforms
- Apple M Series mac mini
- Apple M Series Mac mini
- Rockchip RK3588 / RK3588S SBC (**Advanced Users Only**)
### Potentially Problematic Hardware
These hardware platforms might lead to a poor Jellyfin experience. Please be careful to avoid them when shopping for hardware.
- Intel "Atom" CPUs: Intel J/M/N/Y series low power CPUs up to 11th gen use a different architecture than higher end parts, leading to subpar performance despite what their names might suggest. Please be careful about these parts when shopping for a system to run Jellyfin.
- Prebuilt NAS devices: The software environment on most Prebuilt NAS devices often causes 3rd party software to be hard to install and not work properly. They also often have low end processors that are too slow for a good Jellyfin experience (Intel Atom, Realtek ARM CPUs etc.).
- Most Single Board Computers (SBC): Most SBCs (Including Raspberry Pis and **especially the Pi 5**) are too slow to provide a good Jellyfin experience since they often lack proper support for hardware acceleration. If You really want to run Jellyfin on an SBC, please look at models based on the following platforms: Rockchip RK3588 / RK3588S, Intel Core, Intel 12th gen N series
- Intel "Atom" CPUs: Intel J/M/N/Y series low power CPUs up to 11th gen use a different architecture than higher end parts, leading to subpar performance despite what their names might suggest. It is advised to avoid using these parts in a Jellyfin Server.
- Prebuilt NAS Appliances: The software environment on most prebuilt NAS appliances often makes third-party software more challenging to install, sometimes even preventing it from working properly despite a successful installation. They may have low-end processors that are too slow for an acceptable Jellyfin experience. (e.g. Intel Atom, Realtek ARM CPUs, etc.).
- Most Single Board Computers (SBC): Most SBCs (including the Raspberry Pi, **especially the Raspberry Pi 5**) are too slow to provide an acceptable Jellyfin experience as they often lack proper support for hardware acceleration. If you really want to run Jellyfin on an SBC, you may wish to consider models based on the following platforms: Rockchip RK3588 / RK3588S, Intel Core, Intel 12th gen N series
- AMD Graphics: AMD Graphics have poor encoder quality and poor driver support. **This applies even on Linux**.
- Low end GPUs: Certain low end GPUs (eg. GT1030, RX6400) don't have hardware encoding available. These models can't be used for Jellyfin hardware acceleration.
- Low-end GPUs: Certain low-end GPUs (e.g. GT1030, RX6400) are not capable of hardware encoding. These models cannot be used for hardware acceleration for a Jellyfin Server.
## Detailed Guide
@@ -89,94 +95,95 @@ The CPU will be responsible for many tasks, notably:
- Transcoding Audio
- Decoding video in unsupported codecs
Audio codecs are very lightweight and most CPUs should be able to handle them without issues (Ryzen 5950X FLAC -> AAC transcoding runs at ~110x real time). Please note that they will only use one core.
Whilst most audio codecs will only utilize a single core, they are very lightweight and most CPUs should be able to handle them without issues. (e.g. a Ryzen 5950X transcoding `FLAC -> AAC` runs at ~110x real-time.)
Video in unsupported codecs are usually older formats that are easier to decode. Assuming hardware acceleration is properly configured, any modern CPU with 4 threads should be able to handle the workload.
However, newer codecs can also require software decoding if there are no available hardware decoders. HEVC, VP9 and AV1 can be **VERY** demanding even on modern CPUs if hardware acceleration isn't available. This is why a hardware platform capable of HEVC 10bit hardware decoding is strongly recommended.
However, newer codecs can also require software decoding if there are no available hardware decoders. HEVC, VP9 and AV1 can be **VERY** demanding even on modern CPUs if hardware acceleration is not available on a Jellyfin Server. This is why a hardware platform capable of HEVC 10bit hardware decoding is strongly recommended.
In our custom `jellyfin-ffmpeg` fork, the dav1d decoder is enabled, leading to faster software decoding compared to HEVC or VP9. However, it will still use significantly more resources compared to software decoding H.264 or older codecs. Since we have a more efficient AV1 software decoder, and AV1 media isn't common yet, you shouldn't worry about AV1 when shopping for hardware.
In our custom `jellyfin-ffmpeg` fork, the dav1d decoder is enabled, leading to faster software decoding compared to HEVC or VP9. However, it will still use significantly more resources compared to software decoding H.264 and older codecs. Since we have a more efficient AV1 software decoder, and AV1 media isn't common yet, you shouldn't worry about AV1 when choosing components for your Jellyfin Server.
#### Integrated Graphics
Integrated graphics can be useful for transcoding video. Please refer to [the GPU section](/docs/general/administration/hardware-selection#graphics-cards-gpus) for a guide.
Integrated graphics can be useful for transcoding video. For more information, please refer to [the GPU section](/docs/general/administration/hardware-selection#graphics-cards-gpus).
#### Resizable BAR
[Resizable Bar (ReBAR)](https://www.intel.com/content/www/us/en/support/articles/000090831/graphics.html) is a PCI Express feature that optimizes access to PCIe devices. This feature requires support from both the platform and the device. Intel 10th gen or above and AMD Ryzen 3000 Series or above have support for this feature.
[Resizable Bar (ReBAR)](https://www.intel.com/content/www/us/en/support/articles/000090831/graphics.html) is a PCI Express feature that optimizes access to PCIe devices. This feature requires support from both the platform and the device. Support for this feature is respectively available beginning with Intel 10th gen and AMD Ryzen 3000 Series.
In BIOS settings of motherboards, it may also be called `Smart Access Memory` or `Clever Access Memory`
When using Intel ARC Graphics, Resizable BAR is recommended. Disabling it will result in a 10% reduction in transcoding performance. However, given how fast the media engine on Intel ARC is, this will not be a problem for the vast majority of users.
When using Intel ARC Graphics, Resizable BAR is recommended. Disabling it will result in a 10% reduction in transcoding performance. However, given how fast the media engine on Intel ARC is, this should not be a problem for the average deployment.
#### Software HDR to SDR Tone-mapping
If there is no GPU available, the CPU can also be used to tone-map HDR content to SDR. **This can be very demanding on
If there is no GPU available on a Jellyfin Server, the CPU can also be used to tone-map HDR content to SDR. **This can be very demanding on
the CPU, therefore a GPU is ALWAYS recommended.** When using software tone-mapping, a software encoder will always be
used. Tone-mapping 4K 60fps Dolby Vision content to 4K 60fps H264 SDR requires a Ryzen 9 5950X for faster than real time
transcoding. If you would like to output in H265 or AV1, you may end up in situations where no current desktop CPUs have
enough performance.
used. Tone-mapping 4K 60fps Dolby Vision content to 4K 60fps H264 SDR requires a Ryzen 9 5950X for faster than real-time
transcoding. You may find current desktop CPUs do not offer adequate performance if you seek to provide streams in H.265 or AV1.
### System Memory (RAM)
As a general rule of thumb, at least 8GB is recommended for most configurations. For a Linux server running without a GUI, 4GB should be enough.
As a general recommendation, at least 8GB is recommended for the average deployment. For a Linux server running without a GUI, 4GB may be enough.
It is recommended to add more memory on Windows 11 due to the OS being heavier.
It is recommended to add more memory when using Windows 11 due to the OS being heavier.
### Graphics Cards (GPUs)
With modern systems, the media engines are usually located on the GPUs. Therefore, the available hardware acceleration options are determined by the choice of GPU.
Encoder Quality: Apple ≥ Intel ≥ Nvidia >>> AMD<sup>\*</sup>
Encoder Quality: Apple ≥ Intel ≥ NVIDIA >>> AMD<sup>\*</sup>
<sup>\*</sup> This only represents the default Jellyfin settings. The quality may be different depending on your exact configuration.
Intel is always recommended on non-apple hardware for the following reasons:
Intel is always recommended on non-Apple hardware for the following reasons:
- Intel provides a good quality encoder, slightly better than Nvidia and significantly better than AMD.
- Intel drivers and the compute environment is much easier to setup than both Nvidia and AMD
- Intel provides a good quality encoder, slightly better than NVIDIA and significantly better than AMD.
- Intel drivers and the compute environment is much easier to setup than both NVIDIA and AMD
AMD is not recommended because of poor quality H.264 and H.265(HEVC) output, as well as being hard to setup the compute environment. While AMD has significantly improved AV1 encoder quality, you are still more likely to transcode to H.264 or H.265 than to AV1 due to compatibility.
AMD is not recommended due to poor quality H.264 and H.265 (HEVC) output, as well as being hard to set up the compute environment. While AMD has significantly improved AV1 encoder quality, you are still more likely to transcode to H.264 or H.265 than to AV1 due to the hardware capabilities of the average Jellyfin client.
A list of common codecs can be found [here](/docs/general/clients/codec-support/)
A list of common codecs can be found in the [codec support documentation](/docs/general/clients/codec-support/).
The following is a list of video codecs Jellyfin supports transcoding to:
- H.264 (Most common transcode target)
- H.265 (Limited support by clients)
- AV1 (New in 10.9, supported by most modern browsers)
- H.264 (most common transcode target)
- H.265 (Jellyfin clients have limited support)
- AV1 (new in Jellyfin v10.9, supported by most modern browsers)
For decoding support, the more codecs the better. However, there are only a few codecs that media is commonly available in. The most important one to look for is HEVC 10bit decoding support, as it can be very demanding on the CPU to decode.
A greater number of codecs is desirable for decoding support. With that said, media is generally available in a small number of codecs. The most important one to look for is HEVC 10bit decoding support, as decoding can be CPU intensive.
#### Intel Graphics
Please refer to [this table](https://en.wikipedia.org/wiki/Intel_Quick_Sync_Video#Hardware_decoding_and_encoding) for supported codecs.
Intel CPUs with a model description that ends with F don't have integrated graphics. These are intended to be used with a dedicated graphics card. Please beware if you intend to use Intel integrated graphics.
Intel CPUs with a model name that ends with `F` do not have integrated graphics. These are intended to be used with a dedicated graphics card, meaning that if you wish to use Intel integrated graphics, this is not an appropriate choice of component for your Jellyfin Server.
If you are planning to use Linux with Intel 12/13th Gen integrated graphics or ARC, these GPUs only work on Linux Kernel 6.2 or newer. Please check your distribution to make sure it has a supported Linux Kernel version. Please read [Known Intel limitations on Linux](/docs/general/administration/hardware-acceleration/known-issues#intel-on-linux) for more info.
If you intend to use Linux with Intel 12/13th gen integrated graphics or ARC, these GPUs only work on Linux Kernel 6.2 or newer. Please check your distribution to make sure it has a supported Linux Kernel version. Further information: [Known Intel limitations on Linux](/docs/general/post-install/transcoding/hardware-acceleration/known-issues#intel-on-linux).
:::caution
Intel 10th gen and older integrated graphics are losing support for QSV on Linux due to the SDK for these platforms being deprecated by Intel. If you own 7-10th gen CPUs with integrated graphics, please continue to use them for Jellyfin. If you are making a purchase decision, please choose a newer CPU if you plan on using Intel integrated graphics.
Intel 10th gen and older integrated graphics are losing support for QSV on Linux due to the SDK for these platforms being deprecated by Intel. If you own 7-10th gen CPUs with integrated graphics, please continue to use them for Jellyfin. If you are making a purchase decision, you may wish to consider a newer CPU if you plan on using Intel integrated graphics.
:::
#### Nvidia Graphics
#### NVIDIA Graphics
Please refer to [this table](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new) for supported codecs.
Certain low end cards (e.g. GT 1030) don't have encoding hardware. Please be careful when choosing a GPU.
Certain low-end cards (e.g. GT 1030) do not have encoding hardware. Please be careful when choosing a GPU.
#### AMD Graphics
AMD graphics is not recommended for Jellyfin, but the information is still provided for convenience. Please refer to [this article](https://en.wikipedia.org/wiki/Video_Coding_Engine) for supported codecs.
AMD graphics is not recommended for Jellyfin, this information is solely provided for reference. Further reading on AMD VCE supported codecs: [https://en.wikipedia.org/wiki/Video_Coding_Engine](https://en.wikipedia.org/wiki/Video_Coding_Engine).
Certain low end cards (e.g. RX 6400, RX 6500) don't have encoding hardware. Please be careful when choosing a GPU.
Certain low-end cards (e.g., RX 6400, RX 6500) do not have encoding hardware. Please be careful when choosing a GPU.
Many AMD CPUs don't have integrated graphics. These are intended to be used with a dedicated graphics card.
Many AMD CPUs do not have integrated graphics. These are intended to be used with a dedicated graphics card.
For Ryzen 1000 ~ 5000 Series, desktop CPUs with a model description that ends with G have integrated graphics while other desktop CPUs do NOT. For Ryzen 7000 Series, desktop CPUs with a model description that ends with F do NOT have integrated graphics while others do.
For Ryzen 1000 - 5000 Series, only desktop CPUs with a model description that ends with `G` have integrated graphics—other Ryzen 1000-5000 desktop CPUs do NOT.
For Ryzen 7000 Series, desktop CPUs with a model description that ends with `F` do NOT have integrated graphics, whereas the rest do.
Please check the product page of your CPU for more info.
@@ -196,17 +203,17 @@ Supported codecs are listed below:
✅ = Encode + Decode, 🔶 = Decode Only, ❌ = Not Supported.
<sup>1</sup> Although the hardware does support AV1 decoding, [ffmpeg does not support it yet](https://trac.ffmpeg.org/ticket/10642).
<sup>1</sup> Although the hardware does support AV1 decoding, [ffmpeg does not yet support it](https://trac.ffmpeg.org/ticket/10642).
:::caution
No Apple Silicon media engine drivers currently exist for non-macOS operating systems. You will NOT be able to use hardware acceleration if you are running [Asahi Linux](https://asahilinux.org/).
No Apple Silicon media engine drivers currently exist for non-macOS operating systems. You will NOT be able to use hardware acceleration if the server is running [Asahi Linux](https://asahilinux.org/).
:::
#### Rockchip VPU
Currently only the VPU on RK3588/3588S SoC is recommended. It can handle most common video codecs, including AV1 decode.
Currently only the VPU on RK3588/3588S SoC is recommended, which can handle most common video codecs, including AV1 decode.
Supported codecs are listed below:
@@ -227,16 +234,18 @@ Supported codecs are listed below:
### Storage
There are two general types of storage that can be used on a Jellyfin server. Media libraries and Jellyfin files require different performance characteristics.
There are two general types of storage that can be used on a Jellyfin Server. Media files and Jellyfin files respectively require specific hardware to optimize performance.
#### Media Storage
Anything with higher sequential access speed than bitrate of media will work. This storage can be a network share or a cloud storage service mounted on the Jellyfin host if desired.
Anything with higher sequential access speed than bitrate of media is acceptable. If desired, this storage may be a network share, or a cloud storage service mounted on the Jellyfin Server host.
#### Jellyfin Files
Jellyfin files will see lots of random access, therefore SSDs are recommended for Jellyfin files. AVOID mechanical drives that use [SMR (Shingled Magnetic Recording)](https://en.wikipedia.org/wiki/Shingled_magnetic_recording) as they will result in a VERY poor experience.
The files for Jellyfin itself (i.e., not your media files) will see a lot of random access, therefore SSDs are recommended for these files. AVOID mechanical drives that use [SMR (Shingled Magnetic Recording)](https://en.wikipedia.org/wiki/Shingled_magnetic_recording) as they will result in a VERY poor experience.
### Networking
Networking is for connecting your Jellyfin server to other devices. It is recommended that the server be connected to the internet via Ethernet cables. Wi-Fi or Powerline solutions are NOT recommended.
Networking is for connecting your Jellyfin server to other devices. It is recommended that the Jellyfin Server be connected to your network via Ethernet cable for optimal performance. Wi-Fi or Powerline solutions for a Jellyfin Server are NOT recommended and will result in an especially poor experience.
Jellyfin Server is not designed to be exposed directly to the internet. Ensure it remains protected behind a properly configured firewall or other secure network environment.
-6
View File
@@ -9,12 +9,6 @@ This page covers migrations of Jellyfin as well as migrations to Jellyfin.
Jellyfins internal databases cannot be copied or adjusted easily. Depending on your case there may be ways to work around this, for example by just migrating parts of the data, or because it's possible maintain the same file paths.
If that's not an option for you, there is also a script available to migrate the entire database without data loss, but it's not a turn-key solution.
## Full Database Migration
[Jellyfin Migrator](https://github.com/MMMZZZZ/Jellyfin-Migrator) is a third-party script that can migrate your entire installation from Windows to Linux or Linux Docker. It can also do other migrations, like a reorganization of your media files. All statistics, settings and metadata are preserved.
## Watched Status Migration
There are third-party scripts available that will use the API to copy watched status and users from one instance to another.
+32 -8
View File
@@ -3,11 +3,13 @@ uid: server-storage
title: Storage
---
## Storage
Jellyfin is designed to directly read media from the filesystem. A network storage device that is using samba or NFS must be directly mounted to the OS. The Jellyfin database should also be stored locally and not on a network storage device.
### NFS
:::caution
There are [scheduled maintenance tasks](/docs/general/server/tasks) which remove items from your library if triggered while your media storage is unavailable.
:::
## NFS
In case you encounter performance issues where files take a long time to start playing while using NFSv3, you might be running in an issue with .NET locking without NFSv3 having locking enabled.
@@ -18,18 +20,40 @@ To solve this, you have the following options:
- Enable the lock service.
- Use NFSv4 which has built-in lock support.
## Docker or VMs
## Docker and VMs
For storage, a moderate size library database can grow anywhere from 10 to 100 GB. The [transcoding](/docs/general/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.
A database for a moderate-sized library can grow anywhere from 10 to 100 GB.
## Cloud
The [transcoding](/docs/general/post-install/transcoding) folder typically requires about the same amount of space as the original media when transcoded at an equivalent bitrate. For example, a single 50 GB Blu-ray remux might consume as much as ~60 GB or as little as ~15 GB after transcoding. If the transcoding folder shares the same storage as the database, this should be accounted for to avoid any problems.
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.
## Cloud Storage Providers
### MergerFS
[rclone](https://rclone.org/downloads/) is a popular choice for integrating cloud storage with a Jellyfin Server. rclone is supported on most operating systems. To combine local and cloud filesystems, rclone can be paired with another program such as [mergerfs](https://github.com/trapexit/mergerfs).
When using cloud storage, it is recommended to disable image extraction as it requires downloading the entire file.
## 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).
To modify and examine your mergerfs mount, here's a quick [guide](https://zackreed.me/mergerfs-neat-tricks).
## Filesystem Considerations
For certain filesystems, optimizations are highly recommended for acceptable performance.
### ZFS
Whilst development is being done on further database providers, in the current implementation of Jellyfin Server, the database uses SQLite. ZFS uses a default record size of `128 K`. This is sub-optimal for the SQLite database.
Ideally, you should use a record size of `4 K` or `8 K` on the dataset that contains your Jellyfin Server SQLite database. This is easily configured when running Jellyfin Server within a Docker container as you are able to easily change bind mounts and can set various datasets for each path as appropriate.
The record size for your media file dataset(s) must not be using `4 K` or `8 K`, otherwise you will likely encounter performance issues as your database scales.
For ZFS datasets containing large media files (i.e., not the dataset containing the Jellyfin Server SQLite database), a record size of `1 M` is likely appropriate for optimal performance.
Note that changing the record size on an existing ZFS dataset will not change the existing data within it, meaning performance will not be any different for anything but newly-written changes into the dataset. As such, it is recommended to rewrite your data into the dataset to take advantage of the change in record size; otherwise, the configuration change will not yield the expected change in performance.
As ZFS snapshots can use a lot of storage over time without a sensible `destroy` schedule, there may be a temptation to keep your data on a mechanical drive instead of an SSD. Do not use ZFS-formatted mechanical drives to store your Jellyfin Server data (everything except your media files), as this will result in poor performance. An SSD is strongly recommended.
+45 -21
View File
@@ -21,7 +21,6 @@ If you created the file with a password, then you will have to enter that value
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.
@@ -48,14 +47,11 @@ To enable debug logging, create the `logging.json` file and add the following co
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"": "Debug"
}
}
"Serilog": {
"MinimumLevel": {
"Default": "Debug"
}
}
}
```
@@ -73,15 +69,15 @@ To restore normal logging, you can remove the override `logging.json` (if you cr
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
}
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
}
}
}
```
@@ -111,8 +107,8 @@ If you are running ArchLinux, run the following command instead:
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.
Then paste it in your terminal and press Enter to run it. For Docker, this needs to be done on the host, not the container.
See the [Guard Listen README on increasing inotify watchers](https://github.com/guard/listen/blob/master/README.md#increasing-the-amount-of-inotify-watchers) for more information.
## Uninstalling Jellyfin on MacOS
@@ -170,7 +166,7 @@ Manual changes to the database can destroy your instance beyond repair. to preve
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:
*You can find a list of default Paths [here](../configuration#configuration-directory)*
You can find a list of default paths in the [configuration directory documentation](/docs/general/administration/configuration#configuration-directory).
```bash
sqlite3 /PATH/TO/JELLYFIN/DB/jellyfin.db
@@ -185,14 +181,14 @@ SELECT Permissions.Value,Permissions.Kind,Users.Username FROM Permissions INNER
```
To just check permissions on your admin account, run the following query:
*Please change `AdminUsername` to the username of your admin account*
_Please change `AdminUsername` to the username of your admin account_
```sql
SELECT Value,Kind FROM Permissions WHERE UserId IN (SELECT Id FROM Users WHERE Username = 'AdminUsername');
```
<br />
The first row with an value of 1 or 0 shows if the permission is assigned or not. The second row displays the kind of permission. To get a summary for every permission you can look [here](https://github.com/jellyfin/jellyfin/blob/master/Jellyfin.Data/Enums/PermissionKind.cs)
The first row with an value of 1 or 0 shows if the permission is assigned or not. For a summary of each permission type, see the [PermissionKind enumeration in the Jellyfin source code](https://github.com/jellyfin/jellyfin/blob/master/src/Jellyfin.Database/Jellyfin.Database.Implementations/Enums/PermissionKind.cs)
### Repair Permissions
@@ -217,3 +213,31 @@ If your active devices section in the dashboard is not showing progress of the c
```bash
timedatectl set-ntp true
```
## Database Locked Errors
When encountering issues with failed scans or inconsistent data, check your log file(s) for errors like "Database Locked". If you encounter those you should first check your parallel scan task limit in your admin dashboard and set that lower. If its set to 0 set it to 1/2 your cores. If that does not help, you can set the locking mode instead (keep the task limit to a reasonable low number too).
You have 3 options to set the locking mode to:
- `NoLock` - This is the default mode which should work for most users
- `Optimistic` - Defines that all writes should be attempted and should be retried when they fail.
- `Pessimistic` - Defines a behavior that always blocks all reads while any one write is done.
Stop your Jellyfin server and navigate to its config directory. There are a lot of xml files, look for the `database.xml` file and edit the `LockingBehavior` option:
```xml
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DatabaseType>Jellyfin-SQLite</DatabaseType>
// highlight-start
<LockingBehavior>Optimistic</LockingBehavior>
// highlight-end
</DatabaseConfigurationOptions>
```
then start your Jellyfin instance again. If this still does not help with the issues, you can try setting the `LockingBehavior` to `Pessimistic` instead but this comes with a significant performance impact so it is only recommended when `Optimistic` does not help with the issues.
### LXC specific issues
It has been brought to the team's attention that there are issues with LXC specifically. If you are getting such errors on LXC after setting lock mode to `Optimistic`, it is recommended that you migrate to full virtualization (virtual machines) or Docker. There is unlikely to be a solution for LXC any time soon, and we will be unable to provide any support for database locked problems on LXC.
+1 -1
View File
@@ -1 +1 @@
position: 7
position: 6
+63 -27
View File
@@ -13,16 +13,16 @@ The goal is to Direct Play all media. This means the container, video, audio and
[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](/docs/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') | ✅ | ✅ | ❌ | 🔶<sup>12</sup>| ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| [H.265 8Bit](https://caniuse.com/#feat=hevc 'HEVC Browser Support Reference') | 🔶<sup>8</sup> | ✅<sup>7</sup> | | 🔶<sup>1</sup> | 🔶<sup>2</sup> | ✅<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | 🔶<sup>9</sup> | ✅ | ✅ |
| [H.265 10Bit](https://caniuse.com/#feat=hevc 'HEVC Browser Support Reference') | 🔶<sup>8</sup> | ✅<sup>7</sup> | | 🔶<sup>1</sup> | 🔶<sup>2</sup> | 🔶<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | 🔶<sup>9</sup> | ✅ | ✅ |
| [VP9](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#VP9 'V9 Browser Support Reference') | ✅ | ✅ | ✅ | ✅<sup>10</sup>| ✅<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>11</sup>| ✅ | 🔶<sup>4</sup> | ❌ | | ✅ | ✅ | ✅ |
| Sorted by efficiency (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 | Jellyfin Media Player |
| ------------------------------------------------------------------------------------------------------------------ | -------------- | -------------- | --------------- | --------------- | -------------- | -------------- | -------------- | --------------- | ------------------------------------------------------------------------------- | ---- | --------------------- |
| [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') | ✅ | ✅ | ❌ | 🔶<sup>12</sup> | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| [H.265 8Bit](https://caniuse.com/#feat=hevc 'HEVC Browser Support Reference') | 🔶<sup>8</sup> | ✅<sup>7</sup> | ✅<sup>15</sup> | 🔶<sup>1</sup> | 🔶<sup>2</sup> | ✅<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | 🔶<sup>9</sup> | ✅ | ✅ |
| [H.265 10Bit](https://caniuse.com/#feat=hevc 'HEVC Browser Support Reference') | 🔶<sup>8</sup> | ✅<sup>7</sup> | ✅<sup>15</sup> | 🔶<sup>1</sup> | 🔶<sup>2</sup> | 🔶<sup>5</sup> | 🔶<sup>1</sup> | ✅<sup>6</sup> | 🔶<sup>9</sup> | ✅ | ✅ |
| [VP9](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#VP9 'V9 Browser Support Reference') | ✅ | ✅ | ✅ | ✅<sup>10</sup> | ✅<sup>3</sup> | 🔶<sup>3</sup> | ❌ | ✅<sup>13</sup> | ✅ | ✅ | ✅ |
| [AV1](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs#AV1 'AV1 Browser Support Reference') | ✅ | ✅ | ✅ | 🔶<sup>11</sup> | ✅ | 🔶<sup>4</sup> | ❌ | 🔶<sup>14</sup> | ✅ | ✅ | ✅ |
<sup>1</sup>HEVC is only supported in MP4, M4V, and MOV containers.
<br />
@@ -30,7 +30,7 @@ The goal is to Direct Play all media. This means the container, video, audio and
<br />
<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.
<br />
<sup>4</sup>Needs atleast Android TV 10.
<sup>4</sup>Needs at least Android TV 10.
<br />
<sup>5</sup>As of <a href="https://github.com/jellyfin/jellyfin-androidtv/pull/671">version 0.12</a>, 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.
<br />
@@ -47,6 +47,12 @@ The goal is to Direct Play all media. This means the container, video, audio and
<sup>11</sup>AV1 decoding is only available on devices with A17 or M3 series chips or newer and requires at least Safari 17.
<br />
<sup>12</sup>Need to be manually enabled in Settings > Playback > Enable H.264 High 10 Profile. Playback on Apple Silicon Macs with macOS version < 14 and Intel Macs with all macOS versions may result in blank frames if this is enabled.
<br />
<sup>13</sup>VP9 is only available with Swiftfin (VLCKit) player.
<br />
<sup>14</sup>AV1 is enabled by default for Swiftfin (VLCKit). AV1 is disabled by default but can be enabled for Native (AVKit) using Custom Device Profiles. Enabling AV1 may result in a poor experience for SOCs prior to A17.
<br />
<sup>15</sup>Requires Firefox 134+ for Windows, 136+ for macOS, and 137+ for Linux. On Windows 11 22H2+ and Windows 10 1507-1709, you can play H.265 (HEVC) video natively. Windows 10 1803+ and Windows 11 21H2 need the [HEVC video extension from Microsoft Store](https://apps.microsoft.com/detail/9nmzlz57r3t7). Linux requires system ffmpeg for support.
[Format Cheatsheet:](https://en.wikipedia.org/wiki/MPEG-4#MPEG-4_Parts)
@@ -60,21 +66,41 @@ The goal is to Direct Play all media. This means the container, video, audio and
<br />
<sup>2</sup><a href="https://en.wikipedia.org/wiki/MPEG-4_Part_17">MPEG-4 Part 17: MP4TT Subtitles</a>
### HDR Support
HDR is only supported on a very limited range of devices:
- iOS Devices with an HDR capable internal display can display HDR content when using a browser or the Jellyfin iOS App (not Swiftfin) as long as the codec is supported by the client. All of them support HEVC and VP9, while AV1 is supported on newer devices. HDR10, Dolby Vision and HLG are supported.
- Android devices running either the official Android App or using Chrome can display HDR content if the device supports HDR and the source format. Format support depends on device.
- Macs running macOS that support HDR can play HDR content when using Safari, Chrome or Firefox on an HDR capable display as long as the source codec is supported. Safari has the most complete support, including HDR10, Dolby Vision (including P5) and HLG. Chrome and Firefox only support HDR10. Chrome supports HDR10 on HEVC, VP9 and AV1. Firefox only supports HDR on VP9 and AV1 content. Please refer to [the list of Macs that support HDR](https://support.apple.com/en-us/102205) to check if your device is supported. On non-Apple displays, other HDR formats will be tone-mapped to HDR10 by the client device.
- Windows PCs with an HDR display with HDR enabled in the settings using Edge or Chrome. Dolby Vision only works in Edge and requires [the Dolby Vision add-on from the Microsoft Store](https://apps.microsoft.com/detail/9pltg1lwphlf) to be installed. Edge generally produces better colors than Chrome when playing HDR content.
- Android TV devices with HDR support running the official Android TV App. HDR format support depends on the specific device you are running.
- WebOS devices (Newer LG Smart TVs) running the official WebOS client supports HDR. However, [mkv containers are known to cause issues](https://github.com/jellyfin/jellyfin-web/issues/4678). Please enable the force remux mkv to mp4 option in the client settings as a workaround.
- Some Chromium-based browsers on Linux will attempt Client-side HDR to SDR tonemapping. This generally looks very bad. There will be no server side involvement when this is happening.
Devices not listed above do not support HDR on any official client. Any HDR content will have to be converted to SDR by the server for proper playback on these clients. For more info, please refer to our [tone-mapping documentation](/docs/general/post-install/transcoding/#hdr-to-sdr-tone-mapping)
## [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> | ✅ | ✅ | ✅ | ✅ |
| ALAC | ❌ | ❌ | ❌ | | ❌ | ❌ | | | | | ✅ |
| Codec | 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> | ✅ | ✅ | ✅ | ✅<sup>8</sup> | ✅ | ❌ | ✅<sup>8</sup> | ✅ | ✅ | ✅ | ✅ |
| DTS<sup>4</sup> | ❌ | ❌ | ❌ | | ✅ | ✅ | | ✅ | ✅<sup>6</sup> | ✅ | ✅ |
| OPUS | ✅ | ✅ | ✅ | <sup>5, 7, 8</sup> | ✅ | ✅ | <sup>5, 7, 8</sup> | ✅ | ✅ | ✅ | ✅ |
| ALAC | ❌ | ❌ | ❌ | | ❌ | ❌ | | | | | ✅ |
[Format Cheatsheet:](https://en.wikipedia.org/wiki/Moving_Picture_Experts_Group#External_links)
@@ -94,6 +120,10 @@ If the audio codec is unsupported or incompatible (such as playing a 5.1 channel
<sup>5</sup>Safari only supports opus in <code>.caf</code> files
<br />
<sup>6</sup>Supported via passthrough on all devices. Native support for AC3 & E-AC3 on Roku TVs & Ultra.
<br />
<sup>7</sup>iOS 17 / macOS 14 and above supports stereo Opus in MP4 containers.
<br />
<sup>8</sup>iOS 18.4 / macOS 15.4 and above supports Vorbis and Opus in OGG containers.
ATSC Standard for [AC-3 and EAC-3](https://www.atsc.org/wp-content/uploads/2015/03/A52-201212-17.pdf).
@@ -103,7 +133,7 @@ Subtitles can be a subtle issue for transcoding. Containers have a limited numbe
Here is a [breakdown](https://www.afterdawn.com/guides/archive/subtitle_formats_explained.cfm) of common subtitle formats.
| | Format | TS | MP4 | MKV | AVI |
| Subtitle Format | 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 | ❌ | ❌ | ✅ | 🔶 |
@@ -165,13 +195,13 @@ Text-based subtitle formats require fonts to render properly. Please refer to [F
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 |
| Container | 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, 6</sup> | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [MKV](https://en.wikipedia.org/wiki/Matroska)<sup>2, 3, 8, 9</sup> | | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| [WebM](https://en.wikipedia.org/wiki/WebM)<sup>3, 5, 6</sup> | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [TS](https://en.wikipedia.org/wiki/MPEG_transport_stream)<sup>4</sup> | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [OGG](https://en.wikipedia.org/wiki/Ogg)<sup>5</sup> | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |
| [OGG](https://en.wikipedia.org/wiki/Ogg)<sup>5, 7</sup> | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |
<sup>1</sup>MP4 containers are one of the few containers that will not remux.
<br />
@@ -184,3 +214,9 @@ If the container is unsupported, this will result in remuxing. The video and aud
<sup>5</sup>WebM and OGG have limited codec support (by design), refer to <a href="https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#WebM">this</a> for WebM and <a href="https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#Ogg">this</a> for OGG.
<br />
<sup>6</sup>WebM on Safari requires at least Safari 14.
<br />
<sup>7</sup>OGG on Safari requires at least iOS 18.4 / macOS 15.4
<br />
<sup>8</sup>MKV support in Firefox is currently disabled in Jellyfin, as there are significant issues making it unusable for Jellyfin. [1](https://bugzilla.mozilla.org/show_bug.cgi?id=2000420) [2](https://bugzilla.mozilla.org/show_bug.cgi?id=1991746)
<br />
<sup>9</sup>MKV on Chrome requires at least Chrome 145.
+21 -16
View File
@@ -5,9 +5,9 @@ title: CSS Customization
# CSS Customization
In `Dashboard > General`, the "Custom CSS" field can be used to override current CSS in Jellyfin's stylesheet.
In `Dashboard > Branding`, 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.
[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 all clients that load Jellyfin-Web from the Server. 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 > Branding > 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.
@@ -28,7 +28,7 @@ Some examples of hex color codes:
- 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.
Use the [HTML Color Picker](https://htmlcolorcodes.com/color-picker) to find the hex 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.
@@ -37,7 +37,7 @@ If you are looking for a more standard and less specific color, typing the liter
`aquamarine` Aquamarine <br />
`lightseagreen` Light Sea Green
Go [here](https://www.w3schools.com/colors/colors_names.asp) for a list of color names supported.
You can find a list of supported color names on the [W3Schools Color Names reference](https://www.w3schools.com/colors/colors_names.asp).
### Comments
@@ -76,6 +76,7 @@ This will affect the played/watched indicator. Replace the hex color with any va
### Green Indicators
```css
/* Make watched icon green */
.playedIndicator {
background: #5dd000;
}
@@ -87,16 +88,20 @@ This will affect the played/watched indicator. Replace the hex color with any va
```css
/* Make watched icon dark and transparent */
.indicator { background: #00000058 !important; }
.playedIndicator {
background: #00000058 !important;
}
```
![Screenshot of watched indicators with a custom transparent color applied](/images/docs/custom-css-transparentwatched.png)
### Transparant count indicators (eg. Series)
### Transparent count indicators (eg. Series)
```css
/* Make count indicator icon dark and transparent */
.countIndicator {background: #00000058;}
.countIndicator {
background: #00000058;
}
```
### Display external links in mobile layout
@@ -386,11 +391,11 @@ The episode previews in season view are sized based on horizontal resolution. Th
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 */
/* Shrink and square (or round) cast thumbnails */
#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 */
/* Correct image aspect ratio behavior, 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;}
@@ -731,19 +736,19 @@ Material Icons:
- Outlined:
```css
@import url("https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Outline.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");
@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");
@import url('https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Sharp.css');
```
Fontawesome Icons:
@@ -751,25 +756,25 @@ Fontawesome Icons:
- Solid:
```css
@import url("https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/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");
@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");
@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");
@import url('https://cdn.jsdelivr.net/gh/prayag17/Jellyfin-Icons/Font%20Awesome/duotone.css');
```
## Community Links
+15
View File
@@ -53,6 +53,21 @@ The final decision for inclusion is at the discretion of the Jellyfin Contributo
- The client must fill a significant void in the current first-party client offerings. Must be a high-quality client on a popular platform.
### Removal from the clients list
We strive to maintain an up-to-date and accurate client list; however, we do not wish to remove clients without just cause. To ensure the integrity and relevance of the client list, we will conduct regular maintenance.
The Jellyfin team reserves the right to remove any listed client at any time.
Typically, a client will be removed if any of the following criteria are met:
- The client no longer fulfills the inclusion criteria outlined above.
- The client is no longer maintained or does not support the latest stable version of the Jellyfin server.
- The client is malfunctioning (key features are not operating correctly).
In general, the team will attempt to contact the maintainers of a listed client prior to removal. However, if this is not feasible (e.g., the maintainers cannot be reached), the team may proceed with removal without prior notice.
Additionally, there are situations where contacting maintainers is unnecessary, such as in cases of malware distribution or violations of community guidelines. In these instances, clients will be removed from the list without notification.
## Supported Browsers
Our goal is to provide support for the two most recent versions of these browsers.
+40 -37
View File
@@ -2,7 +2,9 @@
uid: jellyfin-vue
title: Jellyfin Vue
---
##
import Link from '@docusaurus/Link';
# Jellyfin Vue
[Jellyfin Vue](https://github.com/jellyfin/jellyfin-vue) is an experimental, alternative browser-based web client for Jellyfin written using Vue.js.
@@ -13,15 +15,15 @@ Jellyfin Vue is not planned or targeted to replace the main Jellyfin Web client,
Below are concise instructions to get your own instance of Jellyfin Vue up and running.
If you identify with at least one of the following options:
* Want to try it quickly for the first time
* Are not sure whether you want to deploy your own instance
* Don't need to go beyond user customization to change app-wide behaviour.
* Have a working HTTPS setup.
- Want to try it quickly for the first time
- Are not sure whether you want to deploy your own instance
- Don't need to go beyond user customization to change app-wide behaviour.
- Have a working HTTPS setup.
You're probably better using [our hosted instance](https://jf-vue.pages.dev).
More info at [Jellyfin Vue's repository](https://github.com/jellyfin/jellyfin-vue).
# Deployment
## Deployment
:::caution
Since Jellyfin Vue is just an interface for a Jellyfin server, all of these instructions assume that you already have a server up and running.
@@ -30,12 +32,12 @@ Since Jellyfin Vue is just an interface for a Jellyfin server, all of these inst
## RECOMMENDED: Using Docker
* In case you don't have Docker, follow [the official installation guide](https://docs.docker.com/engine/install) first.
Learning about [Compose](https://docs.docker.com/compose) is also recommended.
* Docker Compose is now shipped with Docker, so you don't need to install it. It's recommended that you uninstall
the old `docker-compose`.
* [`version` key is deprecated](https://docs.docker.com/reference/compose-file/version-and-name/#version-top-level-element-obsolete)
in Docker Compose, hence not included below.
- In case you don't have Docker, follow [the official installation guide](https://docs.docker.com/engine/install) first.
Learning about [Compose](https://docs.docker.com/compose) is also recommended.
- Docker Compose is now shipped with Docker, so you don't need to install it. It's recommended that you uninstall
the old `docker-compose`.
- [`version` key is deprecated](https://docs.docker.com/reference/compose-file/version-and-name/#version-top-level-element-obsolete)
in Docker Compose, hence not included below.
We're going to use the following `docker-compose.yml` as a starting point:
@@ -48,11 +50,11 @@ services:
ports:
- 8080:80
labels:
- "com.centurylinklabs.watchtower.enable=true"
- 'com.centurylinklabs.watchtower.enable=true'
watchtower:
container_name: watchtower
image: ghcr.io/containrrr/watchtower
image: ghcr.io/nicholas-fedor/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
@@ -65,7 +67,7 @@ services:
restart: on-failure
```
<span id="why-updates-needed"></span>
<Link id="why-updates-needed"/>
:::success
Getting things up and running is as easy as doing `docker compose up -d` with your terminal
@@ -74,12 +76,14 @@ located where the `docker-compose.yml` file is.
With this compose file:
* Jellyfin Vue will be accessible on `8080` port of the machine that's running the containers
* Watchtower takes care of updating the container to the latest commit available on the [repository](https://github.com/jellyfin/jellyfin-vue).
This is a good idea because:
* As of now, stable releases don't exist and there have only been prereleases that don't necessarily meet a quality criteria, but
- Jellyfin Vue will be accessible on `8080` port of the machine that's running the containers
- Watchtower (fork, [the original is unmaintained](https://github.com/containrrr/watchtower/issues/2067))
takes care of updating the container to the latest commit available on the
[repository](https://github.com/jellyfin/jellyfin-vue).
This is a good idea because:
- As of now, stable releases don't exist and there have only been prereleases that don't necessarily meet a quality criteria, but
[major development milestones](https://jellyfin.org/posts/vue-vue3/).
* Only the latest `unstable` image is supported.
- Only the latest `unstable` image is supported.
After accessing the instance in your browser of choice, you'll be prompted to add a server. You can use your own server or our demo
instance, located at `https://demo.jellyfin.org/stable`
@@ -112,15 +116,15 @@ to further customize Jellyfin Vue to your liking at Jellyfin Vue's wiki.
Since Jellyfin Vue is an SPA web application, you can use any web server to serve it:
Apache, nginx (the one used in Jellyfin's Vue docker image), Traefik, etc...
If you already have a [reverse proxy](../networking/index.md) set up, do you want to do more complex stuff
If you already have a [reverse proxy](/docs/general/post-install/networking/index.md) set up, do you want to do more complex stuff
that it's out of the scope of this documentation like serving at a subpath, in another subdomain, etc...,
you might want to have Jellyfin Vue served by your own webserver instead of the nginx instance shipped with
the Docker image.
To achieve that, in the `jellyfin_vue` service definition of the [`docker-compose.yml` shown above](#recommended-using-docker):
* Remove the `ports` key.
* Add the following keys, **replacing** `_path_` **with the folder** where your web server expects Jellyfin Vue's assets:
- Remove the `ports` key.
- Add the following keys, **replacing** `_path_` **with the folder** where your web server expects Jellyfin Vue's assets:
```yaml
network_mode: none
@@ -129,14 +133,13 @@ volumes:
# This makes the container do nothing and sleep forever,
# frontend will be copied to _𝘱𝘢𝘵𝘩_ and will be served by your web server
command: /bin/sh -c 'rm -rf /dest/* && cp -r . /dest && sleep infinity'
```
This approach:
* Keeps the client always updated in a hassle-free way, as explained [above](#recommended-using-docker).
* In case you use [environment variables](#using-environment-variables),
they will still be applied.
- Keeps the client always updated in a hassle-free way, as explained [above](#recommended-using-docker).
- In case you use [environment variables](#using-environment-variables),
they will still be applied.
## Manually
@@ -168,17 +171,17 @@ They might compromise your system or track your activity!
Since Jellyfin Vue is a web application, using it it's a matter of setting up your own web server
and pointing it to Jellyfin Vue's assets. You can get them:
* By building your own version from our source. The repository's [wiki](https://github.com/jellyfin/jellyfin-vue/wiki)
has instructions for setting up the development environment.
* By getting them from [GitHub's Actions artifacts](https://github.com/jellyfin/jellyfin-vue/actions).
* Although those artifacts are built in our repository's CI/CD,
**some runs are sourced from Pull Requests created by external contributors that might not be good actors!**
* All artifacts generated by GitHub Actions are [built with provenances](https://github.com/jellyfin/jellyfin-vue/attestations).
* Our official Docker image is built from GitHub Actions and all the process is transparent and can be audited.
- By building your own version from our source. The repository's [wiki](https://github.com/jellyfin/jellyfin-vue/wiki)
has instructions for setting up the development environment.
- By getting them from [GitHub's Actions artifacts](https://github.com/jellyfin/jellyfin-vue/actions).
- Although those artifacts are built in our repository's CI/CD,
**some runs are sourced from Pull Requests created by external contributors that might not be good actors!**
- All artifacts generated by GitHub Actions are [built with provenances](https://github.com/jellyfin/jellyfin-vue/attestations).
- Our official Docker image is built from GitHub Actions and all the process is transparent and can be audited.
## Other documentation
* The rest of the documentation about Jellyfin Vue can be found on it's [wiki](https://github.com/jellyfin/jellyfin-vue/wiki).
- The rest of the documentation about Jellyfin Vue can be found on it's [wiki](https://github.com/jellyfin/jellyfin-vue/wiki).
* You can check [GitHub Packages (GHCR)](https://github.com/jellyfin/jellyfin-vue/pkgs/container/jellyfin-vue) (recommended)
or [DockerHub](https://hub.docker.com/r/jellyfin/jellyfin-vue) for all the tagged Docker images.
- You can check [GitHub Packages (GHCR)](https://github.com/jellyfin/jellyfin-vue/pkgs/container/jellyfin-vue) (recommended)
or [DockerHub](https://hub.docker.com/r/jellyfin/jellyfin-vue) for all the tagged Docker images.
+6 -36
View File
@@ -20,7 +20,7 @@ The installation method for the repository varies depending on what kind of devi
#### General Use Devices (PCs and Tablets)
1. Download the repository installer found [here](https://kodi.jellyfin.org/repository.jellyfin.kodi.zip).
1. Download the repository installer from the [Jellyfin Kodi repository ZIP file](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"
@@ -28,7 +28,7 @@ The installation method for the repository varies depending on what kind of devi
- 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)
#### "Embedded" Devices (Android TV, FireTV Stick, and other TV Boxes)
1. Open Kodi, go to the settings menu, and navigate to "File manager"
- Select "Add source"
@@ -91,40 +91,9 @@ To use Add-on mode, simply choose "Add-on" at the dialog and proceed to [Library
#### Native Mode
:::caution
Do not use Native mode! Use Addon-mode instead.
Jellyfin 10.10 no longer provides the shared network folder via the API, and as such native mode does not get the required information to function.
:::
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.
:::caution
Starting from Jellyfin 10.9 it is no longer possible to set the shared network folder.
:::
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
1. 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"
@@ -134,7 +103,8 @@ Starting from Jellyfin 10.9 it is no longer possible to set the shared network f
- 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](/docs/general/clients/kodi#library-syncing)
2. Proceed to [Library Syncing](/docs/general/clients/kodi#library-syncing)
3. Make sure to set up path replacements to rewrite paths on your Jellyfin server to the correct paths on your network share
#### Library Syncing
@@ -179,7 +149,7 @@ JellyCon behaves more like a standard Kodi streaming add-on. Media is accessed p
### 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.
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 a barebones introduction to customizing a skin.
#### Examples
+1 -1
View File
@@ -9,7 +9,7 @@ title: Jellyfin Web Configuration
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.8.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.
We recommend obtaining the [stable](https://github.com/jellyfin/jellyfin-web/blob/release-10.10.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
@@ -1 +1,2 @@
label: Community Standards
position: 101
+1
View File
@@ -0,0 +1 @@
position: 200
+13 -11
View File
@@ -7,26 +7,28 @@ title: Branding
## Usage of the Jellyfin name
You are free to use the Jellyfin name to promote your project, with some restrictions:
The name "Jellyfin" is reserved for the Jellyfin project itself and its official clients. The server (including WebUI) is called "Jellyfin", composed of the "Jellyfin [API] Server" and "Jellyfin Web[UI]". Official clients are, generally, called "Jellyfin for X", where "X" is a platform (e.g. "Jellyfin for Android TV").
- 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.
3rd party developers should **not** use the name Jellyfin directly. Additionally, we **discourage** projects from using the combination of "Jelly[word]" or "[word]fin" to avoid confusion; while there are numerous exceptions over the years, we strongly request that you develop your own unique name for your project. You **may** reference Jellyfin in a subtitle, description, etc. as an indication of interoperability. For example, "Floostream, a Jellyfin client" is ideal.
Do not use the Jellyfin name in the promotion of piracy or to affiliate yourself erroneously with the project or impersonate the project. If you run a public server (which, by default, will use Jellyfin branding), please see [our server policy](/docs/general/community-standards/servers).
## Usage of the Jellyfin logo
Do **not** use the Jellyfin logo as your logo for any project, service, or group without the expressed permission of the Jellyfin team, i.e. the rounded-triangle-within-a-triangle shape. Do not simply rotate the logo shape, or include it inside of another logo; these count too. To help facilitate a common design language even among 3rd party clients, we **do permit** the use of our colour gradient on your logo; we simply request that you use a unique logo design/shape.
Do not use the Jellyfin logo in the promotion of piracy or to affiliate yourself erroneously with the project or impersonate the project.
## Writing Style
As a general rule, Jellyfin should always be capitalized, but language, file, or system conventions trump Jellyfin naming conventions.
As a general rule, Jellyfin should always be capitalized, but language, file, or system conventions trump Jellyfin naming conventions. Avoid "JellyFin".
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`
- Code elements should be formatted according to the specifications of the language in use.
- Git repositories and files using the name should use lowercase `jellyfin` for convenience on case-sensitive filesystems. `build-jellyfin.ps1`, `jellyfin_3.5.2-1_all.deb`, etc.
- 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
+13 -2
View File
@@ -12,13 +12,17 @@ This page details how our repositories are organized, how to get started editing
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 8 and C#.
- [Jellyfin Server](https://github.com/jellyfin/jellyfin): The server portion, built using .NET 9 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](/docs/general/contributing/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.
### Feature Proposals
New features or substantial changes to existing behavior affecting multiple sub-projects should first be proposed as a [Jellyfin Meta discussion](https://github.com/jellyfin/jellyfin-meta/discussions).
### Major Issue Types
A list of issue types can be found on the [issue guidelines](/docs/general/contributing/issues#issue-labels) section.
@@ -58,7 +62,14 @@ The first step is to set up a copy of the Git repository of the project you want
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.
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 can set this path in your project by modifying the **environmentVariables** in the `Jellyfin.Server/Properties/launchSettings.json` file:
```json
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"JELLYFIN_WEB_DIR": "/path/to/your/jellyfin-web/dist"
}
```
You will now be ready to begin building or modifying the project.
@@ -0,0 +1,54 @@
---
uid: donate-directly
title: Donations to individual developers
---
import Link from '@docusaurus/Link';
import { donations } from '../../../src/data/donations';
Jellyfin is free and will always be free. We do not accept any money or benefit for any form of favor or feature and no implicit or explicit entitlement should be assumed or demanded when donating to Jellyfin or one of its developers.
That said the many developers or moderators accept donations purely as a sign of gratitude for their volunteer work on the project or officially related.
This table is not conclusive and if you are missing a specific person you want to donate to, please contact the developer directly.
This list is also intentionally randomly ordered to avoid any appearance of favoring any one developer.
<Link to={donations.sort(() => Math.random() - 0.5)[0].links[0].url}>Pick for me, just somebody.</Link>
<table>
<thead>
<th>Username</th>
<th>Role</th>
<th>Donation Links</th>
</thead>
<tbody>
{donations
.sort(() => Math.random() - 0.5)
.map((element) => (
<tr>
<td>{element.title}</td>
<td>
<ul>
{element.roles.map((role) => (
<li>{role}</li>
))}
</ul>
</td>
<td>
<ul>
{element.links.map((link) => (
<li>
<Link to={link.url}>{link.name}</Link>
</li>
))}
</ul>
</td>
</tr>
))}
</tbody>
</table>
The rules for inclusion into this lists are being a currently active member of the Jellyfin Team and having shown a long term commitment towards the project as a whole.
This can mean either significant contributions to the Jellyfin Server project, any officially recognised Clients or a Jellyfin-Labs project; or existing long commitments towards official moderation efforts as an community moderator in our chat or forum.
As with all official associations with the Jellyfin project, the Core team has the final say on any decision regarding modifications to this list.
@@ -0,0 +1,30 @@
---
uid: documentation
title: Contributing to Documentation
---
# Contributing to Documentation
## What to change and Why
Documentation is fast-moving and ever-changing. Please think carefully about what you're changing and why; what will it contribute going forward? Extensive rewrites and new pages should be considered very carefully and coordinated in our [documentation Matrix room](/contact).
## Please Self-Review
Before finalizing your changes, please be courteous to reviewers and run your changes through, at least, a spellchecker (e.g. `apsell`) and potentially a grammar checker. AI is fine for this though please use it sparingly for _generating_ content. Make sure you re-read what comes out and adjust as required. We appreciate individual writing styles but the bulk of our review back-and-forth is over minor issues like this, so please do your part to get it right first.
## Peer Copyediting
For very large changes, we encourage the idea of peer copyediting. Instead of submitting a massive PR and then having back-and-forth line-by-line editing in there, we suggest placing your new/updated doc in a collaborative document editor such as [HackMD](https://hackmd.io) and sharing it in our [documentation Matrix room](/contact). You can then, between chat and the collaborative editor, obtain a line-by-line copyedit for spelling, grammar, and formatting, without back-and-forth in the PR. Once both sides are happy with the changes, a pull request can then be submitted.
While this does seem like "more work", for substantial changes this should ideally be a small part of the entire process, and will help ensure that final reviews go more smoothly.
## Peer Reviews
Due to the volume of pull requests to our documentation repo and the varying sizes of them, some pull requests will take a long time to review, and potentially languish as a result.
Before (or, immediately after) submitting a PR for review, we ask you to find another PR from another person, ideally one which is not already peer- or team-reviewed, and perform a thorough readthrough of the changes. Make sure they make sense to you, that the copyediting is good, and provide a GitHub review of it. If necessary please point out any change suggestions. This will help go a long way to helping your PR be reviewed, as the next contributor can review your PR in turn.
## Blog Posts
Blog posts are exclusively written by our team members; we do not accept outside blog posts under any circumstances. Blog posts should follow all the above processes, and further require final approval from the Core team in addition to regular documentation approvers. Blog posts may stay in draft or review status for some time, until the event they correlate with (e.g. a release); the date should always reflect the final (expected) publishing date.
+1 -1
View File
@@ -23,7 +23,7 @@ For general guidelines on how the project works, including how to set up your de
## Adding To Documentation
Documentation is incredibly helpful! All these docs are written using [Docusaurus](https://docusaurus.io/docs/markdown-features). You can find the raw markdown in the [documentation repository](https://github.com/jellyfin/jellyfin.org). Pull requests are welcome!
Documentation is incredibly helpful! All these docs are written using [Docusaurus](https://docusaurus.io/docs/markdown-features). You can find the raw markdown in the [documentation repository](https://github.com/jellyfin/jellyfin.org). Pull requests are welcome, though please review our [documentation process](/docs/general/contributing/documentation) first!
## Translating
+1 -1
View File
@@ -43,7 +43,7 @@ When writing a bug issue, please ensure you capture as much relevant detail as p
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)](/docs/general/contributing/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 should not 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.
Bugs should be reproducible. That is, you should be able to have determined through troubleshooting how to replicate the issue. While one-time bugs should not 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](/docs/general/getting-help) and we'll try to help you out!
+49
View File
@@ -0,0 +1,49 @@
---
uid: llm-policies
title: LLM/"AI" Policies
---
# Jellyfin LLM/"AI" Development Policy
The rise of LLMs as a useful development tool over the last year or so has been significant. The power and flexibility of tools like Claude Code and ChatGPT have given a lot of functionality both to experienced developers and new developers alike. But there are trade-offs.
The Jellyfin project has, from day one, had a major focus on code quality - readability, simplicity, conciseness. This is a mostly manual effort driven by a dedicated team of individuals, and is motivated by a desire to fix the code Jellyfin is based off of which, without beating a dead horse too much, was extremely fragile, spaghettified, and prone to over-engineered complexity.
We are seeing a precipitous rise in contributors using AI within the Jellyfin ecosystem, both in the server and for clients, as well as a rise in criticism and concern about LLMs generally. At this time we are writing this policy to address exactly what we expect and desire with respect to contributions and interactions within our community that may use LLMs. These rules apply to all of our official projects and community spaces.
## General Guidelines
1. LLM output is **expressly prohibited** for any direct communication, including the following:
* issues or comments
* feature requests or comments
* pull request bodies or comments
* forum/chat/etc. posts or comments
In short, if you are posting **any** of those things, the output must be your own words, explanation, description, etc., not a verbatim dump of an LLM's output. We expect you to understand what you're posting. Violating this rule will result in closure/deletion of the offending item(s).
An exception will be made for **LLM-assisted translations** if you are having trouble accurately conveying your intent in English. Please explicitly note this ("I have translated this from MyLanguage with an LLM") and, if possible, post in your original language as well.
2. LLM code contributions are subject to more granularity below, but the general principle is that "pure 'vibe coding' will be rejected" and "you are responsible for what you commit". We will review in that vein. If the **code looks terrible**, it will be **rejected as such**.
## LLM Code Contributions to Official Projects
The use of LLMs for code is controversial and open to much interpretation. These guidelines are our best effort attempt to ensure that knowledgeable developers who seek to use these tools as a legitimate aid are not overly-hindered, while also preventing an ongoing flood of slop contributions that violate our core ethos above. These apply to **all official Jellyfin projects**.
1. Contributions should be **concise and focused**. If the PR claims to target X, and is also touching unrelated Y and Z, it will be rejected. This includes incidental changes to unrelated functionality, a hallmark of poorly-worded or too-general prompts. Similarly, a large PR must be **broken into multiple small, manageable commits** for review and history purposes.
2. Formatting and quality **standards must be upheld**. Excessive unhelpful comments, spaghetti code, spaces on empty lines, etc. will be interpreted as pure LLM output and rejected; you must **clean up the mess** before submitting. Also **do not commit LLM metafiles** (e.g. `.claude` configs) or any other editor-created non-code files.
3. You must **review the output** and be able to **explain** in the PR body - **without** LLM output as noted above - **what is being changed and why**. Your PR body (and, if applicable, commit bodies) should be providing context to other developers about why a change was made, and if your name is on it, we want **your** words and explanations, not an LLM's. If **you can't explain** what the LLM did, we are **not interested** in the change.
4. The changes must be **tested**. The code should build and run correctly, or it will be rejected. You should also **explicitly test the functionality being modified**.
5. You must be able and willing to **handle review feedback** and implement the suggested change(s) as required. What this means in practice is, if you do not know what has been changed or why (see #3), and thus can't implement suggested changes or discuss them **yourself**, then we are **not interested** in the change. Just dumping reviewer feedback into an LLM and expecting what comes out to be "good enough", is not.
6. **Features or refactors** require **an in-depth level of understanding** about what is being changed and why. It is obvious to our reviewers when changes are made without the developer making them understanding what is happening. These will be rejected. And as noted in #1, the PR must **contain multiple discrete commits**. _We_ will squash commits as deemed appropriate after review. Large changes must also follow our other development policies (discussion, review, implementation, testing process).
7. The **final discretion always lies with the reviewers**. If your PR is not capable of being reasonably reviewed, for any reason (over-complexity, size, squashed commits, etc.) it will be rejected, and this goes just as much for non-LLM-assisted PRs as it does for LLM-assisted PRs. You will be asked to split such a PR up into multiple PRs that each present a focused, concise set of changes instead.
The golden rule is this: **do not just let an LLM loose on the codebase with a vague vibe prompt and then commit the results as-is**. This is lazy development, will **always** result in a **poor-quality contribution** from our perspective, and we are not at all interested in such slop. **Make an effort** or please do not bother. And again, you are free to use LLMs to **assist** you, but not as the sole source of code changes.
## LLM-generated Tools, Clients, etc. Shared in the Community
You are of course free to do whatever you wish for your own non-official projects. However, we will be enforcing the following rules for any **sharing of such projects within our communities**.
1. Any primarily-LLM-developed projects should be **clearly marked as such**. It is up to users to decide if this is acceptable to them or not. If you used an LLM for secondary assistance (e.g. docs, formatting, etc.) in an obvious way, we would err towards disclosure as well.
2. You **must** respect and follow licenses. If you are basing your project off of existing code, **following its license is not optional**. You must **credit existing contributors in full** for **all contributions**. Do not **mangle the Git history**, and do not **commit pending 3rd party changes as your own** (i.e. by copying the code and then committing it). Doing so will result in, not just rejection, but a ban from our organization and community. We have a **zero tolerance policy** for code theft and bad-faith attribution attempts.
3. For members of the community, **do not report** LLM-generated tools, clients, etc. **on that basis alone**, and do not engage in anti-LLM "witch hunts". As mentioned above, this is **permitted** and it is your choice whether to "support" said tool/client/etc. or not.
4. We, the moderators, are not going to play "LLM police" about 3rd party projects by nitpicking to try to "find LLM contributions" that otherwise follow our rules here; this is tedious and a waste of our time and effort. What this means in practice is that rule #1 is up to the author, and rule #3 must be interpreted in that vein. If you **only suspect** a tool is LLM-generated and violates rule #1, then downvote/ignore it and move on. **Only if** we see **blatant breaking of rule #1** we will enforce it, but again we will not be going through code line by line playing the "was this LLM generated?" game. Rule #2 will always be enforced regardless of LLM-ness or not.
+3 -3
View File
@@ -10,7 +10,7 @@ Jellyfin is a maze of clients, plugins, and other useful projects. These source
## [Jellyfin Server](https://github.com/jellyfin/jellyfin)
1. .ci: `Azure Pipelines Build definitions`
2. DvdLib: `DVD Anaylzer`
2. DvdLib: `DVD Analyzer`
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`
@@ -25,7 +25,7 @@ Jellyfin is a maze of clients, plugins, and other useful projects. These source
- 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`
12. Jellyfin.Networking: `managing network interfaces 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`
@@ -37,7 +37,7 @@ Jellyfin is a maze of clients, plugins, and other useful projects. These source
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`
24. deployment: `files used while building Jellyfin for different platforms`
25. tests: `multiple Unit Test projects testing Jellyfin functionality`
26. Dockerfile.* `Dockerfiles defining the Jellyfin Docker image`
+3 -3
View File
@@ -1,7 +1,7 @@
---
uid: faq
title: FAQ
sidebar_position: 2
sidebar_position: 102
---
# Frequently Asked Questions
@@ -33,7 +33,7 @@ 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](/docs/general/server/media/movies), [Shows](/docs/general/server/media/shows), [Music](/docs/general/server/media/music), and others.)
If it's not one of these, please consider asking for help as it might be a bug.
If it's not one of these, please consider asking for help as it might be a bug.
## How can I contribute to this project?
@@ -48,4 +48,4 @@ Please see our [requesting features](/docs/general/contributing/issues#requestin
All we can ask is you [use Jellyfin](/docs/general/installation), [report any bugs](/docs/general/contributing/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.
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. Many individual developers that are active in the project accept [donations](/docs/general/contributing/direct-donations.mdx) however.
+1 -1
View File
@@ -1,7 +1,7 @@
---
uid: getting-help
title: Getting Help
sidebar_position: 1
sidebar_position: 0
---
# Getting Help
+1 -1
View File
@@ -1,2 +1,2 @@
label: 'Installation'
position: 3
position: 2
@@ -0,0 +1,88 @@
<!-- markdownlint-disable MD041 -->
[Docker](https://www.docker.com/) allows you to run containers on Linux, Windows and MacOS.
:::warning
If you wish to use Windows or macOS, please install Jellyfin natively instead. [Windows](/docs/general/installation/windows) [macOS](/docs/general/installation/macos).
While it is possible to run Jellyfin in Docker on a Windows or macOS host, it is NOT supported. Some features are known to be broken when running in Docker on platforms other than Linux, Notably:
- Hardware Accelerated Transcoding
- [Scanning on macOS in Docker](https://github.com/jellyfin/jellyfin/issues/13093)
You WILL NOT receive any support for running Jellyfin in Docker on platforms other than Linux.
:::
The basic steps to create and run a Jellyfin container using Docker are as follows.
1. Follow the [official 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 \
-p 8096:8096/tcp \
-p 7359:7359/udp \
--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
```
Custom [server-side system fonts](/docs/general/administration/configuration/#server-side-system-fonts) directory can be optionally bind mounted in order to use these fonts during transcoding with subtitle burn-in:
```sh
--mount type=bind,source=/path/to/fonts,target=/usr/local/share/fonts/custom,readonly
```
A directory of [fallback fonts](/docs/general/administration/configuration/#fallback-fonts) can be mounted as well. In this case, you will have to set the directory of fallback fonts to `/fallback_fonts` in Jellyfin server settings panel:
```sh
--mount type=bind,source=/path/to/fallback/fonts,target=/fallback_fonts,readonly
```
@@ -0,0 +1,60 @@
<!-- markdownlint-disable MD041 -->
:::warning
If you wish to use Windows or macOS, please install Jellyfin natively instead. [Windows](/docs/general/installation/windows) [macOS](/docs/general/installation/macos).
While it is possible to run Jellyfin in Docker on a Windows or macOS host, it is NOT supported. Some features are known to be broken when running in Docker on platforms other than Linux, Notably:
- Hardware Accelerated Transcoding
- [Scanning on macOS in Docker](https://github.com/jellyfin/jellyfin/issues/13093)
You WILL NOT receive any support for running Jellyfin in Docker on platforms other than Linux.
:::
Create a `docker-compose.yml` file like the following.
```yml
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
# Optional - specify the uid and gid you would like Jellyfin to use instead of root
user: uid:gid
ports:
- 8096:8096/tcp
- 7359:7359/udp
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
- type: bind
source: /path/to/media
target: /media
- type: bind
source: /path/to/media2
target: /media2
read_only: true
# Optional - extra fonts to be used during transcoding with subtitle burn-in
- type: bind
source: /path/to/fonts
target: /usr/local/share/fonts/custom
read_only: true
restart: 'unless-stopped'
# Optional - alternative address used for autodiscovery
environment:
- JELLYFIN_PublishedServerUrl=http://example.com
# Optional - may be necessary for docker healthcheck to pass if running in host network mode
extra_hosts:
- 'host.docker.internal:host-gateway'
```
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/).
@@ -0,0 +1,182 @@
<!-- markdownlint-disable MD041 -->
[Podman](https://podman.io) allows you to run rootless containers.
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 \
--publish 7359:7359/udp \
--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,relabel=private \
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. Additionally port 7359 UDP needs to be opened for auto discovery.
```sh
sudo firewall-cmd --add-port=8096/tcp --permanent
sudo firewall-cmd --add-port=7359/udp --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`, and a [backup](/docs/general/administration/backup-and-restore) will be required to restore a previous version.
The `z` (shared volume) or `Z` (private volume) volume option and `relabel=shared` or `relabel=private` mount option tell 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.
<details>
<summary>Managing via systemd</summary>
To run as a systemd service see [podman-systemd.unit](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
As always it is recommended to run the container rootless. Therefore we want to manage the container with the `systemd --user` flag.
1. Create a new user that the rootless container will run under.
`useradd jellyfin`
This allows users who are not logged in to run long-running services.
`loginctl enable-linger jellyfin`
Open an interactive shell session.
`machinectl shell jellyfin@`
2. Install `.config/containers/systemd/jellyfin.container`
> Contents of `~/.config/containers/systemd/jellyfin.container`
```ini
[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
PublishPort=8096:8096/tcp
UserNS=keep-id
Volume=jellyfin-config:/config:Z
Volume=jellyfin-cache:/cache:Z
Volume=jellyfin-media:/media:Z
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target
```
3. Reload daemon and start the service.
`systemctl --user daemon-reload`
`systemctl --user start jellyfin`
4. To enable Podman auto-updates, enable the necessary systemd timer.
`systemctl --user enable --now podman-auto-update.timer`
5. Optionally check logs for errors
`journalctl --user -u jellyfin`
6. `exit` the current session.
</details>
<details>
<summary>Using hardware acceleration</summary>
To use hardware acceleration, you need to allow the container to access the render device. If you are using container-selinux-2.226 or later, you have to set the `container_use_dri_devices` flag in selinux or the container will not be able to use it:
`sudo setsebool -P container_use_dri_devices 1`
On older versions of container-selinux, you have to disable the selinux confinement for the container by adding `--security-opt label=disable` to the podman command.
Then, you need to mount the render device inside the container:
`--device /dev/dri/:/dev/dri/`
Finally, you need to set the `--device` flag for the container to use the render device:
`--device /dev/dri/`
Podman run example:
```sh
podman run \
--detach \
--label "io.containers.autoupdate=registry" \
--name myjellyfin \
--publish 8096:8096/tcp \
--device /dev/dri/:/dev/dri/ \
# --security-opt label=disable # Only needed for older versions of container-selinux < 2.226
--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,relabel=private \
docker.io/jellyfin/jellyfin:latest
```
systemd example:
```ini
[Unit]
Description=jellyfin
[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
PublishPort=8096:8096/tcp
UserNS=keep-id
#SecurityLabelDisable=true # Only needed for older versions of container-selinux < 2.226
AddDevice=/dev/dri/:/dev/dri/
Volume=jellyfin-config:/config:Z
Volume=jellyfin-cache:/cache:Z
Volume=jellyfin-media:/media:Z
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target
```
</details>
<details>
<summary>Vendor-specific configuration</summary>
Additional configuration steps may be required depending on your GPU vendor. Check the [Hardware Acceleration](/docs/general/post-install/transcoding/hardware-acceleration) section.
</details>
@@ -0,0 +1,2 @@
label: 'Advanced Installation'
position: 6
@@ -0,0 +1,141 @@
---
uid: installation-advanced-community
title: Community Maintained Packages
description: Community maintained packages.
sidebar_position: 1
---
# Community Maintained Packages
These packages are maintained by community packagers independent of Jellyfin for distributions not officially supported by Jellyfin. We can't always support problems with community-maintained packages. If you encounter trouble with them, please contact their maintainers first. If you're not sure, we recommend using [container images](/docs/general/installation/container) on these systems instead.
## Alpine Linux
Jellyfin can be found in the `community` repository as
[`jellyfin`](https://pkgs.alpinelinux.org/package/edge/community/x86_64/jellyfin) and
[`jellyfin-web`](https://pkgs.alpinelinux.org/package/edge/community/x86_64/jellyfin-web).
To enable the web UI after installing `jellyfin-web`, make sure to remove the `--nowebclient` option from
`/etc/conf.d/jellyfin`.
## Arch Linux
The `Extra` repository contains builds for both [`jellyfin-server`](https://archlinux.org/packages/?name=jellyfin-server) and [`jellyfin-web`](https://archlinux.org/packages/?name=jellyfin-web).
`jellyfin-server` includes a hard dependency on [`jellyfin-ffmpeg`](https://archlinux.org/packages/?name=jellyfin-ffmpeg).
Both packages, server and web, can also be built from source at the tip of the master branch using [`jellyfin-git`](https://aur.archlinux.org/packages/jellyfin-git/).
The AUR also offers each separately at [`jellyfin-server-git`](https://aur.archlinux.org/packages/jellyfin-server-git/) and [`jellyfin-web-git`](https://aur.archlinux.org/packages/jellyfin-web-git/).
## Fedora, CentOS and other RPM distributions
Builds in RPM package format are provided by RPM Fusion. Official packages are no longer provided starting with 10.9.
### RPM Fusion
1. `rpmfusion` must be enabled first
```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
```
2. Install the `jellyfin` package, which will automatically install `jellyfin-server`, `jellyfin-web` and `jellyfin-firewalld`
```sh
sudo dnf install jellyfin
```
3. Enable and start the Jellyfin service:
```sh
sudo systemctl enable --now jellyfin
```
### Manual installation via the .rpm packages
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 server `.rpm` file URL>
```
3. Install the Jellyfin web interface
```sh
sudo dnf install <link to web `.rpm` file URL>
```
4. Enable and start the Jellyfin service:
```sh
sudo systemctl enable --now jellyfin
```
5. Allow Jellyfin through the firewall:
```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. Reload the firewall to apply the new rules:
```sh
sudo firewall-cmd --reload
```
7. Go to `localhost:8096` or `ip-address-of-jellyfin-server:8096` to finish setup in the web UI.
## Gentoo
The Gentoo ebuild repository includes the Jellyfin package which can be installed like other software:
```sh
emerge --ask www-apps/jellyfin-bin
```
For more information, refer to the [Gentoo wiki](https://wiki.gentoo.org/wiki/Jellyfin).
## NixOS
NixOS has a [module for Jellyfin](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/jellyfin.nix),
it can be enabled as follows:
```nix
{
services.jellyfin.enable = true;
}
```
For more information, refer to the [NixOS wiki](https://wiki.nixos.org/wiki/Jellyfin).
## Flatpak
The Jellyfin Server package is available on [Flathub](https://flathub.org/apps/org.jellyfin.JellyfinServer).
This package is provided for convenience only, and may be deprecated at any time. It is not recommended as [Flatpak themselves don't recommend the use of Flatpak for server applications](https://flatpak.org/faq/#Can_Flatpak_be_used_on_servers_too_). Please use [container images](/docs/general/installation/container) instead.
## FreeBSD
A [Third-party Jellyfin build for FreeBSD](https://github.com/Thefrank/jellyfin-server-freebsd) is available. This is not supported by Jellyfin. Please report any issues to them. Issues reported to Jellyfin about this package will be closed without further investigation.
@@ -0,0 +1,307 @@
---
uid: installation-advanced-kubernetes
title: Kubernetes Deployment
description: Deploy Jellyfin on Kubernetes using Helm
sidebar_position: 7
---
# Kubernetes Deployment
This guide covers deploying Jellyfin on Kubernetes using the [official Helm chart](https://github.com/jellyfin/jellyfin-helm/tree/master/charts/jellyfin).
## Prerequisites
- Kubernetes cluster (v1.19+)
- Helm 3.x installed
- `kubectl` configured for your cluster
- Sufficient storage for media and configuration
- Ingress controller (e.g. traefik) for external access (required for this tutorial, see [official docs](https://github.com/jellyfin/jellyfin-helm/tree/master/charts/jellyfin) for alternatives)
## Installation
### 1. Add Helm Repository
```bash
helm repo add jellyfin https://jellyfin.github.io/jellyfin-helm
helm repo update
```
### 2. Custom Installation
For complete installation instructions and configuration options, see the [official Jellyfin Helm chart repository](https://github.com/jellyfin/jellyfin-helm/tree/master/charts/jellyfin).
Create a `values.yaml` file for customization:
```yaml
# values.yaml
replicaCount: 1
image:
pullPolicy: IfNotPresent
persistence:
config:
enabled: true
size: 5Gi
storageClass: ''
media:
enabled: true
size: 100Gi
storageClass: ''
ingress:
enabled: true
className: 'traefik'
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
nodeSelector: {}
tolerations: []
affinity: {}
```
Install with custom values:
```bash
helm install jellyfin jellyfin/jellyfin -f values.yaml
```
## Configuration Options
### Service Types
This guide covers ClusterIP service type (default) for internal access only, with external access via ingress controller. Alternatives include LoadBalancer and NodePort services.
### Persistence
#### Using Existing Persistent Volume Claims
```yaml
persistence:
config:
enabled: true
existingClaim: 'jellyfin-config-pvc'
media:
enabled: true
existingClaim: 'jellyfin-media-pvc'
```
#### Creating New PVCs via Helm
```yaml
persistence:
config:
enabled: true
size: 5Gi
storageClass: 'fast-ssd'
media:
enabled: true
size: 100Gi
storageClass: 'slow-hdd'
```
### Ingress
#### Basic Ingress Configuration
```yaml
ingress:
enabled: true
className: 'traefik'
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
```
#### Advanced Ingress with TLS
```yaml
ingress:
enabled: true
className: 'traefik'
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: default-jellyfin-buffering@kubernetescrd
hosts:
- host: jellyfin.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: jellyfin-tls
hosts:
- jellyfin.example.com
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: jellyfin-buffering
namespace: default
spec:
buffering:
maxRequestBodyBytes: 0
```
## Accessing Jellyfin
### Port Forwarding (Development)
```bash
kubectl port-forward svc/jellyfin 8096:8096
```
Access at: `http://localhost:8096`
### External Access
Once ingress is configured, access Jellyfin at your configured domain (e.g., `https://jellyfin.example.com`).
## Monitoring
### Health Checks
The chart includes readiness and liveness probes:
```yaml
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5
```
### Metrics
Enable Prometheus metrics if available:
```yaml
metrics:
enabled: true
serviceMonitor:
enabled: true
```
## Troubleshooting
### Common Issues
1. **Permission Denied**: Ensure proper security context for media access
2. **Storage Issues**: Verify persistent volume claims are bound
3. **Network Access**: Check service type and ingress configuration
### Debug Commands
```bash
# Check pod status
kubectl get pods -l app.kubernetes.io/name=jellyfin
# View logs
kubectl logs -f deployment/jellyfin
# Check service
kubectl get svc jellyfin
# Describe pod for events
kubectl describe pod -l app.kubernetes.io/name=jellyfin
```
## Upgrading
```bash
# Update repository
helm repo update
# Upgrade installation
helm upgrade jellyfin jellyfin/jellyfin
# Check upgrade status
helm status jellyfin
```
## Uninstalling
```bash
# Remove Helm release
helm uninstall jellyfin
# Clean up persistent volumes (if needed)
kubectl delete pvc -l app.kubernetes.io/name=jellyfin
```
## Advanced Configuration
### Hardware Acceleration
For GPU acceleration, add device access and security context:
```yaml
securityContext:
privileged: true
resources:
limits:
gpu.intel.com/i915: 1
# or nvidia.com/gpu: 1
extraVolumes:
- name: dri
hostPath:
path: /dev/dri
extraVolumeMounts:
- name: dri
mountPath: /dev/dri
```
### Multiple Media Sources
Mount multiple media sources using additional volumes:
```yaml
volumes:
- name: movies
persistentVolumeClaim:
claimName: movies-pvc
- name: tv
persistentVolumeClaim:
claimName: tv-pvc
volumeMounts:
- name: movies
mountPath: /movies
- name: tv
mountPath: /tv
```
### Custom Environment Variables
```yaml
extraEnvVars:
- name: JELLYFIN_PublishedServerUrl
value: 'https://jellyfin.example.com'
- name: JELLYFIN_CACHE_DIR
value: '/cache'
```
For more configuration options, see the [Jellyfin Helm chart documentation](https://github.com/jellyfin/jellyfin-helm/tree/master/charts/jellyfin).
@@ -0,0 +1,375 @@
---
uid: installation-advanced-manual
title: Manual Installation
description: Install Jellyfin Manually.
sidebar_position: 3
---
<!-- markdownlint-disable MD036 no-emphasis-as-heading -->
## Portable Windows Package
### Portable Windows 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`.
### Portable Windows 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
### Portable Windows Rollback
1. Stop Jellyfin.
2. Delete the `system` folder.
3. Rename `system-bak` to `system`.
4. Run `jellyfin.bat` to start the server again.
## Portable macOS package
### Installing the Portable macOS Version
1. Download the latest version of Jellyfin.
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 `xattr -rd com.apple.quarantine .` to remove the quarantine flag.
5. Type `codesign -fs - --deep jellyfin` to create an ad-hoc signature for the server.
6. Type `./jellyfin` to run jellyfin.
7. Open your browser at [http://localhost:8096](http://localhost:8096).
Closing the terminal window will end Jellyfin. Running Jellyfin in screen or tmux can prevent this from happening.
### Updating the Portable macOS Version
1. Download the latest version.
2. Stop the currently running server either via the dashboard or using `CTRL+C` in the terminal window.
3. Extract the latest version into Applications
4. Open Terminal and type `cd` followed with a space then drag the jellyfin folder into the terminal.
5. Type `xattr -rd com.apple.quarantine .` to remove the quarantine flag.
6. Type `codesign -fs - --deep jellyfin` to create an ad-hoc signature for the server.
7. Type `./jellyfin` to run jellyfin.
8. Open your browser at [http://localhost:8096](http://localhost:8096)
### Uninstalling the Portable macOS Version
1. Stop the currently running server either via the dashboard or using `CTRL+C` in the terminal window.
2. Move `/Application/jellyfin-version` folder to the Trash. Replace version with the actual version number you are trying to delete.
3. Delete the folder `~/.config/jellyfin/`
4. Delete the folder `~/.local/share/jellyfin/`
### Using FFmpeg with the Portable macOS Version
The portable version doesn't come with FFmpeg by default. There are a few options for installing FFmpeg:
- download jellyfin-ffmpeg from the [Jellyfin repo](https://repo.jellyfin.org/?path=/ffmpeg/macos) (recommended)
- 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](https://evermeet.cx/ffmpeg/get/zip) (compiled by a third party see [evermeet.cx](https://evermeet.cx/ffmpeg/) for options and information) (Apple Silicon builds are not available from this source)
- compile from source available from the official [website](https://ffmpeg.org/download.html)
Once downloaded, remove the quarantine flag for the `ffmpeg` and `ffprobe`.
Ensure that both `ffmpeg` and `ffprobe` are located at the same path, then execute the following command:
```shell
cd /path/to/ffmpeg/folder
xattr -rd com.apple.quarantine .
```
## Portable Linux install
Generic `amd64`, `arm64`, and `armhf` Linux builds in TAR archive format are available [in the main download repository](https://repo.jellyfin.org/?path=/server/).
### 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.10.7 is being installed (i.e. `jellyfin_10.10.7-amd64.tar.gz`).
Download the generic build, then extract the archive:
```sh
sudo wget https://repo.jellyfin.org/files/server/linux/latest-stable/amd64/jellyfin_10.10.7-amd64.tar.gz
sudo tar xvzf jellyfin_10.10.7-amd64.tar.gz
```
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.
:::caution
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/?path=/ffmpeg/debian/) and install an `ffmpeg` `.deb` package built specifically for Jellyfin.
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](https://jellyfin.org/docs/general/administration/configuration/#command-line-options) that must be passed on to the Jellyfin binary, it is easiest to create a small script to run Jellyfin.
```sh
sudoedit jellyfin.sh
```
Then paste the following commands, optionally changing arguments as needed for custom deployments.
```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
USER=$(id --name --user)
GROUP=$(id --name --group)
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 .NET DLL
Platform-agnostic .NET Core DLL builds in TAR archive format are available from the [portable downloads section](/downloads/dotnet).
These builds use the binary `jellyfin.dll` and must be loaded with `dotnet`.
## Debian (using extrepo)
extrepo is only supported on Debian currently. The advantage of extrepo is that it is packaged in Debian. So you dont have to execute the `curl | sudo bash` combo from the previous Automatic section. The risk with that command is that it relies on the security of the webserver. extrepo avoids this by having the Jellyfin repo information including the GPG key in its [extrepo-data](https://salsa.debian.org/extrepo-team/extrepo-data/-/blob/master/repos/debian/jellyfin.yaml?ref_type=heads). extrepo-data is verified with GPG by the extrepo tool. So there is a chain of trust from Debian all the way to the Jellyfin repo information.
```sh
sudo apt install extrepo
sudo extrepo enable jellyfin
```
Now you can continue at step 5. of the [Repository (Manual) section](#official-linux-repository-manual).
## Official Linux Repository (Manual)
If you would prefer to install everything manually, the full steps are as follows:
1. Install `curl` and `gnupg` if you haven't already:
```sh
sudo apt install curl gnupg
```
2. On Ubuntu (and derivatives) only, 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`
:::
On Debian, you can also enable the `non-free` components of your base repositories for additional FFmpeg dependencies, but this is optional.
3. Download the GPG signing key (signed by the Jellyfin Team) and install it:
```sh
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/jellyfin.gpg
```
4. Add a repository configuration at `/etc/apt/sources.list.d/jellyfin.sources`:
```sh
export VERSION_OS="$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release )"
export VERSION_CODENAME="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )"
export DPKG_ARCHITECTURE="$( dpkg --print-architecture )"
cat <<EOF | sudo tee /etc/apt/sources.list.d/jellyfin.sources
Types: deb
URIs: https://repo.jellyfin.org/${VERSION_OS}
Suites: ${VERSION_CODENAME}
Components: main
Architectures: ${DPKG_ARCHITECTURE}
Signed-By: /etc/apt/keyrings/jellyfin.gpg
EOF
```
:::note
The supported values for the above variables are:
- `${VERSION_OS}`: One of `debian` or `ubuntu`; if it is not, use the closest one for your distribution.
- `${VERSION_CODENAME}`: One of our supported [Debian](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L7) or [Ubuntu](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L8) release codenames. These can change as new releases come out and old releases are dropped, so check the script to be sure yours is supported.
- `${DPKG_ARCHITECTURE}`: One of our [supported architectures](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L6). Microsoft does not provide a .NET for 32-bit x86 Linux systems, and hence Jellyfin is **not** supported on the `i386` architecture.
:::
5. Update your APT repositories:
```sh
sudo apt update
```
6. Install the Jellyfin metapackage, which will automatically fetch the various sub-packages:
```sh
sudo apt install jellyfin
```
:::note
If you want to be explicit, instead of the metapackage, you can install the sub-packages individually:
```sh
sudo apt install jellyfin-server jellyfin-web
```
The `jellyfin-server` package will automatically select the right `jellyfin-ffmpeg` package for you as well.
:::
7. Manage the Jellyfin system service:
```sh
sudo systemctl {action} jellyfin
sudo service jellyfin {action}
```
## `.deb` Packages (Very Manual)
Raw `.deb` packages, including old versions, source packages, and `dpkg` meta files, are available [in the main download repository](https://repo.jellyfin.org/?path=/server/).
:::note
The repository is the preferred way to obtain Jellyfin on Debian and Ubuntu systems, as this ensures you get automatic updates and that all dependencies are properly resolved. Use these steps only if you really know what you're doing.
:::
1. On Ubuntu (and derivatives) only, 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`
:::
On Debian, you can also enable the `non-free` components of your base repositories for additional FFmpeg dependencies, but this is optional.
2. Download the desired `jellyfin-server`, `jellyfin-web`, and `jellyfin-ffmpeg` `.deb` packages from the repository; `jellyfin` is a metapackage and is not required.
3. Install the downloaded `.deb` packages with `apt` to handle dependency resolution:
```sh
sudo apt install ./jellyfin-server_*.deb ./jellyfin-web_*.deb ./jellyfin-ffmpeg_*.deb
```
4. Manage the Jellyfin system service:
```sh
sudo systemctl {action} jellyfin
sudo service jellyfin {action}
```
@@ -1,8 +1,8 @@
---
uid: installation-source
uid: installation-advanced-source
title: Building from source
description: Compile and run Jellyfin yourself.
sidebar_position: 7
sidebar_position: 4
---
<!-- markdownlint-disable MD029 ol-prefix -->
@@ -48,7 +48,7 @@ All package builds begin with these two steps:
Replace "auto" with your own Jellyfin version tag if you want to.
3. Run Jellyfin in a new container using Docker or Podman from the built container image.
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
@@ -0,0 +1,71 @@
---
uid: installation-synology
title: Synology
description: Install on Synology NAS.
sidebar_position: 2
---
# Installation on Synology
:::caution Pre-built NAS Devices
Many pre-built NAS devices are underpowered. We generally do not recommend running Jellyfin on those devices.
See: [Hardware Selection](/docs/general/administration/hardware-selection) for more information.
:::
For [Synology](https://www.synology.com/en-us/dsm), Jellyfin is installed using Docker. In this guide, the Synology Container Manager will be used to install Jellyfin.
## Prerequisites
Everything is done through the Synology web interface.
This guide assumes you have already set up your Synology NAS and have access to the web interface. And your Synology NAS is running DSM 7.0 or newer.
Install the "Container Manager" package from the Synology Package Center.
Open the Package Center and search for "Container Manager" to find the package.
For further information read this [guide](https://kb.synology.com/en-global/DSM/help/DSM/PkgManApp/install_buy?version=7).
The creation and initialization of a volume will not be touched in this guide. Further information is provided by [Synology](https://kb.synology.com/en-global/DSM/help/DSM/StorageManager/volume_create_volume?version=7)
## Installation
The installation is done with the Synology Container Manager.
If you don't see the icon in the main menu after the installation of `Container Manager`, it can be found by clicking the top left corner of the main menu.
### Downloading the Jellyfin Image
Navigate to the "Registry" tab and search for "Jellyfin". You should see the official jellyfin/jellyfin image. Click on it and then click "Download".
![Downloading the Image](/images/docs/advanced/synology/install-synology-0.png)
A new window will open and a Jellyfin version can be selected for installation. The latest version is recommended. Click `Apply` after selection a version.
![Downloading the Image](/images/docs/advanced/synology/install-synology-1.png)
After the image is downloaded, it can be found in the `Image` tab.
### Creating the Container
Navigate to the `Container` tab and click `Create`.
Select the `Jellyfin` image and give the container a name. This is mainly for identification purposes and can be set to anything desired. `auto-restart` can be enabled to automatically start Jellyfin when the NAS boots.
Resource limits can also be set for the container. It is recommended that all CPU resources and at least 4GB of ram be allocated to the Jellyfin container.
Click `Next` to proceed to the next step.
![Creating the Container](/images/docs/advanced/synology/install-synology-2.png)
#### Network and Port Settings
For the [Network Settings](https://jellyfin.org/docs/general/post-install/networking/dlna#general) and [Port Settings](https://jellyfin.org/docs/general/post-install/networking/#port-bindings) please refer their respected guides.
#### Volume Settings
This setting maps, directories on the host within the container. Use this setting to allow Jellyfin access to media and a place to store application data.
To add a volume, click "Add Folder" and select the folder desired. The mount point is set in the middle column and the directory will be accessible at this path within the container. For media files, `/media` can be used, and for config files, `/config` can be used.
#### Example
Your settings should look like this:
![Advanced Settings](/images/docs/advanced/synology/install-synology-3.png)
![Advanced Settings](/images/docs/advanced/synology/install-synology-4.png)
Click `Next` to proceed to the next step.
Settings can be reviewed on this screen. Check the `Run this container after the wizard is finished` checkbox and click `Apply` if everything looks correct. The container should now be shown in the `Container` tab.
Browse to `http://SERVER_IP:8096` in a browser on a other device to finish setting up the Jellyfin server.
If a different port was used, replace `8096` with the port used instead.
@@ -94,7 +94,7 @@ A tab will open from the right side of the page where you launch your custom app
Here, give the custom app a name and write/paste the lines for your compose file.
See here for [documentation on using Docker Compose with Jellyfin](/docs/general/installation/container#using-docker-compose).
See here for [documentation on using Docker Compose with Jellyfin](/docs/general/installation/container?method=docker-compose).
Alternatively, here's a basic compose file where you should edit the volumes to use on your system, then copy & paste it into the editor to launch Jellyfin:
```yml
@@ -126,14 +126,14 @@ services:
- Remember to add your media datasets as extra volumes on your compose file so that the container can access them.
- The user & group you set are only to run the container. They are not used to create a Jellyfin account.
- Make sure your spacing is correct for each option. Compose files use spacing to parse the options correctly.
- You can determine the time zone identifier for you region [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- You can determine the time zone identifier for you region [on Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- Note that lines with `#` in front indicate a comment. They will not apply until you remove it.
- Uncomment the `group_add` and `devices` options if you have a GPU and want to use [hardware acceleration](/docs/general/administration/hardware-acceleration/).
- Uncomment the `group_add` and `devices` options if you have a GPU and want to use [hardware acceleration](/docs/general/post-install/transcoding/hardware-acceleration/).
- If you have an NVIDIA GPU, [please read this](#nvidia-gpus-on-scale-v2410).
- Unless you set the container to run as root, you need to add the render group ID to the container with `group_add`.
- In case the render group's ID is not `107` on all SCALE servers by default, go to your system shell and run the following command to get your render group's ID: `cat /etc/group | grep render`
- Jellyfin's auto discovery ports should also be configured if possible.
- [See more info here](/docs/general/networking/#static-ports)
- [See more info here](/docs/general/post-install/networking/#port-bindings)
<details>
<summary>Docker Compose Options</summary>
@@ -325,7 +325,7 @@ Create an admin user in the Jellyfin initial setup wizard to access the UI.
### Networking Settings
Select **Host Network** under **Network Configuration** if using [DLNA](/docs/general/networking/dlna/), to bind network configuration to the host network settings.
Select **Host Network** under **Network Configuration** if using [DLNA](/docs/general/post-install/networking/dlna/), to bind network configuration to the host network settings.
Otherwise, leave **Host Network** unselected.
![Networking](/images/docs/install-truenas-12.png)
@@ -527,7 +527,7 @@ You can also pull new images to use in the future.
You can choose to pull from Jellyfin's [Docker Hub](https://hub.docker.com/r/jellyfin/jellyfin) or [GitHub Container Registry](https://github.com/jellyfin/jellyfin/pkgs/container/jellyfin).
- To pull from Docker Hub, use: `jellyfin/jellyin`
- To pull from Docker Hub, use: `jellyfin/jellyfin`
- To pull from from GHCR, use: `ghcr.io/jellyfin/jellyfin`
- [You can check this blog post for more info about GHCR:](/posts/jellyfin-release-10.9.0#key-release-notesbreaking-changes)
- "Docker users: We now offer GitHub Container Registry (GHCR) as an alternative container registry in addition to Docker Hub. You can pull images from the new registry via URIs like `ghcr.io/jellyfin/jellyfin:latest`. Don't worry, we have no plans to drop Docker Hub as a container registry, but we feel providing both gives users more choice and flexibility."
@@ -0,0 +1,61 @@
---
uid: installation-advanced-windows
title: Windows Service
description: Installing Jellyfin as a Windows Service.
sidebar_position: 5
---
:::note
While a standard installation is recommended for most users, installing Jellyfin as a service is ideal for dedicated servers. This allows Jellyfin to start automatically at boot and remain active even when no users are logged into the system.
:::
Running as a **Network Service** is preferred over **Local System** for the principle of least privilege. Follow these steps to ensure proper access without over-provisioning permissions.
### Installing as a Service
1. In the Windows installer, select **Install as a Service**.
2. Choose the default install path, `C:\Program Files\Jellyfin\Server`.
3. Choose the default data path, `C:\ProgramData\Jellyfin\Server`.
4. Choose **Use Network Service account** for the account type.
5. Uncheck **Start Service after Install**.
6. Click **Install**.
### Configure Service Account Permissions
The service account needs access to Jellyfin's configuration files.
1. Navigate to `C:\ProgramData\`.
2. Right-click the **Jellyfin** folder, and click **Properties** > **Security** > **Advanced**.
3. Beside **Owner**, click **Change**, and enter `NETWORK SERVICE` in the text box. Click **OK**.
4. Click **Add** under Principal. Click **Select a principal** and enter `NETWORK SERVICE` in the text box. Click **OK**.
5. Under **Basic permissions** for the new principal, choose one of the following based on your security preference, then Click **OK**.
* **Modify**: Allows Jellyfin to read, write, and delete its own data without granting it the power to change system permissions.
* **Full Control**: Easiest for setup. Grants all rights, including the ability to change owner and permissions.
6. Check the option **Replace all child object permission entries...**. Click **Apply**.
7. Exit the menu.
### Configure Media Library Permissions
After setting up a media folder, you should grant the service account read & execute access to that folder to prevent "Path not found" errors.
1. Right-click your media folder, and click **Properties** > **Security** > **Advanced**.
2. Click **Add** under Principal. Click **Select a principal** and enter `NETWORK SERVICE` in the text box. Click **OK**.
3. Under **Basic permissions** for the new principal, choose based on how you want Jellyfin to interact with your files, then Click **OK**.
* **Read & execute** (Recommended): Allows Jellyfin to see and play your media. This is the safest option as it prevents the server from accidentally deleting or modifying your original movie files.
* **Modify**: Required only if you want to use `Delete` from within the Jellyfin UI, or if you want Jellyfin to save subtitles and `.nfo` metadata files directly into your movie folders.
* **Full Control**: Not recommended for media folders. This grants administrative rights that the service does not need for playback.
4. Check the option **Replace all child object permission entries...**. Click **Apply**.
5. Exit the menu.
### Verify and Initialize
1. Press **Windows**+**R** and type "services.msc". Hit **Enter**.
2. Find the **Jellyfin Server** service and verify the "Log On As" column shows **Network Service**.
3. Right-click **Jellyfin Server** service and select **Start**.
4. Navigate to http://localhost:8096 to complete the wizard.
### Troubleshooting
* **Missing ProgramData Folder:** If `C:\ProgramData\Jellyfin` does not exist yet, proceed to **Verify and Initialize** and follow steps 1 and 3. This will generate the necessary directory structure so you can then apply permissions.
* **Empty Libraries:** If the setup wizard does not "see" your media, ensure the `NETWORK SERVICE` account has at least **List folder contents** permissions on the parent directory leading to your media folder (e.g., if media is in `D:\Media\Movies`, check permissions for `D:\Media`).
* **Remote Access:** To allow other devices on your network to connect, you must add a Windows Firewall rule to allow **Inbound** traffic on TCP port `8096`. For detailed steps, see the [Networking Guide](../../post-install/networking/index.md).
+32 -299
View File
@@ -2,324 +2,57 @@
uid: installation-container
title: Container
description: Install as a container using Docker, Podman and others.
sidebar_position: 1
sidebar_position: 4
---
<!-- markdownlint-disable MD036 no-emphasis-as-heading -->
## 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>.
Official container image: `jellyfin/jellyfin` [![jellyfin Docker Pull Count](https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg)](https://hub.docker.com/r/jellyfin/jellyfin).
This image is also published on the GitHub Container Registry: `ghcr.io/jellyfin/jellyfin`.
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>.
LinuxServer.io image: `linuxserver/jellyfin` [![linuxserver jellyfin Docker Pull Count](https://img.shields.io/docker/pulls/linuxserver/jellyfin.svg)](https://hub.docker.com/r/linuxserver/jellyfin).
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>.
hotio image: `ghcr.io/hotio/jellyfin`.
Jellyfin distributes [official container images on Docker Hub](https://hub.docker.com/r/jellyfin/jellyfin/) for multiple architectures.
Jellyfin distributes official container images on [Docker Hub](https://hub.docker.com/r/jellyfin/jellyfin/) and the [GitHub Container Registry](https://ghcr.io/jellyfin/jellyfin) for multiple architectures.
These images are based on Debian and [built directly from the Jellyfin source code](https://github.com/jellyfin/jellyfin-packaging/blob/master/docker/Dockerfile).
Several tags are available tracking different builds and [version](/docs/general/contributing/release-procedure/#versioning) levels.
- `latest` always tracks the latest stable release, including through major and minor version bumps
- `X` (e.g. `10`) tracks the major version, e.g. the latest 10.Y.Z
- `X.Y` (e.g. `10.11`) tracks the minor version, e.g. the latest 10.11.Z
- `X.Y.Z` (e.g. `10.11.0`) tracks a specific release
- `X.Y.Z.YYYYMMDD-HHMMSS` (e.g. `10.11.0.20251020-004604`) tracks a specific packaging build
Additionally, there are several third parties providing unofficial container images, including the [LinuxServer.io](https://www.linuxserver.io/) ([Dockerfile](https://github.com/linuxserver/docker-jellyfin/blob/master/Dockerfile)) project and [hotio](https://github.com/hotio) ([Dockerfile](https://github.com/hotio/jellyfin/blob/release/linux-amd64.Dockerfile)), which offer images based on Ubuntu and the official Jellyfin Ubuntu binary packages.
## Docker
## Installation Instructions
[Docker](https://www.docker.com/) allows you to run containers on Linux, Windows and MacOS.
Replace `uid:gid` if you want to run jellyfin as a specific user/group. Exclude the `user` argument entirely if you want to use the default user.
:::warning
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import DockerCli from './\_container-docker-cli.md';
import DockerCompose from './\_container-docker-compose.md';
import Podman from './\_container-podman.md';
If you wish to use Windows or macOS, please install Jellyfin natively instead. [Windows](/docs/general/installation/windows) [macOS](/docs/general/installation/macos).
<Tabs queryString="method">
<TabItem value="docker-cli" label="Docker">
While it is possible to run Jellyfin in Docker on a Windows or macOS host, it is NOT supported. Some features are known to be broken when running in Docker on platforms other than Linux, Notably:
<DockerCli />
- Hardware Accelerated Transcoding
- [Scanning on macOS in Docker](https://github.com/jellyfin/jellyfin/issues/13093)
</TabItem>
<TabItem value="docker-compose" label="Docker Compose" default>
You WILL NOT receive any support for running Jellyfin in Docker on platforms other than Linux.
<DockerCompose />
:::
</TabItem>
<TabItem value="podman" label="Podman">
The basic steps to create and run a Jellyfin container using Docker are as follows.
<Podman />
1. Follow the [official 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
```
Custom [server-side system fonts](/docs/general/administration/configuration/#server-side-system-fonts) directory can be optionally bind mounted in order to use these fonts during transcoding with subtitle burn-in:
```sh
--mount type=bind,source=/path/to/fonts,target=/usr/local/share/fonts/custom,readonly
```
A directory of [fallback fonts](/docs/general/administration/configuration/#fallback-fonts) can be mounted as well. In this case, you will have to set the directory of fallback fonts to `/fallback_fonts` in Jellyfin server settings panel:
```sh
--mount type=bind,source=/path/to/fallback/fonts,target=/fallback_fonts,readonly
```
### Using Docker Compose
Create a `docker-compose.yml` file with the following contents. Add in the UID and GID that you would like to run jellyfin as in the user line below, or remove the user line to use the default (root).
```yml
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: uid:gid
network_mode: 'host'
volumes:
- /path/to/config:/config
- /path/to/cache:/cache
- type: bind
source: /path/to/media
target: /media
- type: bind
source: /path/to/media2
target: /media2
read_only: true
# Optional - extra fonts to be used during transcoding with subtitle burn-in
- type: bind
source: /path/to/fonts
target: /usr/local/share/fonts/custom
read_only: true
restart: 'unless-stopped'
# Optional - alternative address used for autodiscovery
environment:
- JELLYFIN_PublishedServerUrl=http://example.com
# Optional - may be necessary for docker healthcheck to pass if running in host network mode
extra_hosts:
- 'host.docker.internal:host-gateway'
```
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/).
## 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,relabel=private \
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 and `relabel=shared` or `relabel=private` mount option tell 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 [podman-systemd.unit](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
As always it is recommended to run the container rootless. Therefore we want to manage the container with the `systemd --user` flag.
1. Create a new user that the rootless container will run under.
`useradd jellyfin`
This allows users who are not logged in to run long-running services.
`loginctl enable-linger jellyfin`
Open an interactive shell session.
`machinectl shell jellyfin@`
2. Install `.config/containers/systemd/jellyfin.container`
> Contents of `~/.config/containers/systemd/jellyfin.container`
```sh
[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
PublishPort=8096:8096/tcp
UserNS=keep-id
Volume=jellyfin-config:/config:Z
Volume=jellyfin-cache:/cache:Z
Volume=jellyfin-media:/media:Z
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target
```
3. Reload daemon and start the service.
`systemctl --user daemon-reload`
`systemctl --user start jellyfin`
4. To enable Podman auto-updates, enable the necessary systemd timer.
`systemctl --user enable --now podman-auto-update.timer`
5. Optionally check logs for errors
`journalctl --user -u jellyfin`
6. `exit` the current session.
### With hardware acceleration
To use hardware acceleration, you need to allow the container to access the render device. If you are using container-selinux-2.226 or later, you have to set the `container_use_dri_devices` flag in selinux or the container will not be able to use it:
`sudo setsebool -P container_use_dri_devices 1`
On older versions of container-selinux, you have to disable the selinux confinement for the container by adding `--security-opt label=disable` to the podman command.
Then, you need to mount the render device inside the container:
`--device /dev/dri/:/dev/dri/`
Finally, you need to set the `--device` flag for the container to use the render device:
`--device /dev/dri/`
#### podman run
```sh
podman run \
--detach \
--label "io.containers.autoupdate=registry" \
--name myjellyfin \
--publish 8096:8096/tcp \
--device /dev/dri/:/dev/dri/ \
# --security-opt label=disable # Only needed for older versions of container-selinux < 2.226
--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,relabel=private \
docker.io/jellyfin/jellyfin:latest
```
#### systemd
```sh
[Unit]
Description=jellyfin
[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
PublishPort=8096:8096/tcp
UserNS=keep-id
#SecurityLabelDisable=true # Only needed for older versions of container-selinux < 2.226
AddDevice=/dev/dri/:/dev/dri/
Volume=jellyfin-config:/config:Z
Volume=jellyfin-cache:/cache:Z
Volume=jellyfin-media:/media:Z
[Service]
# Inform systemd of additional exit status
SuccessExitStatus=0 143
[Install]
# Start by default on boot
WantedBy=default.target
```
</TabItem>
</Tabs>
+9 -3
View File
@@ -16,6 +16,12 @@ Even though there are builds available online for these platforms, they are unof
For info on selecting hardware for a Jellyfin server, please refer to the [Hardware Selection Guide](/docs/general/administration/hardware-selection)
import DocCardList from '@theme/DocCardList';
<DocCardList />
- [Windows](/docs/general/installation/windows)
- [macOS](/docs/general/installation/macos)
- [Debian / Ubuntu](/docs/general/installation/linux#debian--ubuntu-and-derivatives)
- [Other Linux Distributions](/docs/general/installation/linux#other-distributions)
- [Docker / Kubernetes / Podman](/docs/general/installation/container)
- [Synology](/docs/general/installation/advanced/synology)
- [TrueNAS SCALE](/docs/general/installation/advanced/truenas)
- [Generic Linux](/docs/general/installation/advanced/manual#portable-linux-install)
- [Building from source](/docs/general/installation/advanced/source).
+19 -436
View File
@@ -1,461 +1,44 @@
---
uid: installation-linux
title: Linux
description: Install on Linux.
sidebar_position: 2
description: Installing on Linux.
sidebar_position: 3
---
## Official packages and methods
## Debian / Ubuntu and derivatives
### Debuntu (Debian, Ubuntu, and derivatives using `apt`) with official repository
To simplify deployment and help automate this for as many users as possible, we provide a BASH script to handle repo installation as well as installing Jellyfin on Debian / Ubuntu and derivatives.
The Jellyfin team provides 3rd-party Debian and Ubuntu repositories, to help ensure your Jellyfin install is always kept up-to-date. For Ubuntu, only LTS distributions from the past 5 years are supported.
#### Repository (Automatic)
To simplify deployment and help automate this for as many users as possible, we provide a BASH script to handle repo installation as well as installing Jellyfin.
All you need to do is run this command on your system (requires `curl`, or subsitute `curl` with `wget -O-`):
Download and verify the script, then execute it on your system (requires `curl` and `sha256sum`):
```sh
curl https://repo.jellyfin.org/install-debuntu.sh | sudo bash
curl -s https://repo.jellyfin.org/install-debuntu.sh -O && \
curl -s https://repo.jellyfin.org/install-debuntu.sh.sha256sum -O && \
sha256sum -c install-debuntu.sh.sha256sum
```
:::note
`install-debuntu.sh: OK` means the checksum is correct.
You can verify the script download integrity with (requires `sha256sum`):
```sh
diff <( curl -s https://repo.jellyfin.org/install-debuntu.sh -o install-debuntu.sh; sha256sum install-debuntu.sh ) <( curl -s https://repo.jellyfin.org/install-debuntu.sh.sha256sum )
```
An empty output means everything is correct. Then you can inspect the script to see what it does (optional but recommended) and execute it with:
You can optionally inspect the script to see what it does before executing it:
```sh
less install-debuntu.sh
```
Then execute it with:
```sh
sudo bash install-debuntu.sh
```
:::
:::note
The script tries to handle as many common derivatives as possible, including, at least, Linux Mint (Ubuntu and Debian editions), Raspbian/Raspberry Pi OS, and KDE Neon. We welcome PRs [to the script](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh) for any other common derivatives, or you can use the steps below instead.
The script tries to handle as many common derivatives as possible, including, at least, Linux Mint (Ubuntu and Debian editions), Raspbian/Raspberry Pi OS, and KDE Neon. We welcome PRs [to the script](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh) for any other common derivatives.
:::
#### Repository (Using extrepo)
If you do not want to execute a script with superuser permissions, you can also install the Jellyfin software repository manually (using either [extrepo](/docs/general/installation/advanced/manual/#debian-using-extrepo) or the [fully manual method](/docs/general/installation/advanced/manual/#official-linux-repository-manual)).
extrepo is only supported on Debian currently. The advantage of extrepo is that it is packaged in Debian. So you dont have to execute the `curl | sudo bash` combo from the previous Automatic section. The risk with that command is that it relies on the security of the webserver. extrepo avoids this by having the Jellyfin repo information including the GPG key in its [extrepo-data](https://salsa.debian.org/extrepo-team/extrepo-data/-/blob/master/repos/debian/jellyfin.yaml?ref_type=heads). extrepo-data is verified with GPG by the extrepo tool. So there is a chain of trust from Debian all the way to the Jellyfin repo information.
## Other Distributions
```sh
sudo apt install extrepo
sudo extrepo enable jellyfin
```
Now you can continue at step 5. of the [Repository (Manual) section](#repository-manual).
### Containers
For non Debian/Ubuntu systems, containers are the recommended way to install Jellyfin. Please follow the instructions [here](/docs/general/installation/container).
## Community maintained packages
### Alpine Linux
Jellyfin can be found in the `community` repository as
[`jellyfin`](https://pkgs.alpinelinux.org/package/edge/community/x86_64/jellyfin) and
[`jellyfin-web`](https://pkgs.alpinelinux.org/package/edge/community/x86_64/jellyfin-web).
To enable the web UI after installing `jellyfin-web`, make sure to remove the `--nowebclient` option from
`/etc/conf.d/jellyfin`.
### Arch Linux
The `Extra` repository contains builds for both [`jellyfin-server`](https://archlinux.org/packages/?name=jellyfin-server) and [`jellyfin-web`](https://archlinux.org/packages/?name=jellyfin-web).
`jellyfin-server` includes a hard dependency on [`jellyfin-ffmpeg`](https://archlinux.org/packages/?name=jellyfin-ffmpeg).
Both packages, server and web, can also be built from source at the tip of the master branch using [`jellyfin-git`](https://aur.archlinux.org/packages/jellyfin-git/).
The AUR also offers each separately at [`jellyfin-server-git`](https://aur.archlinux.org/packages/jellyfin-server-git/) and [`jellyfin-web-git`](https://aur.archlinux.org/packages/jellyfin-web-git/).
### Fedora, CentOS and other RPM distributions
Builds in RPM package format are provided by RPM Fusion. Official packages are no longer provided starting with 10.9.
#### RPM Fusion
1. `rpmfusion` must be enabled first
```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
```
2. Install the `jellyfin` package, which will automatically install `jellyfin-server`, `jellyfin-web` and `jellyfin-firewalld`
```sh
sudo dnf install jellyfin
```
3. Enable and start the Jellyfin service:
```sh
sudo systemctl enable --now jellyfin
```
#### Manual installation via the .rpm packages
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 server `.rpm` file URL>
```
3. Install the Jellyfin web interface
```sh
sudo dnf install <link to web `.rpm` file URL>
```
4. Enable and start the Jellyfin service:
```sh
sudo systemctl enable --now jellyfin
```
5. Allow Jellyfin through the firewall:
```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. Reload the firewall to apply the new rules:
```sh
sudo firewall-cmd --reload
```
7. Go to `localhost:8096` or `ip-address-of-jellyfin-server:8096` to finish setup in the web UI.
### Gentoo
The Gentoo ebuild repository includes the Jellyfin package which can be installed like other software:
```sh
emerge www-apps/jellyfin
```
### NixOS
NixOS has a [module for Jellyfin](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/jellyfin.nix),
it can be enabled as follows:
```nix
{
services.jellyfin.enable = true;
}
```
For more information, refer to the [NixOS wiki](https://wiki.nixos.org/wiki/Jellyfin).
## Advanced
### Manual installation on Debian, Ubuntu and derivatives
#### Repository (Manual)
If you would prefer to install everything manually, the full steps are as follows:
1. Install `curl` and `gnupg` if you haven't already:
```sh
sudo apt install curl gnupg
```
2. On Ubuntu (and derivatives) only, 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`
:::
On Debian, you can also enable the `non-free` components of your base repositories for additional FFmpeg dependencies, but this is optional.
3. Download the GPG signing key (signed by the Jellyfin Team) and install it:
```sh
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/jellyfin.gpg
```
4. Add a repository configuration at `/etc/apt/sources.list.d/jellyfin.sources`:
```sh
export VERSION_OS="$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release )"
export VERSION_CODENAME="$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )"
export DPKG_ARCHITECTURE="$( dpkg --print-architecture )"
cat <<EOF | sudo tee /etc/apt/sources.list.d/jellyfin.sources
Types: deb
URIs: https://repo.jellyfin.org/${VERSION_OS}
Suites: ${VERSION_CODENAME}
Components: main
Architectures: ${DPKG_ARCHITECTURE}
Signed-By: /etc/apt/keyrings/jellyfin.gpg
EOF
```
:::note
The supported values for the above variables are:
- `${VERSION_OS}`: One of `debian` or `ubuntu`; if it is not, use the closest one for your distribution.
- `${VERSION_CODENAME}`: One of our supported [Debian](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L7) or [Ubuntu](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L8) release codenames. These can change as new releases come out and old releases are dropped, so check the script to be sure yours is supported.
- `${DPKG_ARCHITECTURE}`: One of our [supported architectures](https://github.com/jellyfin/jellyfin-repo-helper-scripts/blob/master/install-debuntu.sh#L6). Microsoft does not provide a .NET for 32-bit x86 Linux systems, and hence Jellyfin is **not** supported on the `i386` architecture.
:::
5. Update your APT repositories:
```sh
sudo apt update
```
6. Install the Jellyfin metapackage, which will automatically fetch the various sub-packages:
```sh
sudo apt install jellyfin
```
:::note
If you want to be explicit, instead of the metapackage, you can install the sub-packages individually:
```sh
sudo apt install jellyfin-server jellyfin-web
```
The `jellyfin-server` package will automatically select the right `jellyfin-ffmpeg` package for you as well.
:::
7. Manage the Jellyfin system service:
```sh
sudo systemctl {action} jellyfin
sudo service jellyfin {action}
```
#### `.deb` Packages (Very Manual)
Raw `.deb` packages, including old versions, source packages, and `dpkg` meta files, are available [in the main download repository](https://repo.jellyfin.org/?path=/server/).
:::note
The repository is the preferred way to obtain Jellyfin on Debian and Ubuntu systems, as this ensures you get automatic updates and that all dependencies are properly resolved. Use these steps only if you really know what you're doing.
:::
1. On Ubuntu (and derivatives) only, 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`
:::
On Debian, you can also enable the `non-free` components of your base repositories for additional FFmpeg dependencies, but this is optional.
2. Download the desired `jellyfin-server`, `jellyfin-web`, and `jellyfin-ffmpeg` `.deb` packages from the repository; `jellyfin` is a metapackage and is not required.
3. Install the downloaded `.deb` packages:
```sh
sudo dpkg -i jellyfin_*.deb jellyfin-ffmpeg_*.deb
```
:::note
This step may throw errors; continue to the next step to resolve them.
:::
4. Use `apt` to install any missing dependencies:
```sh
sudo apt -f install
```
5. Manage the Jellyfin system service:
```sh
sudo systemctl {action} jellyfin
sudo service jellyfin {action}
```
### Linux (generic amd64)
Generic `amd64`, `arm64`, and `armhf` Linux builds in TAR archive format are available [in the main download repository](https://repo.jellyfin.org/?path=/server/).
#### 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.8.13 is being installed (i.e. `jellyfin_10.8.13_amd64.tar.gz`).
Download the generic build, then extract the archive:
```sh
sudo wget https://repo.jellyfin.org/?path=/server/linux/stable/combined/jellyfin_10.8.13_amd64.tar.gz
sudo tar xvzf jellyfin_10.8.13_amd64.tar.gz
```
Create a symbolic link to the Jellyfin 10.8.13 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.8.13 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.
:::caution
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/?path=/ffmpeg/debian/) and install an `ffmpeg` `.deb` package built specifically for Jellyfin.
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 on to the Jellyfin binary, it is easiest to create a small script to run Jellyfin.
```sh
sudoedit 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](/downloads#portable).
These builds use the binary `jellyfin.dll` and must be loaded with `dotnet`.
### Building from source
Jellyfin can be built from source directly. Please read [Building from source](/docs/general/installation/source) for more info.
For other distributions, [containers](/docs/general/installation/container) are the recommended way to install Jellyfin. There are also [community-maintained packages](/docs/general/installation/advanced/community) provided by 3rd parties if you would like to use them instead.
+8 -82
View File
@@ -1,99 +1,25 @@
---
uid: installation-macos
title: macOS
description: Install on macOS.
sidebar_position: 6
description: Installing on macOS.
sidebar_position: 2
---
<!-- markdownlint-disable MD036 no-emphasis-as-heading -->
## Installing on macOS
# Install on macOS
macOS Application packages and builds in TAR archive format are available [here](/downloads/macos).
Jellyfin requires macOS 12 or newer to run.
Jellyfin 10.9 or newer is required for Apple Silicon native support.
## Packaged Version(dmg)
### Install
1. Download the latest version.
1. Download the latest version DMG image from [the downloads page](/downloads/macos). For Apple Silicon Macs below macOS 14, please update to a newer version of macOS or download the x86 release.
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".
4. Click the icon in the menu bar and select "Launch".
### Upgrade
## Updating on macOS
1. Download the latest version.
1. Download the latest version DMG image from [the downloads page](/downloads/macos).
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
## Uninstalling on macOS
1. Stop the currently running server either via the dashboard or using the application icon.
2. Move the `.app` package to the trash.
### Deleting Configuration
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
The portable version is intended for advanced users who want more customization options.
For average users, the packaged version is strongly recommended.
If you are not comfortable with command line, then this is not the version for you.
### Installing the Portable Version
1. Download the latest version of Jellyfin.
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 `xattr -rd com.apple.quarantine .` to remove the quarantine flag.
5. Type `codesign -fs - --deep jellyfin` to create an ad-hoc signature for the server.
6. Type `./jellyfin` to run jellyfin.
7. Open your browser at [http://localhost:8096](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.
2. Stop the currently running server either via the dashboard or using `CTRL+C` in the terminal window.
3. Extract the latest version into Applications
4. Open Terminal and type `cd` followed with a space then drag the jellyfin folder into the terminal.
5. Type `xattr -rd com.apple.quarantine .` to remove the quarantine flag.
6. Type `codesign -fs - --deep jellyfin` to create an ad-hoc signature for the server.
7. Type `./jellyfin` to run jellyfin.
8. Open your browser at [http://localhost:8096](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.
2. Move `/Application/jellyfin-version` folder to the Trash. Replace version with the actual version number you are trying to delete.
3. Delete the folder `~/.config/jellyfin/`
4. Delete the folder `~/.local/share/jellyfin/`
### Using FFmpeg with the Portable Version
The portable version doesn't come with FFmpeg by default. There are a few options for installing FFmpeg:
- download jellyfin-ffmpeg from the [Jellyfin repo](https://repo.jellyfin.org/?path=/ffmpeg/macos) (recommended)
- 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) (Apple Silicon builds are not available from this source)
- compile from source available from the official [website](https://ffmpeg.org/download.html)
Once downloaded, remove the quarantine flag for the `ffmpeg` and `ffprobe`.
Ensure that both `ffmpeg` and `ffprobe` are located at the same path, then execute the following command:
```shell
cd /path/to/ffmpeg/folder
xattr -rd com.apple.quarantine .
```
-34
View File
@@ -1,34 +0,0 @@
---
uid: installation-synology
title: Synology
description: Install on Synology NAS.
sidebar_position: 5
---
For [Synology](https://www.synology.com/en-us/dsm), Jellyfin is installed using Docker.
![Installing Synology](/images/docs/install-synology-1.png)
![Installing Synology](/images/docs/install-synology-2.png)
![Installing Synology](/images/docs/install-synology-3.png)
Create the container.
![Installing Synology](/images/docs/install-synology-4.png)
![Installing Synology](/images/docs/install-synology-5.png)
Use Advanced Settings to add mount points to your media and config.
![Installing Synology](/images/docs/install-synology-6.png)
![Installing Synology](/images/docs/install-synology-7.png)
Host Mode is required for HdHR and DLNA. Use bridge mode if running multiple instances.
![Installing Synology](/images/docs/install-synology-8.png)
![Installing Synology](/images/docs/install-synology-9.png)
Browse to `http://SERVER_IP:8096` to access the web client.
+10 -78
View File
@@ -1,97 +1,29 @@
---
uid: installation-windows
title: Windows
description: Install on Windows.
sidebar_position: 3
description: Installing on Windows.
sidebar_position: 1
---
<!-- markdownlint-disable MD036 no-emphasis-as-heading -->
Windows installers and builds in ZIP archive format are available [here](/downloads/windows).
## Installing on Windows
:::caution
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.
:::
:::caution
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
**Install**
1. Download the latest version.
1. Download the latest version installer from [the downloads page](/downloads/windows).
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](http://your_local_IP_address:8096) to finish setting up Jellyfin.
**Update**
## Updating on Windows
1. Download the latest version.
2. Close or Stop Jellyfin if it is running.
1. Download the latest version installer from [the downloads page](/downloads/windows).
2. Close or Stop Jellyfin from the tray app if it is running.
3. Run the installer.
4. If everything was completed successfully, the new version is installed.
**Uninstall**
## Uninstalling on Windows
1. Go to `Add or remove programs` in Windows.
1. Go to [Add or remove programs](https://support.microsoft.com/en-us/windows/uninstall-or-remove-apps-and-programs-in-windows-4b55f974-2cc6-2d2b-d092-5905080eaf98) in Windows settings.
2. Search for Jellyfin.
3. Click Uninstall.
## Install manually (portable)
**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`.
**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.
3. Click Uninstall.
-1
View File
@@ -1 +0,0 @@
position: 5
-36
View File
@@ -1,36 +0,0 @@
---
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",
"Jellyfin.Plugin.Dlna": "Debug"
}
}
}
}
```
-156
View File
@@ -1,156 +0,0 @@
---
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.
:::caution
In order for Chromecast to work on your local LAN, the easiest solution is to use IPv6 instead of IPv4.
For IPv4, you need to use NAT reflection to redirect to your local LAN IPv4 or add a override rules to your local DNS server to point to your local LAN IPv4 (for example 192.168.1.10) of Jellyfin.
Because Chromecasts have hardcoded Google DNS servers, you need to block Chromecast from reaching these servers (8.8.8.8) so it makes use of your local DNS server instead.
For a public routable IPv6 (not a link-local or ULA) there is no difference between public or local. Such IPv6 address is simultaneously publicly routable and accessible from the local LAN.
Because of that, there is no blocking, redirecting or DNS override needed.
:::
### 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](/docs/general/networking/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 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.
In cases when you would like to not use host networking with docker, you may use the gateway ip as a known proxy to fix ip resolution for clients logging in.
:::caution
In order for a reverse proxy to have the maximum benefit, you should have a publicly 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.
:::
:::caution
Be careful when logging requests with your reverse proxy. Jellyfin sometimes sends authentication information as part of the URL (e.g `api_key` 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](/docs/general/networking/apache)
- [Caddy](/docs/general/networking/caddy)
- [HAProxy](/docs/general/networking/haproxy)
- [Nginx](/docs/general/networking/nginx)
- [Traefik](/docs/general/networking/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](/docs/general/networking/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.
:::caution
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.
+2
View File
@@ -0,0 +1,2 @@
position: 3
label: 'Post-Install Setup'
@@ -0,0 +1,65 @@
---
uid: network-tailscale
title: Tailscale
sidebar-position: 3
---
# Tailscale
[Tailscale](https://tailscale.com) is a VPN based on Wireguard which offers easy configuration and high performance. It provides an effective alternative in situations where opening ports is undesirable or not feasible, such as when the network is behind a carrier-grade NAT (CGNAT), or if your ISP blocks incoming traffic on certain ports.
## Prerequisites
A Tailscale account is required for Tailscale to work. An account can be created on the [Tailscale Website](https://tailscale.com)
## Using Tailscale Directly
Tailscale can be directly used to connect multiple devices together.
Pros:
- No changing router or network settings required.
- No Public IP or additional servers required.
Cons:
- Every client needs to have the Tailscale software installed
- Needs extra, complex configuration to block clients from connecting to each other.
- Requires an account with a 3rd party provider.
Setup on server:
1. Install the Tailscale app on the client device. Instructions are available in [Tailscale's official install guide](https://tailscale.com/kb/1347/installation)
2. Login to the Tailscale client and connect to the tailnet. On Windows and macOS that can be done through the icon in the system tray. On Linux that can be done with the command `sudo tailscale up`
3. Find and note your Tailscale IP of the server according to the [Tailscale Documentation](https://tailscale.com/kb/1033/ip-and-dns-addresses?tab=linux#finding-your-tailscale-ip-address). This IP will be used for other devices to connect. The IP should start with 100 (e.g. 100.12.34.56).
Setup on clients:
1. Install the Tailscale app on the client device. Instructions are available in [Tailscale's official install guide](https://tailscale.com/kb/1347/installation)
2. Login to the Tailscale client and connect to the tailnet. On Windows and macOS that can be done through the icon in the system tray. On Linux that can be done with the command `sudo tailscale up`. On mobile devices that can be done through the tailscale app.
3. Type in the server IP from above into your browser or Jellyfin client of choice and connect. (e.g. 100.12.34.56:8096)
## Using Tailscale with a reverse proxy
Tailscale can also be used to connect between a server and a remote reverse proxy. While it is possible to setup a traditional VPN connection between the remote reverse proxy and the Jellyfin server, it can be tricky. Tailscale provides an easy way to set up such a connection.
Setup on Jellyfin server:
1. Follow the `Setup on server` section in the [Using Tailscale Directly](#using-tailscale-directly) section to setup Tailscale on the Jellyfin server host.
2. Complete the setup on the reverse proxy server below.
3. Open the Dashboard of the Jellyfin server and go to Networking. Add the reverse proxy Tailscale IP to the `known proxies` setting. This is explained in detail in our [reverse proxy guide](./8_reverse-proxy/index.md#forwarded-for-headers).
Setup on reverse proxy server:
1. Install the Tailscale app on the client device. Instructions are available in [Tailscale's official install guide](https://tailscale.com/kb/1347/installation)
2. Login to the tailscale client and connect to the tailnet. On Linux this can be done with the command `sudo tailscale up`
3. Setup a reverse proxy of your choice and set the upstream server to the IP from above. Example [Caddy](./reverse-proxy/caddy) configuration: (Assuming server has Tailscale IP of 100.12.34.56)
```txt
example.com
redir /jellyfin /jellyfin/
reverse_proxy /jellyfin/* 100.12.34.56:8096
```
4. Find and note your Tailscale IP of the reverse proxy server according to the [Tailscale Documentation](https://tailscale.com/kb/1033/ip-and-dns-addresses?tab=linux#finding-your-tailscale-ip-address). This IP must be added to the Jellyfin servers `known proxies` setting. The IP should start with 100 (e.g. 100.65.43.21).
@@ -0,0 +1,54 @@
---
uid: network-dlna
title: DLNA
sidebar-position: 2
---
DLNA support has been moved to a first party plugin and is not included in a Jellyfin base install since 10.9.
If you want to use DLNA, please install the plugin from the official Plugin catalog.
To do so simply navigate to the admin dashboard, open the Catalog and install the [DLNA Plugin](https://github.com/jellyfin/jellyfin-plugin-dlna). Plugins maintained by the Jellyfin Project will be available in there by default.
Make sure to restart your Jellyfin-Server to complete the plugin installation.
## General
**Requirements:**
- Docker Host-networking (if Docker is used)
- 1900 udp
DLNA is based on UPnP.
Therefore it will make use of its **Service Discovery** (SSDP) running on Port 1900 UDP.
Since UPnP is a standard Protocol expected to be on UDP port 1900, its not possible to configure this.
Make sure to open this port to your local network. You will find more information about how to do this in the [Firewall guide](./index.md#firewall--port-forwarding).
DLNA discovery works by sending a broadcast to the current subnet and waiting for DLNA Servers to respond.
This means that clients will not be able to find your server if it is not in the same subnet.
Using DLNA remotely is not possible.
If you are using Docker, the network should use **Host Mode**, otherwise the broadcast signal will not reach the bridged network inside of Docker.
## Troubleshooting
- 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",
"Jellyfin.Plugin.Dlna": "Debug"
}
}
}
}
```

Some files were not shown because too many files have changed in this diff Show More