Kazumi 開源追番 App:片單由規則決定,彈幕鑰匙不在原始碼

Kazumi 是用 Flutter 開發的開源番劇採集與觀看 App(GPL-3.0、超過 3 萬顆星),片單來源由五條 XPath 選擇器構成的社群規則決定,彈幕走彈彈play 開放平台、番劇資料走 Bangumi 開放 API,並內建 Anime4K 即時超解析度。它的 App 本體零遙測、無廣告,但彈幕與鏡像服務的身分參數只在官方編譯管線注入,自己從原始碼編譯的版本拿不到這塊功能。

用 AI 摘要這篇文章:

我把 Kazumi 的整包原始碼抓下來讀,最先找的東西有點奇怪:彈幕功能連出去用的那組身分參數放在哪個檔案。答案在 lib/utils/dandan_credentials.dart,裡面的 AppId 與金鑰是讀取編譯期環境變數的常數,預設值是空字串;真正的值放在 GitHub 的 CI 保險庫,只有官方管線在編譯安裝檔那一刻才注入。一支以 GPL-3.0 完整開源的 App,有一小塊功能無法從原始碼重製,這個設計是理解整個專案的入口。

Kazumi 在 GitHub 上有超過 3 萬顆星(截至 2026 年 9 月),2024 年 5 月開張,到我查證的這天(2026-09-21)前一天還有提交紀錄,2.3.3 版在 9 月 15 日剛發布。它用 Flutter 開發,一版打包九種安裝檔,Android、Windows、macOS、Linux 通吃。但它的真正結構是三層:播放器引擎(App 本體)、採集規則(社群維護的 JSON 檔)、內容來源(規則指向的第三方網站)。App 本體不內建任何一片動漫,你的片單從哪來,由你匯入的規則決定;而彈幕、番劇資料這些加分功能,靠的是另外兩家服務的開放平台。引擎乾淨是真的,體驗與風險則由規則層與服務層說了算。

五條 XPath,決定你的片單從哪裡來

規則是整個專案最核心的設計。打開規則倉庫 KazumiRules 的任何一份 JSON,本質就是一份網站說明書:baseURL 寫網站根目錄,searchURL 寫搜尋網址並用 @keyword 標記關鍵字位置,剩下五個欄位全部是 XPath 選擇器,分別指出搜尋結果清單、作品名稱、作品連結、播放線路、集數連結在網頁裡的位置。我實際從規則倉庫抓了一份名為 AGE 的規則下來,它的 baseURL 指向 agedm.io,五條選擇器把那個網站的搜尋頁結構描述得清清楚楚。

Kazumi 規則編輯器畫面Pin
Kazumi 的規則編輯器:BaseURL 與 SearchURL 加上五條 XPath 選擇器欄位(官方功能截圖)

這也是官方文件大方承認的分工。kazumi.app 官網的行銷頁只講引擎與體驗,從頭到尾不點名任何一個內容網站;而官方的規則開發教學,則以一個第三方動漫網站為完整範例,教你怎麼用瀏覽器開發者工具複製 XPath。責任切割是刻意的:引擎開源、規則社群共筆、內容歸內容網站。規則倉庫根目錄到查證這天累積了 86 份規則,歡迎任何人提交,也可選擇在規則裡留下自己的 ID。

Kazumi 規則管理清單畫面Pin
規則管理清單:已匯入的採集規則可切換與編輯(官方功能截圖)

這裡必須把話講清楚:規則指向的第三方網站,授權狀態各自不同,是不是能合法播放你追的那部番,取決於該網站與你所在地的規範。Kazumi 官方的免責聲明自己也劃了線,要求使用者遵守所在地法規、不得侵犯第三方智慧財產權,還寫明「因使用本專案而產生的資料和快取應在 24 小時內清除」。專案作者用這條 24 小時條款替整個生態定性:它知道內容層是灰色地帶,並把責任推回使用者手上。本文不提供任何內容網站的使用指引,下面只談引擎層與服務層的工程事實。

把它會連的門牌全部列出來

讀完 lib/request/config/api_endpoints.dart 這份端點總表,再加上幾個實測,Kazumi 裝好之後會對外連線的對象可以分成六群。番劇元資料走 Bangumi 的開放 API,我實際打了它的每日放送端點,回傳將近百 KB 的結構化資料,2026 年 7 月檔期的節目、評分、封面圖都在裡面,所以 App 裡的番劇目錄與時間表有真實資料源,不是空殼。彈幕走彈彈play 開放平台,這個稍後單獨講。規則商店走 GitHub 的原始檔空間,另外備了一份 gitcode 鏡像給中國大陸網路環境使用,兩邊我都實測抓得到同樣的規則檔。圖片識番功能串了 trace.moe 的搜尋 API。一起看功能則使用 SyncPlay 協定,預設連的伺服器是 syncplay.pl 這台公共機器(連接埠 8996,備選 8995 到 8999),也就是說開房一起看時,你的播放進度會經過第三方公共伺服器轉發。

