LXC安装JellyFin并轻松开启硬件编码

前言

如果你是一个 Proxmox 用户又恰好装了群晖,想让群晖里的 Docker 里装的 Jellyfin 使用硬件解码是一件十分复杂的事情。另外,如果为了使用显卡硬件解码而安装一个虚拟机也会十分复杂,主要原因是 Intel 显卡直通的配置十分复杂而且成功与否因主板而异。

最简单的方法莫过于直接将 Jellyfin 安装到宿主机的 Debian 系统中,可惜这样做不是很优雅。Jellyfin 侵入了 Proxmox 的环境,如果对 Linux 不是非常熟悉,在管理 Jellyfin 时可能会影响到其他软件。LXC 提供了一套很好的解决方案,在保留了 Proxmox 优秀的管理能力的同时,又让配置不是很复杂。

最直观的感受就是在安卓手机使用 Proxmox 管理虚拟机,可以看到虚拟机的性能曲线,可以方便地扩缩容,还可以直接在手机上进入某个系统的控制台。

创建支持挂载显卡的容器

创建 CT注意取消选中非特权容器访问硬件需要特权容器,我创建的容器ID为109 (记住这个ID后文要用)
创建ID 109 容器
系统我选择了ubuntu18.04,其他系统操作也一样
ubuntu18.04
直接默认
网络设置一个 ip,注意 ip 需要加上 netmask 也就是后面的/24
网络配置
配置完成后直接启动容器。

在容器中安装jellyfin

启动容器以后先配置一下软件源,具体操作可以参考阿里云镜像源。
这一步可以选做,用默认镜像源在国内只是下载速度会慢一些。

1
2
apt update
apt upgrade

接着根据官方教程安装
https://jellyfin.org/docs/general/administration/installing.html#ubuntu
安装完后执行 service jellyfin status,显示状态为 running 说明安装成功.
顺便搬运一下官网的安装流程:

1
2
3
4
5
6
sudo apt install apt-transport-https software-properties-common
sudo add-apt-repository universe
wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo apt-key add -
echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list
sudo apt update
sudo apt install jellyfin

运行service jellyfin status查看jellyfin状态。
4

在浏览器中输入 http://容器ip:8096 就可以进入jellyfin,对显卡硬解没有需求的值友来说,再把nas的电影目录挂载到容器中,已经可以开始用了。如果希望jellyfin能进行实时转码,cpu又不太好可以接着配置显卡硬解。

重头戏,配置显卡挂载

第一步 安装宿主机的显卡驱动

以下操作在宿主机执行
以下操作在宿主机执行
以下操作在宿主机执行

进入宿主机的shell

  1. 常规操作,更新一下 apt
    1
    apt update
  2. 安装驱动和检测工具
    1
    apt install i965-va-driver vainfo
  3. 检查显卡解码工作状态
    执行vainfo,如果显示出支持的各种编解码信息(Supported profile and entrypoints)说明驱动安装成功。
    如果执行报错或者没有正确试别解码配置,检查是否阻止了模块加载。(比如配置显卡直通的时候会配置驱动黑名单,让宿主机不要加载显卡的驱动,让位给vfio。)
    写这篇文章的时候用于演示的CPU是G5400,核心显卡型号为hd600。
    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
    root@pve:~# vainfo
    error: can't connect to X server!
    libva info: VA-API version 1.4.0
    libva info: va_getDriverName() returns 0
    libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
    libva info: Found init function \_\_vaDriverInit_1_4
    libva info: va_openDriver() returns 0
    vainfo: VA-API version: 1.4 (libva 2.4.0)
    vainfo: Driver version: Intel i965 driver for Intel(R) Coffee Lake - 2.3.0
    vainfo: Supported profile and entrypoints
    VAProfileMPEG2Simple : VAEntrypointVLD
    VAProfileMPEG2Simple : VAEntrypointEncSlice
    VAProfileMPEG2Main : VAEntrypointVLD
    VAProfileMPEG2Main : VAEntrypointEncSlice
    VAProfileH264ConstrainedBaseline: VAEntrypointVLD
    VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
    VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
    VAProfileH264Main : VAEntrypointVLD
    VAProfileH264Main : VAEntrypointEncSlice
    VAProfileH264Main : VAEntrypointEncSliceLP
    VAProfileH264High : VAEntrypointVLD
    VAProfileH264High : VAEntrypointEncSlice
    VAProfileH264High : VAEntrypointEncSliceLP
    VAProfileH264MultiviewHigh : VAEntrypointVLD
    VAProfileH264StereoHigh : VAEntrypointVLD
    VAProfileVC1Simple : VAEntrypointVLD
    VAProfileVC1Main : VAEntrypointVLD
    VAProfileVC1Advanced : VAEntrypointVLD
    VAProfileNone : VAEntrypointVideoProc
    VAProfileJPEGBaseline : VAEntrypointVLD
    VAProfileJPEGBaseline : VAEntrypointEncPicture
    VAProfileVP8Version0_3 : VAEntrypointVLD
    VAProfileHEVCMain : VAEntrypointVLD
    VAProfileHEVCMain10 : VAEntrypointVLD
    VAProfileVP9Profile0 : VAEntrypointVLD
    VAProfileVP9Profile2 : VAEntrypointVLD

