Signed-off-by: SilverAg.L <caclx@outlook.com>
This commit is contained in:
@@ -48,13 +48,13 @@ volumes:
|
|||||||
|
|
||||||
我针对的还是 Jellyfin “神奇”的资源组织方式。就像[这篇《基于 Jellyfin 和音流的 nas 影音库搭建及踩坑》](https://sspai.com/post/90896)所说,“为什么不直接读取音乐标签进行专辑聚合”呢?
|
我针对的还是 Jellyfin “神奇”的资源组织方式。就像[这篇《基于 Jellyfin 和音流的 nas 影音库搭建及踩坑》](https://sspai.com/post/90896)所说,“为什么不直接读取音乐标签进行专辑聚合”呢?
|
||||||
|
|
||||||
### 音乐:混乱的元数据
|
### 元数据刮削:一笔糊涂账
|
||||||
|
|
||||||
然而事实上,即使真的能做到自动专辑聚合,元数据本身的刻录和查询也是一片混乱。上面援引的博文推荐 MusicTag 这个工具,但同是从网易云那刮削,下载下来本是《紫罗兰永恒花园 OST》的曲目能给它识别成《凹凸世界五周年》,也是给我看笑了。更别说国外的 MusicBrainZ 数据库有相当一部分冷门曲目并没有收录(尽管 Spotify 等平台能够找到),手动录入更是个吃力不讨好的体力活。
|
然而事实上,即使真的能做到自动专辑聚合,元数据本身的刻录和查询也是一片混乱。上面援引的博文推荐 MusicTag 这个工具,但同是从网易云那刮削,下载下来本是《紫罗兰永恒花园 OST》的曲目能给它识别成《凹凸世界五周年》,也是给我看笑了。更别说国外的 MusicBrainZ 数据库有相当一部分冷门曲目并没有收录(尽管 Spotify 等平台能够找到)。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
::: tip 最简方案
|
::: tip 音乐库最简方案
|
||||||
文档这么说:我管你怎么整理,我只知道**是同一张专辑就该塞在同一个文件夹**。
|
文档这么说:我管你怎么整理,我只知道**是同一张专辑就该塞在同一个文件夹**。
|
||||||
|
|
||||||
那么事情也好办,就按专辑名来呗。好比如:`music/{album or "[standalone]"}/{artist1,artist2} - {title}`。
|
那么事情也好办,就按专辑名来呗。好比如:`music/{album or "[standalone]"}/{artist1,artist2} - {title}`。
|
||||||
@@ -66,12 +66,24 @@ volumes:
|
|||||||
- 没招,默认合并(甚至可以看到重复的曲号,都是第六首)。只能手工分离(`Fragrance - SoundzImage`和`Fragrance - Hatsune Miku`)。
|
- 没招,默认合并(甚至可以看到重复的曲号,都是第六首)。只能手工分离(`Fragrance - SoundzImage`和`Fragrance - Hatsune Miku`)。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
但比起前面所述的国内外两桌草台班子,更令我恼火的当属大把大把的、查无此人的“黑户”。怎么来的?音声、网文、3D 动画。
|
||||||
|
|
||||||
|
> 我的整理方式和 acgdb 类似:3D 区、音声区(作者分发、油管录播、DLsite 正作)、书目区(漫画和文集)、写真区、插画区,此外新增音乐区。
|
||||||
|
|
||||||
|
3D 区无论玩恋活还是 MMD,既有图集又有视频,无法按媒体类型区分。即便真要分,它算电视节目?电影?MV?分不明白。
|
||||||
|
|
||||||
|
音声区大量的音频资源,摆烂一点直接用电子书库、按文件夹访查也不是不行,但显示出来反倒是专辑名(或者说 DLsite、系列作品名)更显眼,而非每一集的标题;若要用音乐库收纳,就得改造一番目录树适配它那个“一个专辑只有一个目录”的原则,工作量也不小。
|
||||||
|
|
||||||
|
至于书目区,正经出版物想获取元数据并不难。相对的,“不正经”读物呢?网文可以依靠豆瓣之流;同人文只要作者有公开发布,留心寻找也是能记下元数据的(同人圈子对打 Tag 这件事很看重);那么只剩下来源不正经、题材也不正经的“那种”作品了。它们流通的地方通常都是论坛这种早期网络社区,只知道个标题(很难说发帖人就是作者,万一是二道贩子呢?甚至文件名也不一定就是完整标题)。What can I say?
|
||||||
|
|
||||||
|
偏偏这种不在台面上的“资源”我收纳了不少,哪怕有自动化工具,后续校对也是个体力活,何况很多资源只能一件件手工入库。饶了我吧。
|
||||||
|
|
||||||
### 电子书:吃力不讨好
|
### 电子书:吃力不讨好
|
||||||
|
|
||||||
至于小说漫画,或者说书籍媒体库,那只能说真搭一个私人图书馆也是同样的编排要求,满满的工作量。
|
小说漫画,或者说书籍媒体库,只能说真搭一个私人图书馆大概也和 Jellyfin 别无二致——满满的工作量。可能甚至有过之而不及。
|
||||||
|
|
||||||
> 不禁想到米哈游创始人蔡浩宇的“快乐守恒定律”:你做的过程中如果很轻松快乐,那么你做出来的结果未必能给人带来快乐。
|
> 不禁想到米哈游创始人蔡浩宇的“快乐守恒定律”:你做的过程中如果很轻松快乐,那么你做出来的结果未必能给人带来快乐。
|
||||||
> 媒体库编排是不是也要“苦其心志、劳其筋骨”,借阅者、用户才能有好的体验呢?但话又说回来,像 Jellyfin 这样的家庭影院通常都是自己管理自己用,费那么大功夫组织这些文件,观赏的体验又能改善多少呢?
|
> 媒体库编排是不是也要“苦其心志、劳其筋骨”,才能有好的观影体验呢?但话又说回来,这种家庭影院通常都是自己管理自己用,费那么大功夫组织这些文件,观赏的体验又能改善多少呢?
|
||||||
|
|
||||||
我相信大多数\*并不在乎资源来源\*的读者去找网络上流通的小说肯定优先去找 txt、doc(x) 这种容易打开的格式。但现有的私人图书馆,无论 Jellyfin 这种顺手实现的,还是 Kavita 这种专用的,**都不支持这些格式**。Calibre 也许可以,但**书目的元数据就成了另一桩麻烦事**。
|
我相信大多数\*并不在乎资源来源\*的读者去找网络上流通的小说肯定优先去找 txt、doc(x) 这种容易打开的格式。但现有的私人图书馆,无论 Jellyfin 这种顺手实现的,还是 Kavita 这种专用的,**都不支持这些格式**。Calibre 也许可以,但**书目的元数据就成了另一桩麻烦事**。
|
||||||
|
|
||||||
@@ -79,13 +91,18 @@ volumes:
|
|||||||
那当然是通通转换成 pdf,单纯当作文件管理器那样访问文件夹、文件最简单。**但 pdf 对移动端并不友好,文字内容并不能自适应,更多还是用于漫画**。
|
那当然是通通转换成 pdf,单纯当作文件管理器那样访问文件夹、文件最简单。**但 pdf 对移动端并不友好,文字内容并不能自适应,更多还是用于漫画**。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
进阶一点的方案就只能按照文档来了。啰嗦是显然的,但如前面的“快乐守恒定律”所言,苦一苦自己,阅读体验才能好起来。
|
进阶一点的方案主要围绕 epub 电子书,毕竟漫画这块 pdf、epub、`.cb*`压缩包三者的页面版式不可能差太多,翻页起来其实没什么区别。
|
||||||
|
|
||||||
首先讨论相对容易些的漫画。“画”嘛,总归是一张张的图片序列。把它们打成压缩包[^compress](当然多数网站已经打好包给你下载了),我们就得到本体了。顺带一提`.cbz`即`.zip`,`.cbr`即`.rar`,`.cb7`即`.7z`,有需要的话改个后缀名就是了。至于元数据,Jellyfin 文档指出**只有 epub 书籍才允许元数据集成在文件里**,对于这种漫画压缩包,需要另写`ComicInfo.xml`。也就是说,**每一本、系列的每一话,都需要单独的文件夹放置元数据和本体**。
|
::: info 压缩包漫画
|
||||||
|
漫画本质上就是一页页的画嘛。许多网站本就提供试阅,给这些图片打个包也就是顺手的事。像我这样存储空间拮据的(主要还是[协议不通用](recents-11172025.md#硬件购置)),只能是哪种最节省空间就选哪种咯。
|
||||||
|
|
||||||
[^compress]: 还请注意**不要把文件夹层级包含进去**。换言之,用软件打开压缩包应**直接显示图片序列**。
|
Jellyfin 本身支持`.zip` `.rar` `.7z`。如果你打算另起炉灶,但选配的服务不支持这样通用的后缀名,也可以改变后缀:
|
||||||
|
`.cbz`即 zip、`.cbr`即 rar、`.cb7`即 7z、`.cbt`即 tar。
|
||||||
|
|
||||||
然后是 epub 电子书,它的话则更麻烦亿些。现有的 epub 编辑器并没有像写 bilibili 专栏(或者像 Word 文档)那样自动编纂页面的能力,操作起来更像是手搓 HTML 博客。所以,**图方便的话更建议在线转换**`.txt` `.doc(x)`文档。
|
至于元数据,Jellyfin 文档指出**只有 epub 书籍才允许元数据集成在文件里**,对于这种漫画压缩包,需要另写`ComicInfo.xml`。也就是说,**每一本、系列的每一话,都需要单独的文件夹放置元数据和本体**。
|
||||||
|
:::
|
||||||
|
|
||||||
|
现有的 epub 编辑器并没有像写哔哩哔哩专栏(或者像 Word 文档)那样自动编纂页面的能力,操作起来更像是手搓 Web 三剑客(HTML、CSS、JavaScript)。所以,**图方便的话更建议在线转换**`.txt` `.doc(x)`文档。
|
||||||
|
|
||||||
::: details EPUB 内容物
|
::: details EPUB 内容物
|
||||||
epub 的 mimetype 通常标`application/epub+zip`,说明其本质是压缩包。解压出来通常分这么几块:
|
epub 的 mimetype 通常标`application/epub+zip`,说明其本质是压缩包。解压出来通常分这么几块:
|
||||||
@@ -99,7 +116,7 @@ epub 的 mimetype 通常标`application/epub+zip`,说明其本质是压缩包
|
|||||||
- `nav.*htm*` `nav.opf`:电子书的目录。前者为 epub3 标准,后者为 epub2 标准,通常在`content.opf`里特别标注。
|
- `nav.*htm*` `nav.opf`:电子书的目录。前者为 epub3 标准,后者为 epub2 标准,通常在`content.opf`里特别标注。
|
||||||
- `Fonts/` `Audio/` ...:其他内容。
|
- `Fonts/` `Audio/` ...:其他内容。
|
||||||
|
|
||||||
所以我称编辑 epub 这件事为“手搓 HTML 博客”,因为本来就需要按章回编排 HTML 内容。每一章是一页 HTML,不恰好对应一篇博文吗?
|
所以我称编辑 epub 这件事为“手搓网站”,因为本来就需要按章回编排 Web 内容,这 OEBPS 的目录树也很有网站的味。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: warning 书目目录索引
|
::: warning 书目目录索引
|
||||||
@@ -121,19 +138,6 @@ epub 的 mimetype 通常标`application/epub+zip`,说明其本质是压缩包
|
|||||||
扫描结果是:“不正经的”和《时间简史》。其余读物无法直接访问(可能仍能搜索到)。
|
扫描结果是:“不正经的”和《时间简史》。其余读物无法直接访问(可能仍能搜索到)。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### 元数据刮削:一笔糊涂账
|
|
||||||
前面我也论述过,音乐专辑的元数据库就是几桌草台班子。但比起草台班子,更令我恼火的当属大把大把的、查无此人的“黑户”。怎么来的?音声、同人志、网文。
|
|
||||||
|
|
||||||
> 我的整理方式和 acgdb 类似:3D 区、音声区(作者分发、油管录播、DLsite 正作)、书目区(漫画和文集)、写真区、插画区。
|
|
||||||
|
|
||||||
3D 区无论玩恋活还是 MMD,既有图集又有视频,无法按媒体类型区分。即便真要分,它算电视节目?电影?MV?分不明白。
|
|
||||||
|
|
||||||
音声区大量的音频资源,摆烂一点直接用电子书库、按文件夹访查也不是不行,但显示出来反倒是专辑名(或者说 DLsite、系列作品名)更显眼,而非每一集的标题;若要用音乐库收纳,就得改造一番目录树适配它那个“一个专辑只有一个目录”的原则,工作量也不小。
|
|
||||||
|
|
||||||
至于书目区,像上面列的“正经读物”想获取元数据并不难。那“不正经读物”呢?对比出版物,网文显然算不上“正经”,但豆瓣之流依然有机会找到。所谓的同人文受限于作者的圈地自萌,但若是有缘知道 Ta 发布的平台,也是能记下元数据的(同人圈子对打 Tag 这件事很看重)。那么只剩下来源不正经、题材也不正经的“那种”作品了,它们流通的地方通常都是论坛这种早期网络社区,只知道个标题(甚至标题也不一定知道)。What can I say?
|
|
||||||
|
|
||||||
偏偏这种不在台面上的“资源”我收纳了不少,哪怕有自动化工具,后续校对也是个体力活,何况很多资源只能一件件手工入库。饶了我吧。
|
|
||||||
|
|
||||||
## 穿透与反向代理
|
## 穿透与反向代理
|
||||||
|
|
||||||
如今连网易云也改得不知为何物了,于是我随身听的需求便也转向 Jellyfin。最简单的方法可以是 ZeroTier,但安卓有“同一时间只允许一个 VPN”的限制,所以在群友指导下搞了内网穿透(FRP)。
|
如今连网易云也改得不知为何物了,于是我随身听的需求便也转向 Jellyfin。最简单的方法可以是 ZeroTier,但安卓有“同一时间只允许一个 VPN”的限制,所以在群友指导下搞了内网穿透(FRP)。
|
||||||
@@ -150,16 +154,13 @@ AI 对此的解法是在 frp 这里记录下真实 IP。我选配的服务商支
|
|||||||
server {
|
server {
|
||||||
listen 8097 proxy_protocol;
|
listen 8097 proxy_protocol;
|
||||||
listen [::]:8097 proxy_protocol;
|
listen [::]:8097 proxy_protocol;
|
||||||
|
|
||||||
#root /var/www/html;
|
|
||||||
set_real_ip_from 127.0.0.1;
|
set_real_ip_from 127.0.0.1;
|
||||||
real_ip_header proxy_protocol;
|
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 _;
|
server_name _;
|
||||||
|
|
||||||
|
add_header X-Content-Type-Options "nosniff";
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:8096;
|
proxy_pass http://127.0.0.1:8096;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
@@ -168,19 +169,36 @@ server {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||||
proxy_set_header X-Forwarded-Host $http_host;
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
# for websocket
|
location /socket {
|
||||||
|
proxy_pass http://127.0.0.1:8096;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
# First attempt to serve request as file, then
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
# as directory, then fall back to displaying a 404.
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
#try_files $uri $uri/ =404;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ...
|
# Jellyfin 推荐给真实客户端信息“打码”
|
||||||
|
access_log /var/log/nginx/access.log stripsecrets;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 为了解说方便把 http 块里的全局“打码”配置拉下来叻(本文件本来就嵌套在 http 块)。
|
||||||
|
# 不清楚先后顺序有没有影响。
|
||||||
|
log_format stripsecrets '$remote_addr $host - $remote_user [$time_local] '
|
||||||
|
'"$secretfilter" $status $body_bytes_sent '
|
||||||
|
'$request_length $request_time $upstream_response_time '
|
||||||
|
'"$http_referer" "$http_user_agent"';
|
||||||
|
|
||||||
|
map $request $secretfilter {
|
||||||
|
~*^(?<prefix1>.*[\?&]api_key=)([^&]*)(?<suffix1>.*)$ "${prefix1}***$suffix1";
|
||||||
|
~*^(?<prefix1>.*[\?&]ApiKey=)([^&]*)(?<suffix1>.*)$ "${prefix1}***$suffix1";
|
||||||
|
default $request;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
此外 Jellyfin 文档还提到要给真实 IP“打码”。由于有些配置项是写在 http 全局块里,目前也不清楚会不会对其他监听造成影响,我就先没整这个了。
|
|
||||||
|
|||||||
Reference in New Issue
Block a user