安装Jellyfin并配置硬件加速

如果在外网播放家里NAS中的视频,通常会遇到2个问题:带宽不足和编码不支持。这时候我们就需要NAS对原始视频进行二次编码,然后将低码率的视频推送到设备上,能完成这项任务的软件有3个:Plex、Emby和Jellyfin,鉴于前两个都需要付费才能解锁完整功能,我们自然优先选择开源免费的Jellyfin。

安装Jellyfin

Jellyfin为我们提供了一键安装脚本,能够自动检测系统环境,配置软件源并完成安装。

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

安装完成后,使用IP+端口的方式访问Jellyfin的Web界面,完成后续配置。
http://your_local_IP_address:8096

配置硬件加速

默认情况下,Jellyfin使用CPU进行视频编解码,速度慢,功耗高,所以最好使用GPU来转码,以提高性能。

Intel GPU

Intel的GPU主要支持QSV和VA-API两种硬件加速方式。QSV性能好,但只支持5代以后的GPU;VA-API性能差,但支持几乎所有的GPU。

  1. 安装jellyfin-ffmpeg

    1
    sudo apt update && sudo apt install -y jellyfin-ffmpeg7
  2. 确认/dev/dri/render节点是否存在

    • PromoxVE中的LXC容器,编辑/etc/pve/lxc/<CONTAINER_ID>.conf

      1
      2
      3
      lxc.cgroup2.devices.allow: c 226:0 rwm
      lxc.cgroup2.devices.allow: c 226:128 rwm
      lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
  3. 将jellyfin用户添加到render组

    1
    2
    sudo usermod -aG render jellyfin
    sudo systemctl restart jellyfin
  4. 安装intel-opencl-icd

    1
    sudo apt install -y intel-opencl-icd
  5. 检查当前GPU支持的编码格式,以及OpenCL运行状态

    1
    2
    sudo /usr/lib/jellyfin-ffmpeg/vainfo --display drm --device /dev/dri/renderD128
    sudo /usr/lib/jellyfin-ffmpeg/ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device opencl@va
  6. 配置Jellyfin硬件转码

    打开Jellyfin > 控制台 > 播放 > 转码

    • 硬件转码: Intel QuickSync (QSV)
    • QSV设备: /dev/dri/renderD128
    • 启用硬件解码: 根据当前GPU支持的解码格式选择
    • 启用硬件编码: 根据当前GPU支持的编码格式选择
    • 启用VPP色调映射

配置Nginx反向代理

如果需要使用域名或者https访问Jellyfin服务,可以配置Nginx的反向代理功能。

/etc/nginx/conf.d/jellyfin.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Uncomment the commented sections after you have acquired a SSL Certificate
server {
listen 80;
listen [::]:80;
# server_name DOMAIN_NAME;

# Uncomment to redirect HTTP to HTTPS
# return 301 https://$host$request_uri;
#}

#server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
server_name DOMAIN_NAME;

# use a variable to store the upstream proxy
# in this example we are using a hostname which is resolved via DNS
# (if you aren't using DNS remove the resolver line and change the variable to point to an IP address e.g `set $jellyfin 127.0.0.1`)
set $jellyfin jellyfin;
resolver 127.0.0.1 valid=30;

#ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem;
#include /etc/letsencrypt/options-ssl-nginx.conf;
#ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
#add_header Strict-Transport-Security "max-age=31536000" always;
#ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem;
#ssl_stapling on;
#ssl_stapling_verify on;

# Security / XSS Mitigation Headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

# Content Security Policy
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
# Enforces https content and restricts JS/CSS to origin
# External Javascript (such as cast_sender.js for Chromecast) must be whitelisted.
#add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com/cv/js/sender/v1/cast_sender.js https://www.gstatic.com/eureka/clank/95/cast_sender.js https://www.gstatic.com/eureka/clank/96/cast_sender.js https://www.gstatic.com/eureka/clank/97/cast_sender.js https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'";

location = / {
return 302 http://$host/web/;
#return 302 https://$host/web/;
}

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

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

# location block for /web - This is purely for aesthetics so /web/#!/ works instead of having to go to /web/index.html/#!/
location = /web/ {
# Proxy main Jellyfin traffic
proxy_pass http://$jellyfin:8096/web/index.html;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
}

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

参考

https://miaotony.xyz/2023/11/26/Server_HomeLab_4_GPUtranscoding/

https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration/

Downloads - Jellyfin: The Free Software Media System

Home | Documentation - Jellyfin Project

Intel media stack on Ubuntu · Intel-Media-SDK/MediaSDK Wiki · GitHub

software recommendation - How to measure GPU usage? - Ask Ubuntu

linuxserver/jellyfin:10.6.4-1-ls96 broke Intel Quicksync (most likely due to jellyfin-ffmpeg4.3.1-4-focal) · Issue #96 · linuxserver/docker-jellyfin · GitHub

Hardware video acceleration - ArchWiki