Kazumi 首頁番劇目錄畫面Pin
首頁以 Bangumi 元資料為骨架的番劇目錄與分類(官方功能截圖)

線上更新也走同一套雙通道邏輯:檢查新版本先問 GitHub 的 releases API,拿不到就退回 api.kazumi.fyi 這個自架鏡像,跟規則倉庫的 gitcode 備援一樣,都是為了網路環境連不上主站時不會整個變成孤兒。

第六群最微妙:你匯入的規則指向哪些網站,App 就直接向那些網站發請求。規則檔裡可以自訂 User-Agent 與 Referer,還有一個廣告過濾旗標;遇到網站的反爬驗證頁,程式會用內建瀏覽器核心載入頁面,依規則設定的三種方式過關:圖片驗證碼抓圖給你手動輸入、偵測到驗證按鈕就自動點擊、或執行規則自帶的 JavaScript 腳本,通過後存下 Cookie 重試搜尋。這套「反反爬」工程寫得相當完整,它同時也說明了這類工具與內容網站之間的軍備競賽本質:網站加牆,規則想辦法翻過去。

原始碼裡沒有彈幕的鑰匙

回到開頭那個發現,這是整個專案最反常的一項設計。彈彈play 開放平台要求每個請求帶 X-AppId 與 X-Signature,後者是由身分參數、路徑與時間戳合成的 SHA256 簽名。Kazumi 的原始碼完整實作了這套簽名流程,但簽名用的兩個參數是空常數,真正的值由 .github/workflows/pr.yaml 裡的 GitHub secrets 在編譯時以 –dart-define 注入。自架編譯管線的人拿不到這組值,自編譯版的彈幕功能等於帶著空白身分出門。

為了確認空白身分的下場,我模仿 App 的請求方式直接呼叫彈彈play 的搜尋端點,不帶身分參數,用兩組真實動畫標題各測一輪,兩次都拿到同一個結果:錯誤代碼 3,訊息大意是應用不存在。對照原始碼結構,這就是自編譯版會遇到的行為。要公平地說,我無法證明被拒的唯一原因就是身分參數,但官方管線特別為它開保密通道、自編譯版註定送出空值,這個組合已經足夠說明差別。

同樣的模式還有第二處。番劇資料的鏡像後端 api.kazumi.fyi(給連不上 Bangumi 原站的網路環境用)與 App 更新檢查的鏡像端點,走的也是 CI 注入的身分簽名。有意思的是,README 的開發者問答只提醒自行編譯需要良好的網路環境、可能要設鏡像位址,完全沒有提到這兩組參數不在原始碼裡。想在原理層面審計這個 App 的人,裝了自編譯版會發現部分功能安靜地失效,而文件沒有解釋原因。

彈幕這條線的工程細節,還藏著一個反向工程的活標本。Kazumi 抓彈幕的路徑是三段式:先拿 Bangumi 的條目 ID 去彈彈play 換出它自家的番劇 ID,再換分集 ID,最後才抓彈幕檔。原始碼註解自己承認,彈彈play 的分集編號規則是猜出來的(例如番劇 ID 若是 1758,第一集的彈幕庫編號大概叫 17580001),這套規則沒有寫在官方 API 文件裡,穩當的做法是多問一次中介端點。另一段註解則記錄了搜尋 API 上限 25 筆、不分頁,大型系列作品會被截斷(註解裡舉的例子是某部 48 個條目的長壽推理番),所以他們改走另一個不限筆數的端點。開放平台聽起來有合約保障,實際整合仍然是貼著別人家地板在走路。

這不是指控。彈彈play 對開放平台要求註冊身分、專案不想把自家身分放在公開倉庫裡被人冒用,都是合理的工程決定。值得記下的教訓是:開源在這裡是信任設計,不是可重製保證。「原始碼公開」與「你能組出跟官方一模一樣的東西」是兩件事,Kazumi 是這條界線的乾淨範例。

零遙測的 App,不等於零足跡的你

對 App 本體的隱私宣稱,我做了能做的核對。README 的隱私政策寫「不收集任何用戶資料,不使用任何遙測組件」,這是作者宣稱;我這邊的對照證據是把整包 lib 目錄掃過一遍,Sentry、Firebase、友盟、PostHog 這些常見遙測套件全部搜不到,兩邊對得上。廣告也一樣,官方問答明講本專案未插入任何廣告,廣告來自影片源,請挑沒有廣告的來源看。

但「零遙測」只涵蓋 App 這一層。實際使用時,你的請求會送到規則指向的網站(對方伺服器看得到你的 IP 與請求模式)、彈彈play(它知道你搜了什麼番)、Bangumi(元資料查詢)、開一起看房間時的 SyncPlay 公共伺服器。把這些門牌攤開,你就會發現隱私邊界其實畫在生態系上,不是畫在 App 上。它沒有說謊,只是宣稱的範圍比讀者直覺的小。

