From 7fc4da6b14c50e61ab2b8a510ec44e4392a31e04 Mon Sep 17 00:00:00 2001 From: "SilverAg.L" Date: Sun, 15 Feb 2026 18:38:56 +0800 Subject: [PATCH] Rewrite Diary: nas media Signed-off-by: SilverAg.L --- docs/diaries/wbsy/nas-media.md | 143 ++++++++++++++++++++++++++++++--- 1 file changed, 130 insertions(+), 13 deletions(-) diff --git a/docs/diaries/wbsy/nas-media.md b/docs/diaries/wbsy/nas-media.md index adee54c..c748d63 100644 --- a/docs/diaries/wbsy/nas-media.md +++ b/docs/diaries/wbsy/nas-media.md @@ -1,26 +1,143 @@ -# 元数据刮削就是一笔糊涂账 +# Jellyfin 真的好用吗? -> [!warning] -> 本文所抛出的观点**并未经过严谨的论证,且容易引起争论**。读者们看个乐就是,文中的论述莫要当真。换句话说,**“这家伙叽里咕噜说什么呢?”** +我的结论是:实则不然。但 DIY 这一块本就是矮个子拔高个,也没那么多平替可以挑。 -虽然主要差异在于思维方式——毕竟我还是更习惯基于文件和目录的树形资源管理,但在讨论之前我不得不承认:**元数据的收集整理(即刮削)相对来说很有必要**。听起来就……左右脑互搏,对吧?~~本文之所以是篇"无病呻吟",正因为犯这个病的大抵只有我一个。~~ +> [!important] +> - 本文字里行间夹带着作者的私货,行文并不严谨,谨慎阅读。 +> - 本文有关的折腾流程时间跨度较长,经验之谈不说没有,也只能说碎得跟渣一样。~~所以不是笔记而是大作文。~~ -我的观点很简单:元数据有用,但并不好用。要说什么方案更好?对不起,我也不知道。 +## 硬件加速,硬件呢 -首先还是说说为什么值得肯定。不说别的,至少分类的角度多了。同是音乐,我可以看专辑、看艺术家,当然也可以直接随便 roll 一些单曲来听。从用户体验上说,图像就是比冷冰冰的文字更抓眼球,一排排专辑封面、电影海报总要好过全是文件夹图标、甚至只有一排排文件名、文件路径的。 +我是 Linux Docker 部署的。由于因特耳的核显驱动闭源,**官版 Docker 容器搞起来后还需要`exec -it`进去装 Intel 驱动**。即便是`nyanmisaka`版开箱即用 Jellyfin 镜像,也需要**手动映射渲染节点**(他们就没设置过`render`用户组,若要**映射整个`/dev/dri`后续就需要进去`groupadd`**)。 -但……为什么我又要攻击它呢?因为用户体验好了,管理体验就要折磨。 +::: details docker-compose.yml +See [AgxCOy@liteyuki/agserver.svc](https://git.liteyuki.org/AgxCOy/agserver.svc). +```yaml +services: + jellyfin: + image: nyanmisaka/jellyfin:latest + container_name: jellyfin + network_mode: 'host' + volumes: + - /var/lib/jellyfin:/config + - jellyfin-cache:/cache + - /media:/media + # - /dev/dri/renderD128:/dev/dri/renderD128 + - type: bind + source: /usr/share/fonts/opentype + target: /usr/local/share/fonts/custom + read_only: true + devices: + - /dev/dri/renderD128:/dev/dri/renderD128 + #- /dev/dri/card0:/dev/dri/card0 + restart: 'unless-stopped' + # Optional - alternative address used for autodiscovery + # environment: + # - JELLYFIN_PublishedServerUrl= + extra_hosts: + - 'host.docker.internal:host-gateway' +volumes: + jellyfin-cache: + driver: local +``` +::: -现如今的媒体库,基本上按影视、图像、音乐、文档分类,工具选用上属于没什么平替。论及私人图书馆总绕不开 Calibre,论音像库讨论比较多的就 Jellyfin、Emby、Plex(姑且不讨论品牌家的原生工具,毕竟我没钱)。这些工具对于传统的音像、图书资源支持非常好,**只要刮削得当**,通常能得到比较干净的媒体库。是的,《只要刮削得当》。 +## 媒体库组织 -然鹅事实上,光是音乐专辑的刮削就足以令我恼火。国内**原生**对音乐元数据的刻写做得比较好的可能就网易云,何况网易云也并不全对;有些音乐平台下载的歌曲文件甚至莫得元数据,需要手动刮削。那么刮削用什么呢?有[文章](https://sspai.com/post/90896)推荐 MusicTag,然鹅同是从网易云那刮削,下载下来本是《紫罗兰永恒花园 OST》的曲目能给它识别成《凹凸世界五周年》,也是看笑了。 +我还是更习惯树形文件系统,媒体库还是太难为我了。那样的话,事情或许也很简单——许多成品 NAS 都有自带视频、相册之类的浏览功能。但很遗憾,自己装的 Ubuntu Server 自然什么都没有。 + +我针对的还是 Jellyfin “神奇”的资源组织方式。就像[这篇《基于 Jellyfin 和音流的 nas 影音库搭建及踩坑》](https://sspai.com/post/90896)所说,“为什么不直接读取音乐标签进行专辑聚合”呢? + +### 音乐:混乱的元数据 + +然而事实上,即使真的能做到自动专辑聚合,元数据本身的刻录和查询也是一片混乱。上面援引的博文推荐 MusicTag 这个工具,但同是从网易云那刮削,下载下来本是《紫罗兰永恒花园 OST》的曲目能给它识别成《凹凸世界五周年》,也是给我看笑了。更别说国外的 MusicBrainZ 数据库有相当一部分冷门曲目并没有收录(尽管 Spotify 等平台能够找到),手动录入更是个吃力不讨好的体力活。 ![误刮削](./musictag-misfetch.webp) -那国外平台呢?更是有相当一部分扫不出来。有些作者也不过是兴趣使然、随便做做,别说全平台了,能当专辑、EP 发到某一个平台上都已经烧高香了。这种叫冷门资源。还有一些歌曲能在 Spotify、SoundCloud 找到,但数据库网站就是没有收录。可不要认为比例不多,musicbrainz 扫不出来的歌占我歌库的 $\frac{1}{3}$。手动录入又十分繁琐,不就只能凑合用了,好用吗?实则不然。 +::: tip 最简方案 +文档这么说:我管你怎么整理,我只知道**是同一张专辑就该塞在同一个文件夹**。 -另一方面,影视、音乐、图书的分类并不能兼顾新兴媒体类型,比如音声,比如网文。豆瓣或许能够一定程度上打打辅助,那我问你,NSFW 资源呢?遗憾的是,我维护的大部分媒体都是 NSFW 的。这类资源刮削没有门路、媒体类型不好界定,组织起来尤其折磨。DLsite 上的同人音声尚有`dvtag`,国内作者通过订阅、打赏分发的音声又要如何应对?视频网站上薅下来的视频是可以有元数据,那些通过网盘分发的 MMD 呢?就很烦,哥们。 +那么事情也好办,就按专辑名来呗。好比如:`music/{album or "[standalone]"}/{artist1,artist2} - {title}`。 -总而言之,私以为媒体资源的元数据就是一笔糊涂账,很大程度上资源组织依然仰赖人工,对我个人而言体验并没有多少质的提升,反倒因为刮削需要解决的种种问题而身心俱疲。 +- 为什么要`or "[standalone]"`? + - 不单独收纳**没有专辑**的单曲,结果就会被淹没在大几百首、好几页的“歌曲”页面。 -> 话又说回来,我看多数的资源网站,基本采取论坛体、博客体、挂 Alist 这几种形式,或许也表明刮削比起长痛、短痛,更像是持续的剧痛(规模较大、源源不断、出处难辨)。 +- 要是有专辑重名了(比如两张专都叫`Fragrance`)? + - 没招,默认合并(甚至可以看到重复的曲号,都是第六首)。只能手工分离(`Fragrance - SoundzImage`和`Fragrance - Hatsune Miku`)。 +::: + +### 电子书:组织难绷,查阅也难绷 + +至于小说漫画,或者说书籍媒体库,那只能说真搭一个私人图书馆也是同样的格式要求。平时在各种论坛搜罗的 TXT、DOC(X) 显然难登“书架”之上。 + +但 Jellyfin 对书籍库的编排属于是并不上心(也许他们真在用 Calibre?到处都能看到推荐它的),默认是文件夹视图,却又因为元数据裸放要求一本(或者说一章?一话?)一个文件夹。这棵文件夹子树能长多繁茂我都不敢想。 + +::: tip 最简方案 +那当然是通通转换成 PDF,单纯当作文件管理器那样访问文件夹、文件最简单。只是这种方法对于文字读物不太友好。毕竟 **PDF 只能缩放整页,内容又不会自适应**。 +::: + +尝试一番之后,的确还是适应它们那一套更为高效。Jellyfin 这边对于文本读物最友好的还是 EPUB(当然阅读体验也就那样,但总比 PDF 好)。至于漫画,通用的扩展名是`.cbz`、`.cbr`、`.cb7`(对应`.zip` `.rar` `.7z`)。其中 Jellyfin 只支持前两种。查了下 vivo 的 BlueLM Copilot,似乎`.cbr`的支持也算不上好,所以建议还是`.cbz`。 + +元数据这一块,Jellyfin 似乎集成在电子书里还是裸放均可(仅考虑上述格式)。我还是觉得集成更好,要不然漫画每一话都开一个文件夹裸放`.cbz`和`ComicInfo.xml`,我是觉得有些抽象。 + +::: info EPUB 索引 +现有的 EPUB 编辑器几乎都是放个 HTML 编辑器让用户手改。基于此,的确不如考虑用在线转换器,一键导入 TXT 等通用格式。但这种转换出来的 EPUB 的目录似乎无法跳转(只能逐页翻),暂时还不知道怎么回事。 +::: + +### 元数据刮削:一笔糊涂账 +前面我也论述过,音乐专辑的元数据库就是几桌草台班子。但比起草台班子,更令我恼火的当属大把大把的、查无此作的“黑户”。怎么来的?音声、同人志、网文。 + +> 我的整理方式和 acgdb 类似:3D 区、音声区(作者分发、油管录播、DLsite 正作)、书目区(漫画和文集)、写真区、插画区。 + +3D 区无论玩恋活还是 MMD,既有图集又有视频,无法按媒体类型区分(即便真要分,它算电视节目?电影?MV?分不明白)。音声区大量的音频资源,摆烂一点直接用电子书库、按文件夹访查也不是不行,但显示出来反倒是专辑名(或者说 DLsite、系列作品名)更显眼,而非每一集的标题;若要用音乐库收纳,就得改造一番目录树适配它那个“一个专辑只有一个目录”的原则,工作量也不小。 + +偏偏这种不在台面上的“资源”我收纳了不少,哪怕有自动化工具,后续校对也是个体力活,何况很多资源只能一件件手工入库。饶了我吧。 + +## 穿透与反向代理 + +> ~~写着写着总会变成报流水账。~~ + +在部署好 frp 穿透后,我遇到了子网划分的问题。经由 frp 进来的流量再进 Jellyfin,源 IP 默认就变换为`localhost`,Jellyfin **默认对本地回环不设限速**,在 Dashboard 里全局设置流比特率的做法并不起作用。 + +在实地测试后,发现 Jellyfin 并不直接支持 Proxy Protocol,那么就只能在前面套多一层 nginx 做反向代理了。 + +方法很简单,frp 侧仍旧启用 Proxy Protocol,在 nginx 里剥离真实 ip。我是在 Ubuntu Server 上安装的 nginx,据称已集成`realip`模块。那么编辑`/etc/nginx/sites-enabled/default`(我是图方便直接原地开刀了): + +``` +server { + listen 8097 proxy_protocol; + listen [::]:8097 proxy_protocol; + + #root /var/www/html; + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + + # Add index.php to the list if you are using PHP + #index index.html index.htm index.nginx-debian.html; + + server_name _; + + location / { + proxy_pass http://127.0.0.1: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; + + # for websocket + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + #try_files $uri $uri/ =404; + } + + # ... +} +``` + +此外 Jellyfin 文档还提到要给真实 IP“打码”。由于有些配置项是写在 http 全局块里,目前也不清楚会不会对其他监听造成影响,我就先没整这个了。