折腾经历
我的N5105软路由是2022年4月底入手的,BIOS到手就是v5.19这个传说中可以直通核显的版本,但是在ESXi 7.0直通核显给Windows或者Ubuntu虚拟机一直没有成功,表现是直通核显后虚拟机开机出现图形界面即死机。
这里 N5105/N6005 群晖 核显解码 配置参考 是一个用N5105直接物理安装黑群晖DS918+ 6.23的成功实现硬件转码的案例。我把核显直通给黑群晖DS918+6.23虚拟机,按照帖子里的要点可以打上核显补丁,在黑群系统里看到核显,但是jellyfin调用不成功,开启硬件转码后客户端提示“播放错误该客户端与媒体不兼容,服务器未发送兼容的媒体格式
并一直循环报错。用软解CPU自然是100%,卡顿无比,没有实用价值。
这个帖子 软路由N5105硬解方案归纳 归纳了三种N5105核显成功实现硬件转码的情况,宿主机分别是PVE 7.2、Unraid 6.12和Windows server 2019,本质上核显都是在宿主机上实现驱动或者用容器调用宿主机的核显,并没有把核显真正直通给虚拟机。
那么用EXSi做宿主机是否一定不能直通核显到虚拟机实现硬件转码呢?我开始了摸索和尝试,在几篇教程的指引下,终于成功实现了这个目的。
一、ESXi 7开启核显直通
以下这部分内容转载自这里 VMware vSphere(ESXI)7.X直通核显再重启ESXI后仍提示需要直通的解决办法。
自从VMware vSphere(ESXi)升级到7.0以后,改进了一个功能,就是硬件直通以后不需要重启就可以直接添加给虚拟机使用。可是偏偏有不少人会遇到以下情况:直通核显给虚拟机可以正常使用,但是ESXi重启后直通列表里面的核显会变成再次需要直通才能使用,这样的话设置的虚拟机自动启动就无效了。
有人说这是BUG,博主认为这个应该是ESXi的管理机制:每次ESXi重启后,宿主会直接忽视核显直通然后获得核显的使用权,应该是为了防止在直通核显以后又误将管理口网卡直通出去造成ESXI无法进入管理界面的尴尬。这个可以关掉的:
1、在电脑浏览器打开ESXi,在菜单中开启SSH;
2、在电脑上打开MobaXterm或者Putty等软件,用root账号登录到ESXi的SSH下;
3、输入一条命令(须注意英文的大小写和空格),回车:
esxcli system settings kernel set -s vga -v FALSE
4、重启ESXi生效。
N5105 BIOS 版本 : V5.19
N5105 核心显卡的 Device ID : 0x4e61
二、安装Ubuntu 22
在ESXi 7里新建一台虚拟机,建议分配4核CPU和2G~4G内存。我这里的启动设置是默认的BIOS启动,也有论坛玩家反馈需要设置为EFI启动才可以成功添加直通核显。先不要添加核显,用默认的虚拟显卡安装好Debian 11或者Ubuntu 22.04(推荐安装Ubuntu 22.04,因为不用自己折腾non-free的linux 固件),选择安装组件时不要选择任何GUI图形化桌面(如果安装了图形界面,后面直通核显时大概率死机),仅勾选安装SSH Server和基础组件,Ubuntu 要用ubuntu-22.04-live-server-amd64.iso这个安装包,选最小化安装,其他组件可以等安装完成后再apt install。
我在这里就先预留了所有内存,因为后面直通显卡设备有这个要求。也可以等直通显卡时再修改此项配置。
三、开启Ubuntu 22 SSH登录
说明: 以下所有Linux命令都是用root用户执行。如果用普通用户执行,可能需要加上sudo,请自行测试。
因为后面我们要禁用虚拟机默认的虚拟显卡,将会导致虚拟机的控制台不可操作,只能远程SSH登录后操作,所以在操作核显之前,我们要先配置好Debian 11 / Ubuntu 22 的静态IP和SSH登录。
先在线升级一下各组件,下载速度慢的请自行设置一下国内的镜像源:
apt update && apt -y upgrade
安装一下后面要用到的工具
apt -y install vim wget curl open-vm-tools
修改为静态IP
(如果安装时已经设定为静态IP的可以跳过这一步)
Ubuntu 22 设置静态IP
Ubuntu 比 Debian要麻烦一些,Ubuntu从17.10开始,已放弃在/etc/network/interfaces里固定IP的配置,即使配置也不会生效,而是改成netplan方式 ,配置写在/etc/netplan/00-installer-config.yaml或者类似名称的yaml文件里:
vim /etc/netplan/00-installer-config.yaml
先按 i 进入编辑模式,然后修改为下面这个样子,其中ensxxx要和你的实际网卡名字保持一致,IP网关DNS根据实际情况添加(注意每一层前边的缩进,至少比上一层多两个空格):
network:
ethernets:
ensxxx:
addresses:
– 192.168.1.18/24
gateway4: 192.168.1.1
nameservers:
addresses:
– 192.168.1.1
– 114.114.114.114
version: 2
编辑完成后先按ESC,退出编辑模式,再按英文冒号键:然后输入wq最后回车就可以保存并退出。
重启网络让新IP生效:
netplan apply
开启root用户远程登录
如果安装时没安装SSH服务,请先安装:
apt -y install openssh-server
检查状态:
systemctl status ssh
确认SSH服务是enabled状态,可以开机自启动:
修改sshd_config文件允许root用户远程登录:
vim /etc/ssh/sshd_config
先按 i 进入编辑模式,然后找到以下几行并去掉前面的注释标记#号,并修改后面的设定值:
PermitRootLogin yes
PasswordAuthentication yes
编辑完成后 先按ESC,退出编辑模式,再按英文冒号键:然后输入wq最后回车就可以保存并退出。
Ubuntu还需要手动为root用户设置密码:
sudo passwd root
重启SSH服务:
systemctl restart ssh
打开MobaXterm或者Putty等软件,用root账号和密码尝试连接运行在Ubuntu 的IP 22端口上的SSH服务,确定可以正常登录和输入命令。
四、 Ubuntu 22 内核到6.1.8
根据Jellyfin中国特供版作者nyanmisaka等各位大佬的研究,想要让N5105核显开启硬件转码需要升级Linux内核到5.17以上,开启低功耗编码HuC和GuC。
升级Ubuntu 22 内核到6.1.8
Ubuntu 22.04安装好以后是5.15内核,我们把它升级到6.1.8内核:
下载ubuntu-mainline-kernel脚本:
wget https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh
将脚本放在可执行路径中:
install ubuntu-mainline-kernel.sh /usr/local/bin/
检查当前可以下载安装的内核版本:
ubuntu-mainline-kernel.sh -r
返回:
下载安装指定版本内核v6.1.8:
ubuntu-mainline-kernel.sh -i v6.1.8
返回:
Downloading index from kernel.ubuntu.com Will download 6 files from kernel.ubuntu.com: Downloading amd64/linux-headers-5.18.19-051819-generic_5.18.19-051819.202208211443_amd64.deb: 100% Downloading amd64/linux-headers-5.18.19-051819_5.18.19-051819.202208211443_all.deb: 100% Downloading amd64/linux-image-unsigned-5.18.19-051819-generic_5.18.19-051819.202208211443_amd64.deb: 100% Downloading amd64/linux-modules-5.18.19-051819-generic_5.18.19-051819.202208211443_amd64.deb: 100% Downloading amd64/CHECKSUMS: 100% Downloading amd64/CHECKSUMS.gpg: 100% Signature of checksum file has been successfully verified Checksums of deb files have been successfully verified with sha256sum Installing 4 packages Cleaning up work folder
查看当前已通过该脚本安装的内核版本:
ubuntu-mainline-kernel.sh -l
返回:
v6.1.8-060108
重启:
reboot
重启后查看新内核生效了没有:
uname -r
返回:
6.1.8-060108-generic
代表新内核成功启用。
五、直通核显到Ubuntu 22
添加核显PCI设备成为虚拟机硬件
现在关闭 Ubuntu 22 虚拟机,在ESXi 7里将核显PCI设备添加到虚拟机的硬件里:
禁用虚拟显卡
然后在虚拟机选项-高级-配置参数-编辑配置里,将svga.present由TRUE改为FALSE,保存并启动虚拟机。
开机后虚拟机控制台将一直呈现灰色而不可用,稍等片刻可以尝试SSH连接设置好的静态IP的22端口。如果不出意外,应该可以用root用户直接远程登录继续执行下面的操作。
验证核显是否已经加载:
ls -al /dev/dr
返回:
total 0 drwxr-xr-x 3 root root 100 Jul 15 22:07 . drwxr-xr-x 17 root root 3200 Jul 15 22:07 .. drwxr-xr-x 2 root root 80 Jul 15 22:07 by-path crw-rw---- 1 root video 226, 0 Jul 15 22:07 card0 crw-rw---- 1 root render 226, 128 Jul 15 22:07 renderD128
说明核显已经正常识别加载。
Ubuntu 22 检查固件
ls -l /lib/firmware/i915/ehl_guc_69*
ls -l /lib/firmware/i915/ehl_huc_9*
ls -l /lib/firmware/i915/icl_dmc_ver1_09*
返回:
-rw-r--r-- 1 root root 343360 May 13 11:44 /lib/firmware/i915/ehl_guc_69.0.3.bin
-rw-r--r-- 1 root root 498880 May 13 11:44 /lib/firmware/i915/ehl_huc_9.0.0.bin
-rw-r--r-- 1 root root 25952 May 13 11:44 /lib/firmware/i915/icl_dmc_ver1_09.bin
开启核显低功耗编码 HuC 和 GuC
编辑grub配置文件,强制开启 HuC 和 GuC:
vim /etc/default/grub
先按 i 进入编辑模式,然后找到并修改 GRUB_CMDLINE_LINUX_DEFAULT=”quiet” 为:
GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on i915.enable_guc=3 quiet"
编辑完成后 先按ESC,退出编辑模式,再按英文冒号键:然后输入wq最后回车就可以保存并退出。
然后更新grub菜单:
update-grub
或者:
grub-mkconfig -o /boot/grub/grub.cfg
重启:
reboot
补充说明:guc引导项不同的参数不同的作用,具体如下:
i915.enable_guc=1 ## 启用GuC提交和电源管理
i915.enable_guc=2 ## 只启用HuC认证
i915.enable_guc=3 ## 将两个功能结合在一起
##在内核4.16之前,HuC认证是通过设置:
i915.enable_guc_loading=1 ##4.16之前使用此参数开启huc认证
经过我的测试,如果/etc/default/grub这里设置i915.enable_guc=2,GuC submission会是disabled,不确定是否会影响硬件转码,就还是设置为3吧。
至此,核显设置就安装完成了。
安装intel-gpu-tools,可以用intel_gpu_top命令查看gpu的运行状态
apt -y install intel-gpu-tools
重启后,验证低功耗编码HuC和GuC是否开启:
journalctl -b -o short-monotonic -k | egrep -i "i915|dmr|dmc|guc|huc"
返回:
[ 0.000000] debian kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-5.18.0-2-amd64 root=UUID=1ac9bedb-49b8-4a86-b4e5-72b33eb78abd ro intel_iommu=on i915.enable_guc=3 quiet [ 0.043744] debian kernel: Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.18.0-2-amd64 root=UUID=1ac9bedb-49b8-4a86-b4e5-72b33eb78abd ro intel_iommu=on i915.enable_guc=3 quiet [ 3.509988] debian kernel: Setting dangerous option enable_guc - tainting kernel [ 3.509991] debian kernel: Setting dangerous option enable_guc - tainting kernel [ 3.511534] debian kernel: i915 0000:0b:00.0: [drm] VT-d active for gfx access [ 3.511543] debian kernel: i915 0000:0b:00.0: vgaarb: deactivate vga console [ 3.511906] debian kernel: i915 0000:0b:00.0: [drm] Transparent Hugepage mode 'huge=within_size' [ 3.514195] debian kernel: i915 0000:0b:00.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0xffff [ 3.514202] debian kernel: i915 0000:0b:00.0: [drm] Failed to find VBIOS tables (VBT) [ 3.514250] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 3.525794] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 3.525952] debian kernel: i915 0000:0b:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=io+mem [ 3.527603] debian kernel: i915 0000:0b:00.0: firmware: direct-loading firmware i915/icl_dmc_ver1_09.bin [ 3.528081] debian kernel: i915 0000:0b:00.0: [drm] Finished loading DMC firmware i915/icl_dmc_ver1_09.bin (v1.9) [ 4.531068] debian kernel: i915 0000:0b:00.0: [drm] failed to retrieve link info, disabling eDP [ 4.532486] debian kernel: i915 0000:0b:00.0: firmware: direct-loading firmware i915/ehl_guc_69.0.3.bin [ 4.533796] debian kernel: i915 0000:0b:00.0: firmware: direct-loading firmware i915/ehl_huc_9.0.0.bin [ 4.695205] debian kernel: i915 0000:0b:00.0: [drm] GuC firmware i915/ehl_guc_69.0.3.bin version 69.0 [ 4.695214] debian kernel: i915 0000:0b:00.0: [drm] HuC firmware i915/ehl_huc_9.0.0.bin version 9.0 [ 4.709613] debian kernel: i915 0000:0b:00.0: [drm] HuC authenticated [ 4.709763] debian kernel: i915 0000:0b:00.0: [drm] GuC submission enabled [ 4.709766] debian kernel: i915 0000:0b:00.0: [drm] GuC SLPC disabled [ 4.712512] debian kernel: [drm] Initialized i915 1.6.0 20201103 for 0000:0b:00.0 on minor 0 [ 6.089740] debian kernel: i915 0000:0b:00.0: [drm] Cannot find any crtc or sizes [ 6.090267] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 7.459136] debian kernel: i915 0000:0b:00.0: [drm] Cannot find any crtc or sizes [ 7.459592] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 8.863108] debian kernel: i915 0000:0b:00.0: [drm] Cannot find any crtc or sizes [ 21.078282] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 21.078426] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 31.311088] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 31.314778] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal. [ 32.698143] debian kernel: i915 0000:0b:00.0: [drm] *ERROR* VBT claims to have both internal and external displays on PHY A. Configuring for internal.
因为之前并没有在虚拟机里手动导入核显的VBios(这是另外一个复杂的工程),所以有一堆的和VBT有关的*ERROR*,这可能就是虚拟机不能开启图形界面的原因,会导致虚拟机系统进入图形界面时直接卡死。还好我们只是把核显用来解码和编码,最关心的HuC和GuC都成功开启了:
[ 4.532486] debian kernel: i915 0000:0b:00.0: firmware: direct-loading firmware i915/ehl_guc_69.0.3.bin [ 4.533796] debian kernel: i915 0000:0b:00.0: firmware: direct-loading firmware i915/ehl_huc_9.0.0.bin [ 4.695205] debian kernel: i915 0000:0b:00.0: [drm] GuC firmware i915/ehl_guc_69.0.3.bin version 69.0 [ 4.695214] debian kernel: i915 0000:0b:00.0: [drm] HuC firmware i915/ehl_huc_9.0.0.bin version 9.0 [ 4.709613] debian kernel: i915 0000:0b:00.0: [drm] HuC authenticated [ 4.709763] debian kernel: i915 0000:0b:00.0: [drm] GuC submission enabled
特别提示:如果上面的日志里有错误提示加载某个固件.bin不成功,请仔细核对一下文件路径、文件名、文件大小和文件权限,按照日志里的提示到相应的地址下载对应的固件文件,上传到/lib/firmware/i915并设置好文件权限即可。
六、安装Docker
Ubuntu 安装Docker
在Debian / Ubuntu 的SSH中输入命令:
curl -fsSL https://get.docker.com | bash -s docker
下载速度慢的话可以试试指定国内的源,例如阿里云:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
检查:
docker ps -a
如果能看到以下说明成功:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
安装docker-compose
目前docker-compose的最新版本是v2.6.1,如果有更新的版本,请相应替换:
curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
chmod +x /usr/local/bin/docker-compose
创建软链:
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
执行完成后输入:
docker-compose --version
如果能看到版本号的输出,即表示安装成功,例如:
Docker Compose version v2.6.1
七、安装Jellyfin
安装准备
首先需要规划jellyfin安装在什么位置
例如/opt/apps/jellyfin
请注意,如果将来索引和转码的视频数量很多,jellyfin的config和cache文件夹可能膨胀到大几十GB,请确保安装挂载点有足够的磁盘空间可以容纳。
创建jellyfin安装挂载点/opt/apps/jellyfin,并在该处新建三个挂载文件夹config 、cache 和media:
mkdir -p /opt/apps/jellyfin
cd /opt/apps/jellyfin
mkdir config cache media
创建完成后开始编写docker-compose.yml文件:
cd /opt/apps/jellyfin
vim docker-compose.yml
先按 i 进入编辑模式,然后复制以下内容:
version: '3' services: jellyfin: image: nyanmisaka/jellyfin:latest container_name: jellyfin network_mode: host environment: - TZ=Asia/Shanghai - JELLYFIN_PublishedServerUrl=192.168.123.6 volumes: - ${PWD}/config:/config - ${PWD}/cache:/cache - ${PWD}/media:/media restart: unless-stopped privileged: true devices: - /dev/dri:/dev/dri
几点说明:
${PWD}指的是当前目录/opt/apps/jellyfin,
媒体文件夹${PWD}/media即相当于/opt/apps/jellyfin/media,下面我们会把远程共享文件夹直接挂载到这里。它映射到容器里的/media,记住容器和宿主机两个路径的对应关系,在设置jellyfin的时候会用到;
Docker image用的是nyanmisaka大佬开发的Jellyfin中国特供版的开发者的最新版,目前的版本是10.8.1,封装了核显驱动;
JELLYFIN_PublishedServerUrl需要改成本机的IP地址如192.168.123.6,不知道设置为127.0.0.1是否可以(未测试);
devices: – /dev/dri:/dev/dri是把核显挂载到容器内部。
network用host,省去指定端口,http访问的默认端口是8096,如果需要映射到别的端口可以自行修改network_mode和添加ports映射,示例如下:
version: '3' services: jellyfin: image: nyanmisaka/jellyfin:latest container_name: jellyfin network_mode: bridge ports: - 8096:8096 - 8920:8920 - 7359:7359/udp - 1900:1900/udp environment: - TZ=Asia/Shanghai - JELLYFIN_PublishedServerUrl=192.168.123.6 volumes: - ${PWD}/config:/config - ${PWD}/cache:/cache - ${PWD}/media:/media restart: unless-stopped privileged: true devices: - /dev/dri:/dev/dri
端口说明:
ports 说明
8096 WebUI http访问端口
8920 WebUI https访问端口
7359/udp (可选)允许本地网络的客户端发现 Jellyfin
1900/udp (可选)DLNA服务
编辑完成后 先按ESC,退出编辑模式,再按英文冒号键:然后输入wq最后回车就可以保存并退出。
以上就做好了启动Jellyfin的所有准备。
启动Docker容器
输入命令启动Docker容器:
cd /opt/apps/jellyfin
docker-compose up -d
就会开始拉取镜像,并启动jellyfin。
等执行完毕后再次输入:
docker ps -a
就可以看到jellyfin正在运行中:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 002dc50b61a6 nyanmisaka/jellyfin "./jellyfin/jellyfin…" 14 seconds ago Up 12 seconds (health: starting) jellyfin
耐心等待容器初始化完成。
进入容器内部看一下核显是否成功挂载:
docker exec -i -t jellyfin /bin/bash
上面命令中的jellyfin就是docker-compose.yml里设定好的容器名container_name。
在容器内部查看核显是否挂载:
ls -al /dev/dri
返回:
total 0 drwxr-xr-x 2 root root 80 Jul 16 09:29 . drwxr-xr-x 13 root root 2980 Jul 16 09:29 .. crw-rw---- 1 root video 226, 0 Jul 16 09:29 card0 crw-rw---- 1 root 106 226, 128 Jul 16 09:29 renderD128
和在Debian / Ubuntu 宿主机里一样,说明容器成功挂载核显。
输入:
exit
退出容器。
这时在浏览器地址栏输入http:// Ubuntu 的ip地址:8096就可以进入jellyfin后台,例如http://192.168.123.6:8096
八、挂载NFS远程视频文件
我的视频文件全在另一部群晖里,已开启了NFS共享服务NFS版本v4.1,权限为可读写(具体设置方法请在网上搜索群晖NFS设置教程)。以下的设置仅供参考:
为Ubuntu安装NFS客户端:
apt -y install nfs-common
假设远程群晖主机(192.168.123.4)
NFS共享出来了/volume3/Video
这个文件夹,先尝试手动挂载它:
mount -t nfs 192.168.123.4:/volume3/Video /opt/apps/jellyfin/media
检查一下挂载是否成功:
df -hT
成功后可以修改/etc/fstab
实现开机自动挂载(这可能会在后面引起一点小问题,最后有解决办法):
vim /etc/fstab
先按 i
进入编辑模式,添加一行:
192.168.1.19:/volume2/video /opt/apps/jellyfin/media nfs rw,soft,intr 0 0
编辑完成后 先按ESC,退出编辑模式,再按英文冒号键:
然后输入 wq!
最后回车就可以保存并退出。
媒体文件确定挂载成功后,需要重启容器一次让jellyfin读取它:
cd /opt/apps/jellyfin
docker-compose restart
或者先停止再启动
docker-compose stop
docker-compose up -d
九、设置jellyfin
访问http://Ubuntu的ip地址:8096
例如http://192.168.123.6:8096
,开始设置,具体设置方法可参考 群晖用Jellyfin实现GPU硬解实时转码 。
设置媒体文件夹时要注意:
媒体文件夹在容器内的路径是 /media
,jellyfin设置页面添加媒体文件夹的路径应该用容器内的路径如/media/movie
、/media/tv
,因为容器内的/media
被映射到我们上面设置好的宿主机/opt/apps/jellyfin/media
,容器内/media/movie
对应的就是宿主机/opt/apps/jellyfin/media/movie
,以此类推。
十、开启硬件转码
按下面的图片内容来设置硬件转码,设置完保存即可:
十一、验证硬件转码效果
##测试视频一
测试片源America.Wild.National.Parks.Adventure.2016.BluRay.2160p.x265.10bit.HDR.2Audio.mUHD-FRDS.mkv
,带字幕烧录:
###关闭硬件转码测试
纯CPU转码,转码为1080p 10Mbps H264视频,转码帧率只有20fps:
###开启硬件转码测试
开启硬件转码后,还是转码为1080p 10Mbps H264视频,转码帧率53fps:
###CPU占用对比
###日志验证
/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -ss 00:32:21.000 -init_hw_device vaapi=va:,driver=iHD,kernel_driver=i915 -init_hw_device qsv=qs@va -init_hw_device opencl=ocl@va -filter_hw_device qs -hwaccel vaapi -hwaccel_output_format vaapi -autorotate 0 -canvas_size 1920x1080 -i file:"/media/4k_uhd/狂野之美:国家公园探险.America.Wild.National.Parks.Adventure.2016.BluRay.2160p.x265.10bit.HDR.2Audio.mUHD-FRDS/America.Wild.National.Parks.Adventure.2016.BluRay.2160p.x265.10bit.HDR.2Audio.mUHD-FRDS.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -codec:v:0 h264_qsv -low_power 1 -preset 7 -look_ahead 0 -b:v 9616000 -maxrate 9616000 -bufsize 19232000 -profile:v:0 high -level 51 -g:v:0 72 -keyint_min:v:0 72 -filter_complex "[0:3]scale=flags=fast_bilinear,format=bgra,hwupload=derive_device=qsv:extra_hw_frames=64[sub];[0:0]setparams=color_primaries=bt2020:color_trc=smpte2084:colorspace=bt2020nc,scale_vaapi=w=1920:h=1080,hwmap=derive_device=opencl,tonemap_opencl=format=nv12:p=bt709:t=bt709:m=bt709:tonemap=bt2390:peak=100:desat=0,hwmap=derive_device=qsv:reverse=1:extra_hw_frames=16,format=qsv[main];[main][sub]overlay_qsv=eof_action=endall:shortest=1:repeatlast=0:w=1920:h=1080" -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 647 -hls_segment_filename "/config/transcodes/c2b53203519dbbad0f8d5dd9788b228e%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/transcodes/c2b53203519dbbad0f8d5dd9788b228e.m3u8"
Stream mapping:
Stream #0:0 (hevc) -> setparams:default (graph 0)
Stream #0:3 (pgssub) -> scale:default (graph 0)
overlay_qsv:default (graph 0) -> Stream #0:0 (h264_qsv)
Stream #0:1 -> #0:1 (truehd (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
##测试视频二
采用Jellyfish视频比特率测试文件,选择最高码率400Mbps的视频,29秒的视频文件大小达到1.4GB:
jellyfish-400-mbps-4k-uhd-hevc-10bit.mkv
还是转码为1080p 10Mbps H264视频,转码帧率44fps:
###日志验证:
十二、补充设置
后续使用中发现虚拟机重启后,因为NFS挂载需要一点时间,但是Docker已经启动,会发生jellyfin无法识别媒体文件夹内容的情况,表现是播放文件弹出“播放错误该客户端与媒体不兼容,服务器未发送兼容的媒体格式
”提示,和硬解没有成功开启的提示是一样的,但查看核显状态是正常。
执行:
docker-compose restart
后错误消失。
解决思路就是延迟启动Docker服务,等待NFS挂载成功后再启动:
##取消Docker开机自启动
systemctl disable docker.service
##用/etc/rc.local
延迟启动Docker服务
从Ubuntu22 默认不带 /etc/rc.local
文件,而rc.local
服务却还是自带的,需要手工添加一个 /etc/rc.local
文件:(以下为一整条命令,请一起复制到ssh命令行运行)
cat <<EOF >/etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0
EOF
然后赋予可执行权限:
chmod +x /etc/rc.local
接着启动 rc-local
服务:
systemctl enable --now rc-local
此时可能会弹出警告:
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
不用管它,因为这个服务没有任何依赖的系统服务,只是开机执行 /etc/rc.local
脚本而已。
再次查看状态:
systemctl status rc-local.service
返回:
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
Drop-In: /usr/lib/systemd/system/rc-local.service.d
└─debian.conf
Active: active (exited) since Sat 2022-07-16 12:27:14 HKT; 46s ago
Docs: man:systemd-rc-local-generator(8)
Process: 37576 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
CPU: 1ms
Jul 16 12:27:14 debian systemd[1]: Starting /etc/rc.local Compatibility...
Jul 16 12:27:14 debian systemd[1]: Started /etc/rc.local Compatibility.
然后就可以把需要开机启动的命令添加到 /etc/rc.local
文件,放到在 exit 0
前面即可。
编辑/etc/rc.local
文件:
vim /etc/rc.local
先按 i
进入编辑模式,在文件末尾exit 0
之前追加如下内容:
sleep 300
systemctl restart docker.service
编辑完成后 先按ESC
,退出编辑模式,再按英文冒号键:
然后输入wq
最后回车就可以保存并退出。
说明:sleep 300
的意思是延迟5
分钟启动Docker,这里用restart
是为了保证万一Docker已经被另外的脚本启动,就重启它。如果Docker还没有启动执行restart也会启动它。
重启服务器进行测试:
reboot
稍等几分钟,尝试访问和播放视频,到此为止,应该可以愉快的看片了。如果想在外网也能看,再设置一下upnp或在路由器上手动映射端口。
再次感谢各位无偿分享的大佬!如果你觉得nyanmisaka/jellyfin
好用,欢迎向Jellyfin中国特供版的开发者nyanmisaka大佬捐赠。