基于 Jellyfin 和 aliyundrive-fuse 打造家庭媒体库

前言

之前介绍过aliyundrive-webdav 项目项目已经实现了通过 WebDAV 访问阿里云盘内容,在其基础上配合 rclone 已经可以实现将 WebDAV 挂载为本地磁盘后提供给 Emby/Jellyfin 之类的多媒体内容管理系统使用。虽然这样基本能够工作,但过于复杂了,增加 rclone 只是因为 Jellyfin 之类的软件原生不支持直连 WebDAV 服务,所以为了去掉中间商 rclone,一种方法是给 Jellyfin 写个支持读取 WebDAV 的插件,而这需要使用 C# 语言实现并且需要学习了解 Jellyfin 的插件接口,不是很熟故放弃这条路径;二是直接实现与 rclone 类似的挂载为本地磁盘的功能,Linux 和 macOS 上都支持 FUSE(Filesystem in Userspace),Rust 也有对应的库 fuser 可以直接使用,于是便开发了 aliyundrive-fuse 这个项目。

aliyundrive-fuse

之前 aliyundrive-webdav 的已有代码是面向 Rust 异步 async/await 特性设计的,而目前 fuser 还不支持异步只有同步的接口,故将之前访问阿里云盘的接口从异步改成了同步实现,得益于 reqwest 库同时提供了基本一致的异步和同步接口,改造成本很低。而后只需要实现 fuser 的 Filesystem trait 的几个方法就可以实现一个简单的只读文件系统。

相对比较麻烦的地方是,由于 FUSE 文件系统单次读请求的大小都比较小,比如 Linux 上最大也就 128KB,这对于需要发起网络请求下载数据的场景就是灾难,因此需要缓存一个相对较大的大小比如 10MB,来避免每次读取都需要发起网络请求。解决了这个问题,文件读取速度就有了较好的保障,但因为缓存一次要下载 10MB 的数据,在读取到还没有被缓存的位置的时候需要等待网络请求传输完成,结果就可能导致视频在串流播放的时候偶尔出现卡顿的情况。不过只要播放器也会提前下载后续需要播放的内容倒也不是大问题,至少在配合 Jellyfin 使用的情况下还是挺流畅的没有明显问题。

安装配置

aliyundrive-fuse 提供了很多种安装方式,最简单的可以通过 pip 安装:pip install aliyundrive-fuse ,安装好之后提前通过阿里云盘网页版本获取 refresh token,然后就可以配置挂载了,以 Linux 系统为例,这里我们在 /mnt/aliyundrive 目录挂载磁盘:

# 先新建目录
mkdir -p /mnt/aliyundrive /etc/aliyundrive-fuse
# 挂载磁盘
aliyundrive-fuse -r your-refresh-token -w /etc/aliyundrive-fuse /mnt/aliyundrive

其中 your-refresh-token 替换为你的云盘 refresh token 值。

以 Docker 安装的 Jellyfin 为例,我们需要将刚刚挂载好的阿里云盘目录也 mount 到 Docker 容器中,这里假设 Jellyfin 工作路径为 /root/jellyfin 将云盘挂载到容器 /media 路径:

docker run -d --name jellyfin \
-v /root/jellyfin/config:/config \
-v /root/jellyfin/cache:/cache \
-v /mnt/aliyundrive:/media \
-p 8096:8096 \
--device=/dev/dri/renderD128 \
--device /dev/dri/card0:/dev/dri/card0 \
--restart unless-stopped \
jellyfin/jellyfin

然后访问 Jellyfin 容器的 8096 端口进入控制台添加媒体库。

媒体库管理

在媒体库设置中将文件夹的位置选择挂载好的阿里网盘即可: image.png

等待媒体库扫描完成后即可

Enjoy!

Some rights reserved
Except where otherwise noted, content on this page is licensed under a Creative Commons Attribution-NonCommercial 4.0 International license.