播放器本身有兩個真材實料的功能值得記。超解析度不是行銷詞:安裝包裡真的附了 Anime4K 的 GLSL 著色器,包含 CNN 模型的 S、M、VL 三種大小變體,加上自動降採樣預處理,播放設定裡提供關閉、效率、品質三檔。官方問答同時提醒(作者宣稱):這功能吃 GPU,沒有高效獨立顯卡就選效率檔,而且對高解析度來源開超分意義不大,它本是為低解析老片設計的。另外,遇到使用反盜鏈措施的來源,內建播放器能處理,丟給外部播放器則不行,這是官方問答承認的邊界,也解釋了為何它堅持自帶播放核心。

播放這一層其實是雙引擎。規則裡有個 useWebview 旗標,某條規則搜得到卻播不動時,可以關掉內建播放器改用網頁核心播放,相容性換流暢度;官方問答的建議是內建播放器能用就用內建,因為彈幕與流暢度都掛在它身上。記憶體策略也值得知道:播放時它會盡量把影片快取在記憶體裡換觀看體驗,官方問答承認佔用偏高,記憶體吃緊的機器要去播放設定裡開低記憶體模式。這兩條都是 README 白紙黑字,屬於作者自己先招的誠實限制。

五種下載管道,拿到的不是同一個版本

管道版本狀態附帶條件
GitHub Releases2.3.3(2026-09-15),每版九種安裝檔Windows 版由 SignPath 免費簽章
F-Droid頁面版本標籤止於 2.1.1落後主線兩個小版號
Flathub頁面上線中Linux 用
iOS跟進主線版號,但只發無簽章 ipa需自行側載,官方有專文教學
HarmonyOS NEXT在 ErBWs 分支倉庫另發,最新 2.3.1無簽章 hap,同樣要側載

同一個開源專案,生態落地時長出五條通道。Android 主力用 GitHub 或 F-Droid;Linux 有 deb、tar.gz(amd64 與 arm64)加 Flathub 與 AUR;iOS 與鴻蒙官方不碰簽章這關,直接發無簽章包讓使用者自己側載。選管道時唯一的實際陷阱是 F-Droid 的版本滯後:它在頁面上停在 2.1.1,而主線已經走到 2.3.3,新功能與修正要等 F-Droid 自己的建置排程。Linux 使用者還有個小坑:官方問答明講 tar.gz 版天生缺圖示與系統匣功能,常規桌面體驗請裝 deb 版。

跟直接開網頁看比起來,它多給你什麼

拿它跟「瀏覽器直接開網站看」比,一條可防守的差異是:它把散落在各網站的觀看體驗收攏成一個統一的書架。Bangumi 元資料當骨架,追番清單、歷史記錄、時間表全部跨來源共用;彈幕疊在任何來源的畫面上;廣告過濾在規則層處理;反盜鏈在播放核心處理。這些是網站本身不會給你的東西,也是這類採集器存在的理由。

最後把限制集中講清楚。這篇的證據來自原始碼與網路層實測,我沒有實機安裝操作它,播放流暢度、彈幕延遲、崩潰率這些體驗層的問題不在本文能回答的範圍。XPath 支援是子集,官方問答明說只支援以 // 開頭的選擇器,寫規則別照一般 XPath 教學抄。自編譯版的功能缺口前面講過了。規則層的內容合法性因地而異,24 小時清除條款是作者自己畫的紅線,不是我的法律建議。深色模式、配色方案、DLNA 投屏、倍速這些功能官方清單都打了勾,但我沒驗證,僅供索引。

自編譯會少的那一塊,決定你該走哪條路

如果你追番時想要彈幕與超分、能接受自己挑選規則並對內容來源的合法性自負,抓 GitHub 官方安裝檔是最短路徑,功能完整且更新最快。如果你是想審計原始碼再決定信任的人,現在你知道界線在哪:引擎與規則邏輯可完整審計,彈幕與鏡像服務的身分是編譯期注入的空缺,自編譯版會安靜地少一塊。如果你只在乎正版授權的確定性,這類規則式工具的灰色本質不會因為引擎開源而改變,訂閱你自己信任的正版平台反而省心。

判斷裝了有沒有成功的標準很簡單:匯入規則後搜一部你追的番,目錄、時間表、彈幕三個地方都有東西,代表引擎與服務層都通了。失敗的話先換一條規則再說,規則與網站結構會互相漂移,這是規則式工具的宿命,也是那個 86 份規則的倉庫每天都在長大的原因。

Sliven 褚崇名
Sliven 褚崇名

每日分享科技新知、免費資源以及 WordPress、虛擬主機相關主題,任何問題歡迎在科技月球下方留言,或是發送 Email 至 [email protected] 與我聯繫。

文章: 1441

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


Share to...