继上一篇 ITX 主機升級 + 清灰記錄 進行了硬體層面的維護,最近從軟體層面對家庭串流媒體服務 Jellyfin 做了優化,使 Jellyfin 變成一個真正意義上的 NAS,不僅用於觀影和追番,還可以進行家庭圖片、視頻以及書籍、Podcast 等的存儲。
NAS 在維基百科是這麼定義的:Network-attached storage (NAS) 是一種文件級 (相對於 block-level storage) 計算機數據存儲 伺服器,連接到一個 計算機網絡,為一個 異構 客戶端組提供數據訪問。術語 “NAS” 既可以指所涉及的技術和系統,也可以指為這種功能構建的專用設備 (與局域網等相關技術不同,NAS 設備通常是單個單元)。
翻譯:網絡附加存儲 (NAS) 是一種文件級 (相對於塊級存儲) 計算機數據存儲伺服器,它連接到計算機網絡,為異構客戶端組提供數據訪問。術語 “NAS” 既可以指所涉及的技術和系統,也可以指為這種功能構建的專用設備 (與局域網等相關技術不同,NAS 設備通常是單個單元)。
所以不像我們常說的 NAS 設備,實現了對應功能的軟體或系統也可以這樣稱呼,比如我的 NAS 就是運行在一台 24h 開機的 Win11 主機上。所以本文是基於 Win11 環境進行配置
部署方案#
Nastools + Jackett + Qbittorent + ChineseSubFinder + Jellyfin
上述所有服務都可以直接部署在 windows 上
實現功能#
- 使用 Jackett 進行 BT 站索引,並反饋給 Nastools 進行電影、節目(綜藝、電視劇、番劇)利用 TMDB API 刮削(我是 BT 愛好者,沒有精力折騰 PT,但 NASTools 內置的索引器網站很少,主要是番劇站點,不能滿足影視的需求,所以引入 Jackett 增加索引站點)
- 利用 NASTools、Qbittorrent 工具批量下載和整理媒體文件
- 使用 ChineseSubFinder 自動下載中文字幕
- 硬體轉碼加速媒體播放
具體的部署方法不是這篇文章的重點,網上有大量的教程可以參考,我分享一些進階操作,希望能幫助更多的人。
硬鏈接🔗(Hard Link)#
具體關於文件的移動方式如硬鏈接、軟鏈接等等概念可以參考 名詞解釋 - 轉移方式
我們可以輕鬆地用 NASTools 實現硬鏈接,但是有時會因為番劇字幕組的文件命名或無關文件導致無法識別出元數據,所以這裡就需要手動進行,這裡我用 Python 寫了個腳本,也是為了自動化理念的實現。
目錄結構:
[DBD-Raws][孤獨搖滾!][01-12TV全集+特典影像][1080P][BDRip][HEVC-10bit][簡繁外挂][FLAC][MKV]
├── CDs
│ ├── 01
│ │ ├── 01 ふらふら.flac
│ │ ├── 02 来世でがんばります.flac
import os
# 創建一個目錄中的所有文件的硬鏈接到另一個目錄
def create_hard_links(folder, new_folder):
# 如果番劇主文件夾不存在,創建一個
while not os.path.exists(new_folder):
os.mkdir(new_folder)
# 遍歷文件夾中的所有文件
for file_name in os.listdir(folder):
try:
file_path = os.path.join(folder, file_name)
# 如果是文件夾,遞歸調用函數
if os.path.isdir(file_path):
# 同時創建該文件夾,因為硬鏈接不能鏈接文件夾
new_folder_path = os.path.join(new_folder, file_name)
os.mkdir(new_folder_path)
create_hard_links(file_path, new_folder_path)
else:
new_file_path = os.path.join(new_folder, file_name)
# 如果文件已經存在,添加後綴“_copy{n}”,比如有多個“cover.jpg”,命名為“cover_copy1.jpg”,“cover_copy2.jpg”等
while os.path.exists(new_file_path):
print(f"Renaming {file_name} to add the suffix “_copy” in {new_folder}")
count = 1
file_name_without_extension, file_extension = os.path.splitext(file_name)
new_file_name = f"{file_name_without_extension}_copy{count}{file_extension}"
count += 1
new_file_path = os.path.join(new_folder, new_file_name)
os.link(file_path, new_file_path)
else:
os.link(file_path, new_file_path)
print(f"鏈接成功!快去{anime_dir}看看吧o(* ̄▽ ̄*)ブ!")
except (FileNotFoundError, PermissionError) as e:
print(f"An error occurred: {str(e)}")
# Usage example
anime_name="孤獨搖滾(2020)1"
# NASTools設置的二級目錄
category = ["動漫" , "完結動漫"]
# suffix = "CDs"
anime_dir = f"D:\TV\Anime\{category[1]}\{anime_name}"
# os.mkdir(anime_dir)
source_folder = r'D:\Media_download\[DBD-Raws][孤獨搖滾!][01-12TV全集+特典影像][1080P][BDRip][HEVC-10bit][簡繁外挂][FLAC][MKV]\Fonts'
new_folder = rf'{anime_dir}'
create_hard_links(source_folder, new_folder)
腳本下載🔗:hlink.py
字幕優化#
自定義字幕#
【控制台】->【播放】->【備用字體文件路徑】,勾選【啟用備用字體】
格式轉換#
由於字幕組提供的字體多為.otf,.ttf 等,他們的文件大小最大的甚至在 27MB 左右,這對於 WEB 傳輸可以說是相當大的負擔了,參考 Jellyfin 官方文檔我們知道可以使用.woff2 格式,這是一種專門用於 Web 開發中使用的高效的字體壓縮格式,經實測可以壓縮到原來的 50%,我們使用 fontTools,採用 Google 的 Brotli 壓縮算法進行批量字體轉換,相比傳統的壓縮算法(如 gzip),Brotli 在相同的壓縮比下可以實現更快的解壓縮速度。
翻譯:Web 客戶端當前僅使用 Fallback Fonts 選項來呈現字幕。可以將其設置為包含字體的文件夾。這些字體的總大小限制為 20MB。建議使用 woff2 等針對 web 優化的輕量級格式。


