TechMoon 科技月球
WordPress、SEO 與 AI 工具實測指南
TechMoon 科技月球
WordPress、SEO 與 AI 工具實測指南

Folder2Podcast 是把音訊資料夾變成 Podcast RSS 訂閱源的自架小工具,Docker 一行指令就能上線,讓播客 App 接手斷點續播與跨裝置進度。這篇實測拆解幾件事:集數發佈日期是從 2024 年 12 月起算出來的假時間線、整個服務沒有任何登入機制所以私人邊界只到區網、README 宣稱的 iTunes 標籤在實際輸出一個都不存在,加上遲遲沒發佈到 stable 的 v2 開發線與倉庫裡缺落的授權條款。
用 AI 摘要這篇文章:
硬碟裡躺著一套有聲書 MP3,手機通勤聽到第七章,回家想用平板接著聽,才發現兩台裝置各記各的進度。這是很多自己收藏音訊檔的人都撞過的牆:檔案是你的,但「聽到哪」這件事沒有地方記。Folder2Podcast 給的答案很直接,把資料夾變成一條 Podcast RSS 訂閱源,讓現成的播客 App 接手續播、進度與同步。
我實際用 Docker 把它跑起來測過:一行指令、一個裝了幾個音檔的資料夾,服務就列出訂閱網址,抓下來的 RSS 也符合規範。不過實測同時驗出兩件 README 沒說清楚的事,一是整個服務沒有任何登入機制,「私人」的邊界只到你家的網路;二是文件宣稱完整支援的 iTunes 標籤,實際輸出一個都不存在。這篇把可用的部分和該小心的部分一次攤開。
先講清楚這個工具到底借了什麼巧力。Podcast 之所以好用,是因為十幾年累積下來的客戶端生態:Apple Podcasts、Pocket Casts 這些 App 天生就會記住每一集聽到第幾分鐘、換裝置時透過帳號同步進度、自動下載新集數。這些能力播客 App 原本就免費提供,問題只在於它們只認 RSS 訂閱源,不認你硬碟裡的資料夾。還在挑閱讀器的人可以順便看我們介紹過的 Readig 這類 RSS 與 Podcast 閱讀器,跨平台的選擇比想像中多。
Folder2Podcast 做的就是中間那層翻譯。它掃描資料夾、讀檔名、產生 RSS,之後的事全部交給播客 App。這個分工也是它最誠實的地方:工具本身不處理進度、不處理同步,那些是客戶端的工作。作者在文件裡對此有明確宣稱,我實測的範圍是服務端產生的 RSS 輸出,跨裝置同步的實際體驗取決於你選的 App,這段效果我沒有逐一驗證。
同樣的需求市場上早有重量級答案,audiobookshelf 這類自架有聲書伺服器就是標準解,功能全到有 App、有轉檔、有使用者管理。Folder2Podcast 走的是另一個極端,後面會對照兩者該怎麼選。
實測環境是本機 Docker,過程比說明文件寫的還短。建一個資料夾放幾個用序號命名的 WAV 檔,加上一個可有可無的 podcast.json 描述檔,然後一行指令:
docker run -d -p 3000:3000 -v /path/to/audio:/podcasts -e BASE_URL=http://192.168.1.10:3000 yaotutu/folder2podcast
容器啟動後終端直接印出掃描結果:找到幾個播客源、每個幾集、RSS 網址是什麼。打開網頁介面,清單頁列出播客名稱、集數與最新更新時間,旁邊附上複製訂閱網址的按鈕,以及 Apple Podcasts、Overcast、Pocket Casts、Castro、Moon FM 五個一鍵訂閱鈕。介面文字是簡體中文,台灣使用者看功能沒有障礙,但第一次接觸會明顯感覺到這是對岸專案。有個小地方值得記:清單頁顯示的「最新更新」日期也是算出來的那條假時間線,我的測試資料明明當天才建立,頁面卻寫著 2024 年 12 月,第一次看到先別以為是抓錯資料。

兩個環境變數直接決定訂閱成敗。BASE_URL 決定 RSS 裡所有連結的開頭,本機測試填 localhost,要讓手機訂閱就得填區網內伺服器的實際位址,填錯的症狀是 App 訂閱成功但音檔全部載不到。PUID 和 PGID 則處理 Linux 上常見的資料夾權限問題,把音樂資料夾擁有者的使用者 ID 填進去即可。掛載時可以加上唯讀參數,原始碼裡掃描與產生 RSS 的流程也只讀來源檔,訂閱清單存在容器自己的工作目錄,不會回寫你的音樂資料夾。
資料夾怎麼組織也有講究:掃描器把根目錄底下的每個子資料夾當成一支獨立的播客,各自產生一條 RSS。換句話說,一個掛載目錄可以同時放有聲書、課程錄音和演講整理,訂閱時各訂各的,互不干擾。每個子資料夾裡還可以放一張命名固定的封面圖,掃到就用它當播客封面,沒放就套預設圖;podcast.json 也是每個子資料夾一份,標題、作者、語言、分類都能逐檔設定。想替不同類型的內容保持不同門面,靠資料夾結構就做得到,不需要任何額外設定介面。
實測最有趣的發現在 RSS 內容裡。我把三個檔案放進去,檔名開頭分別是 01、02、10,抓下來的 RSS 裡三集的發佈日期分別是 2024 年 12 月 18 日、19 日、27 日。檔案明明是我當天才產生的,日期卻落在 2024 年底。

