Jellyfin

Jellyfin - стриминговый сервер, позволяющий организовать стриминг кинчиков, сериальчиков. Так же имеет фунционал для организации стриминга музыки и даже чтения книжек/комиксов, но удобство использования последних оставляет желать лучшего.

Поддерживает рендер видео на лету используя ресурсы CPU, что долго и ориентировано на 1 пользователя максимум, или же использование аппаратного рендера средствами QuickSync, VA-API, NVENC. По видеокарточкам - Nvidia GTX 1050 и выше, по QuickSync - Intel CPU 9 поколение+ желательно (Но без индекса F).

Установка с пакета (но через скрипт)

В debian/ubuntu - лучших традициях через внешний sh скрипт

curl https://repo.jellyfin.org/install-debuntu.sh | sudo bash
sudo bash install-debuntu.sh

Установка через бинарник

Создадим папку и перейдем

sudo mkdir /opt/jellyfin
cd /opt/jellyfin

Находим на странице репозитория ссылку на последнюю версию и копируем tar.gz. Далее скачаем и распакуем. После распаковки создадим символическую ссылку и создадим папки.

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
sudo ln -s jellyfin_10.10.7 jellyfin
sudo mkdir data cache config log

Бинарник готов, осталось организовать FFmpeg. В связке с Jellyfin рекомендуется использовать кастомный билд который можно взять так же в репозитории. В моем случае это Debian, поэтому просто находим deb пакет и ставим.

wget https://repo.jellyfin.org/files/ffmpeg/debian/latest-7.x/amd64/jellyfin-ffmpeg7_7.1.1-2-bookworm_amd64.deb
sudo dpkg -i jellyfin-ffmpeg7_7.1.1-2-bookworm_amd64.deb

Создадим скрипт jellyfin.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

Файлу дадим права на запуск и назначим пользователя:

sudo chown -R user:group *
sudo chmod u+x jellyfin.sh

Далее создаем systemd службу которая будет запускаться автоматически при старте системы. Создадим файл /etc/systemd/system/jellyfin.service

[Unit]
Description=Jellyfin
After=network.target

[Service]
Type=simple
User=youruser
Restart=always
ExecStart=/opt/jellyfin/jellyfin.sh

[Install]
WantedBy=multi-user.target

По классике перезагружаем демон systemd и запускаем. Так же не забываем поставить на автостарт

sudo systemctl daemon-reload
sudo systemctl enable jellyfin.service
sudo systemctl start jellyfin.service

NVENC в Jellyfin

Предварительно ознакомьтесь с разделом Nvidia Driver и NVENC в Debian

В разделе Administration -> Playback -> Transcoding переключите на Nvidia NVENC. В зависимости от желаемого поведения, поставьте галочки напротив интересующих кодеков. Чаще всего проставлять везде не обязательно, если фильмы храните в каком-то определенном формате.

Далее запустите фильм в UI Jellyfin и попробуйте понизить качество, к примеру до 10 Mbit

Если настроенно корректно, то в панели статистики увидите что производится транскодинг, будет указана причина почему он происходит и в nvidia-smi увидим процесс который использует NVENC.

Важно уточнить, что транскодинг производится в случаях когда:

  • Не хватает скорости интернет-соединения
  • Когда принудительно выставлена скорость потока воспроизведения
  • Когда исходный кодек несовместим с устроиством воспроизведения. К примеру браузер компьютера не может воспроизводить HEVC нативно. (см. скрин выше).

Если происходит ошибка воспроизведения при запуске, то или некорректно работает NVENC, или же несовместимый кодек. О проблеме можно узнать почитав логи воспроизведения которые есть так же в UI админки. Так же убедитесь, что места для транскодинга видео достаточно, обычно - не меньше 8 ГБ

Jellyfin за реверспрокси Nginx

Базовая конфигурация выглядит так:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name YOUR_HOSTNAME;
    ssl_protocols TLSv1.3 TLSv1.2;
    # Здесь серты Let's Encrypt
    ssl_certificate /etc/letsencrypt/live/YOUR_HOSTNAME/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/YOUR_HOSTNAME/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/YOUR_HOSTNAME/chain.pem;

    location / {
        # Proxy main Jellyfin traffic
        proxy_pass http://IP_YOUR_INSTANCE:8096;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;

        # Disable buffering when the nginx proxy gets very resource heavy upon streaming
        proxy_buffering off;
    }

    location /socket {
        # Proxy Jellyfin Websockets traffic
        proxy_pass http://IP_YOUR_INSTANCE:8096;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name YOUR_HOSTNAME;
    return 301 https://$host$request_uri;
}