轉換腳本如下
from fontTools.ttLib import TTFont
import brotli
import os
def convert_fonts_in_directory(input_dir):
for file in os.listdir(input_dir):
if os.path.isdir(os.path.join(input_dir, file)):
convert_fonts_in_directory(os.path.join(input_dir, file))
# 如果文件後綴是.otf/.ttf
elif file.lower().endswith((".otf", ".ttf")):
input_file = os.path.join(input_dir, file)
output_file = os.path.join(output_dir, os.path.splitext(file)[0] + ".woff2")
convert_otf_to_woff2(input_file, output_file)
else:
print(f"文件{file}不是.otf/.ttf文件")
def convert_otf_to_woff2(input_file, output_file):
# 打開 字體文件
font = TTFont(input_file)
# 將字體保存為 .woff2 文件
font.save(output_file, 'woff2')
# 壓縮 .woff2 文件
with open(output_file, 'rb') as f:
woff2_data = f.read()
compressed_data = brotli.compress(woff2_data)
# 將壓縮後的數據保存為 .woff2 文件
with open(output_file, 'wb') as f:
f.write(compressed_data)
print(f'轉換成功,他們在{output_dir}靜悄悄地等你了哦!(*^▽^*)')
# 輸入和輸出目錄
input_dir = r'D:\文件互傳\Fonts\1'
output_dir = r'D:\文件互傳\Fonts\1'
# 調用函數進行轉換
convert_fonts_in_directory(input_dir)
腳本下載🔗:convert_to_woff2.py
經過轉換格式,字體基本就可以滿足需求了,如果還需進一步壓縮,請參考 字體子集化
劇集展示順序#
在刮削番劇的特典文件時,有可能會出現因為 TMDB 元數據的結構與字幕組命名順序不同導致刮削失敗,比如《總之就是非常可愛 - 女子高中生篇》在 TMDB 放在特典篇的 16-19 集
而雲光字幕組的結構是這樣👇
對此我們有 2 個解決方案
- 重命名為 S00E16-S00E19,進行刮削
- 通過了解 TMDB🈶劇集組 (Episode Group) 的元數據
在 Jeltfin 中對應設置:選中劇集 -> 編輯元數據,即可實現刮削
也可以通過 TMDB API 來獲取,方便手動編輯
GET
https://api.themoviedb.org/3/tv/{series_id}/episode_groups
Podcast 刮削#
Jellyfin 沒有 Podcast 分類,但是我們可以通過音樂庫或者書籍庫來實現,但是對應的元數據刮削有可能比較少,不過聊勝於無 hhh。
建立好目錄結構,Jellyfin 就會自動刮削,比如 BBC Sound 中的
Americast 最新一期 “Trump Trial… Donald Found Guilty!”,音樂
庫結構推薦為 Music - Some Artist - Album a - music.mp3
目前還沒有找到比較好刮削 Podcast 的插件,NASTools 只支持電影和劇集的刮削,
如果有推薦可以告訴我,為後續誰文章提供材料 (bushi)