翻原始碼就知道為什麼。episode.ts 裡寫死了一個基準日期常數 BASE_DATE,值是 2024 年 12 月 18 日,然後 generatePubDate 函式把集數當位移量加上去,第 N 集的發佈日就是基準日加 N 減一天。第 1 集落在 12 月 18 日,第 10 集落在 12 月 27 日,一天一集,整整齊齊。
這個設計有其道理。播客客戶端大多依日期排序集數,如果用檔案的真實建立時間,同時批次丟進去的幾百個檔案會擠在同一天,排序就亂了。用集數反推一條一天一集的時間線,客戶端看到的順序就和檔名序號一致。副作用是你在 App 裡看到的「發佈時間」是虛構的,這對私人收聽無妨,但如果你打算把這條 RSS 給別人訂閱,對方看到的日期全部是假的。podcast.json 裡另有 useMTime 選項可以改成使用檔案真實時間,此時排序改由檔案時間決定,魚與熊掌只能選一邊。
測到一半我往資料夾補了一個 05 開頭的新檔,沒有重啟容器,幾秒後重新查詢清單,集數從 3 變 4。底層用的是 chokidar 檔案監看,寫入穩定兩秒後才觸發、再加一秒防抖,避免大檔複製到一半被掃進去。日常把新下載的章節丟進資料夾,其他什麼都不用作。
檔名規則預設抓開頭數字(01-、001_ 這類);結尾是數字的命名(例如第一集01.mp3)要另外把擷取策略設成後綴模式才認得,也可以直接給自訂正規表示式。完全沒有數字的檔案有後備機制,原始碼會拿檔案時間戳記加上檔案大小湊出一個排序值,清單照樣排得出來,只是順序不如序號命名那樣可控。清理模式則只剝開頭或結尾的數字,01-第一章 會變成 第一章。文件裡有個例子寫第01期清理後會只剩第和期兩個字,我拿實際程式碼核對的結果是夾在中間的數字根本不會被處理,這個檔名清理後原樣不動,文件又一次比實作樂觀。
硬限制是格式。原始碼裡的副檔名判斷只接受 MP3、M4A、WAV 三種,FLAC、OGG 連出現在清單裡的機會都沒有。收藏裡有無損音樂的人要先轉檔,而它自己也完全不轉檔,只做清單。
這是要放最前面講的那件事。我把 server.ts 從頭讀到尾,全部路由裡找不到任何一行認證程式碼:沒有帳號、沒有密碼、沒有 API 金鑰,服務直接監聽所有網路介面。也就是說,只要能連到這台機器的這個連接埠,任何人都可以列出你全部的播客清單、下載全部音檔、拿到全部 RSS。我實測時不帶任何憑證,照樣把所有內容抓了下來。
在家用區網裡這通常可接受,路由器就是你的防火牆。真正的風險情境是把連接埠轉發到公網,想在公司用手機聽家裡的書,直覺做法就是開埠,這一開等於把整個音訊資料夾對全世界裸奔,而且 RSS 一旦被 Google 索引就連「知道網址才知道」這層保護都沒有。要有對外存取,正確做法是在前面加一層帶認證的反向代理,或走 VPN 連回家裡再存取。這些在目前發佈的版本裡都不提供,自己想;開發中的 v2 已經補了帳號機制,但何時變成正式發佈沒有時間表。
同場加映一個小提醒:podcast.json 裡的電子郵件欄位會原封不動寫進 RSS 的作者欄位,對外提供訂閱時記得填丟棄式信箱。
說明文件宣稱完整支援 Podcast RSS 2.0 規範與 iTunes 專有標籤,這句話我只信了一半。實際輸出裡,RSS 2.0 的部分確實齊全,標題、連結、描述、每集的 enclosure 音檔網址都在,多數客戶端靠這些就能訂閱播放。但 iTunes 命名空間的東西,實際輸出的 XML 裡一個 itunes 開頭的標籤都沒有,連命名空間宣告都不存在。我測了 Docker Hub 上兩個版本,穩定版和主線版結果相同。
回頭看原始碼,feed.ts 裡寫了加入 iTunes 標籤的程式碼,呼叫的是 feed 這個套件的擴充介面。問題是這個擴充機制在該套件的產出流程裡根本不會被讀取,呼叫了等於沒呼叫,產生出來的 XML 自然一個都不含。作者寫了、沒驗證輸出,文件就照設計意圖寫了。對私人收聽的實際影響有限,分類欄位、節目類型這些 iTunes 欄位缺席不影響播放;但如果你照文件期待拿它做需要 iTunes 欄位的應用,會直接落空。
要判斷它值不值得裝,最快的座標是拿 audiobookshelf 對比。同樣自架音訊庫,audiobookshelf 在 GitHub 上有一萬四千多顆星、GPL 授權、到我查證當天前一天還有程式更新;Folder2Podcast 一百七十八顆星、沒有授權條款、主線功能程式碼停在 2025 年 2 月。數字差距就是定位差距。
audiobookshelf 是平台:有自己的手機 App、掃描時自動抓 metadata、轉檔、多使用者帳號。Folder2Podcast 整個原始碼樹只有四十多個檔案,核心邏輯集中在幾支 TypeScript 檔,本質是把資料夾對應到 RSS 的翻譯層,其餘全交給別人。前者的部署與維護成本換來完整功能,後者五分鐘上線但功能邊界就是 RSS 規範本身。你的收藏如果需要 App 播放介面與豐富 metadata,走 audiobookshelf,或參考我們寫過的 qm-music-server 自架音樂伺服器;如果只是要把一批有聲書塞進既有的播客 App,這個小工具反而更輕。
評估自架工具離不開看它的呼吸狀態。專案 2025 年 1 月底開張,兩週內衝了十個版號到 v0.1.9,主線最後一次功能性提交在 2025 年 2 月,其後只剩文件修補。Docker Hub 的下載次數七千三百多次,規模是社群工具等級。
不過開發並沒有停下來,只是搬了地方。倉庫上有一條公開的 dev-v2 分支,提交一路排到 2026 年 1 月,Docker Hub 的 dev 映像跟著同步更新。從分支原始碼看,v2 是一次大改版:介面換成 Next.js,加上資料庫、檔案上傳、影片連結下載,連接埠也換了,前面提過的帳號機制就在這條線上,倉庫描述寫的「上傳本地音訊、貼上影片連結自動生成 RSS」對應的也是它。真正的落差在版本策略:這條線從未合回主線,也沒有發佈過 stable 映像,README 教人部署的 stable 標籤停在 2025 年 2 月的舊架構,描述裡的新功能全在還沒正式發佈的開發線上,兩版之間沒有任何過渡說明。你照文件裝,拿到的是堪用且我實測正常的舊架構;期待新功能,只能等作者哪天把 v2 扶正,而這件事沒有承諾也沒有時間表。
開發者帳號本身是活的,這幾個月還在推其他專案,folder2podcast 比較像是被他放到穩定維護、主力轉向商業版的狀態。另外唯一開著的 issue 是 2025 年 2 月留下的版號顯示建議,開的人是作者自己,等於一張沒兌現的待辦,與「穩定但低維護」的整體訊號一致。
授權部分要單獨講:倉庫裡找不到授權條款檔,GitHub 顯示授權狀態 None,只有套件定義檔裡一行 ISC 的宣告,嚴格說構不成完整授權。原始碼公開不等於開放授權,法律上預設保留所有權利。自己下載、自己跑,風險很低;要改作、散佈或整合進商業服務,嚴格說需要先向作者取得授權,這和 immich 自架相簿那類正式開源專案是不同的法律處境。
自己聽、家人一起聽、資料都在區網裡的人,這工具給的價值很實在,五分鐘把死檔案變成活的訂閱源,續播和進度從此交給播客 App 傷腦筋。若你的音訊來自 yt-dlp 這類下載工具,下來就照集數命名,這條路幾乎不用額外加工。
想在外面透過公網聽、又不會架反向代理的人,先停一下,它的無認證設計讓這個情境變成安全洞,用 VPN 或改用 audiobookshelf 這類有帳號機制的方案才是對的。需要豐富 metadata、App 播放介面、轉檔的人也一樣,直接往平台級方案走。
最後一種是把它當長期基礎設施的人。功能凍結對 RSS 這種穩定規範不算致命傷,我實測的一切也都正常,但 stable 版停留在舊架構、新功能全押在未發佈的 v2 開發線上,依賴它的同時最好把這個斷層算進風險。工具本身做得簡單而誠實,連它沒做的部分都一目了然,這在小型自架專案裡已經是中上水準,用對場景它就是好工具。