第二步 让容器可以使用显卡

  1. 获取显卡分组信息
    这部分操作在宿主机执行
    输入以下命令

    1
    ls -l /etc/dri

    以下是命令输出内容

    1
    2
    3
    4
    5
    root@pve:~# ls -l /dev/dri/
    total 0
    drwxr-xr-x 2 root root 80 Oct 13 12:39 by-path
    crw-rw---- 1 root video 226, 0 Oct 13 12:39 card0
    crw-rw---- 1 root render 226, 128 Oct 13 12:39 renderD128

    这里的操作是挂载显卡的关键。先找到card0,可以看到设备号“226,0”,再找到renderD128,可以看到设备号为”226,128”。
    记下card0的设备号为226:0,renderD128的设备号为226:128。

  2. 将显卡挂载到虚拟机
    proxmox的每个lxc都有一个配置文件,这些容器配置文件放在/etc/pve/lxc下,命名为 “虚拟机ID.conf”。
    下面的所有109都是指容器ID,如果你的容器ID不是109需要自行替换命令中的109。
    使用nano编辑109号容器的配置

    1
    nano /etc/pve/lxc/109.conf

    在配置文件末尾加入

    1
    2
    3
    4
    5
    lxc.cgroup.devices.allow: c 226:0 rwm
    lxc.cgroup.devices.allow: c 226:128 rwm
    lxc.cgroup.devices.allow: c 29:0 rwm
    lxc.autodev: 1
    lxc.hook.autodev: /var/lib/lxc/109/mount_hook.sh

    其中226:0和226:128是上一步获得的设备号

    使用nano创建mount_hook.sh

    1
    nano /var/lib/lxc/109/mount_hook.sh

    加入

    1
    2
    3
    4
    mkdir -p ${LXC_ROOTFS_MOUNT}/dev/dri
    mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/card0 c 226 0
    mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/renderD128 c 226 128
    mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/fb0 c 29 0

    以上这些配置的目的是让容器拥有访问显卡设备的权限。

第三步 验证容器是否可以进行硬解

以下操作全部在容器的控制台中完成。接下来进入109容器控制台。

  1. 检查显卡设备是否存在
    ls /dev/dri
    应该存在两个设备,分别是 card0 renderD128,说明容器成功挂载了这两个设备。
  2. 检查解码是否正常
    vainfo
    如果与刚才宿主机执行这条命令输出内容相似说明解码正常。
  3. 启用jellyfin硬件解码
    在jellyfin中硬件转码的设置在控制台->服务器->播放,把硬件加速改为VAAPI,在下面的VAAPI设备里输入/dev/dri/renderD128。
    5
    6
    此时只要打开的视频编码是显卡支持硬解的编码类型,转码就会使用显卡完成,大幅度降低cpu的压力。
    7
    如果在看电影过程中发现黑屏或者花屏,可以适当关闭一部分编码的硬件编码。

总结

LXC安装jellyfin搭配手机控制软件proxmon可以直观地监视容器与虚拟机的状态,让家庭影音系统的搭建更加方便灵活。配合硬解可以很好地利用上因为安装了proxmox而闲置的核显资源。
8


LXC安装JellyFin并轻松开启硬件编码
https://blog.timzhong.top/2020/10/13/jellyfin-in-lxc/
作者
TimZhong
发布于
2020年10月13日
许可协议