TubeTube 自架 YouTube 下載器:手機貼網址,檔案直落資料夾

TubeTube 把 yt-dlp 包成 Docker 自架網頁下載器,手機瀏覽器貼網址就能排隊下載。實測下載鏈完整、成品自動嵌封面與詮釋資料,但格式代碼落空會靜默改抓最高畫質,介面零鑑別加跨來源全開,只適合留在自己信任的網路裡。

用 AI 摘要這篇文章:

想在自己家裡跑一台 YouTube 下載器的人,通常會先卡在三個問題:線上下載站說關就關,自己架的這台會不會兩個月後也跟著壞掉?手機上要怎麼操作?號稱免費開源,代價藏在哪裡?

TubeTube(GitHub:MattBlackOnly/TubeTube)給了其中一種答案:它把 yt-dlp 這套下載引擎包成一頁自己管的網頁介面,Docker 一行跑起來,手機瀏覽器貼上網址就能用。我在自己的 Mac 上把它的原始碼跑起來,完整下載了影片與音訊各一輪,也把整份程式碼讀完。結論先講:下載這條主鏈是真的,檔案直接落進你指定的資料夾,成品還自動嵌好封面和詮釋資料;但它的兩個預設行為官方說明完全沒提,一個會讓你以為要下 1080p 卻拿到 4K 巨檔,另一個會默默剪掉影片裡的贊助片段。加上整個介面沒有任何登入機制,這台機器適合放在你自己看得到的位置,不適合暴露到網際網路。

把 yt-dlp 包成一頁自己管的介面

TubeTube 的本體很小:Python 寫的 Flask 網頁服務,前後端靠 Socket.IO 即時推送下載進度,真正做下載的是 yt-dlp,轉檔與合併交給 FFmpeg。全部程式碼不到五百行,加上一個 Bootstrap 介面就是全部。它以 GPL-3.0 授權開源,用 GitHub Container Registry 的 Docker 映像分發,amd64 與 arm64 兩種架構都有,NAS 或小主機都裝得起來。

專案由 Matt Black 一人維護,2024 年 8 月開張,到目前累積 679 顆星、46 次 fork。整個倉庫 200 次 commit 全部來自作者本人與自動化機器人,沒有第二個貢獻者;issue 版上 22 筆紀錄清一色是作者自己的 PR 與相依套件更新機器人,外部使用者開的討論是零。這個數字先記著,後面談壽命時會用到。

預設的四個資料夾名字洩漏了它的設計意圖:Video 之外,Music 與 Podcast 是兩個獨立的音訊出口,差別只在副檔案格式(mp3 與 m4a),搭配音訊開關就是「把 YouTube 當播客來源」的使用流。依程式邏輯,丟入播放清單網址會整包展開、照清單名稱開子資料夾收納,單支影片的網址則只抓該支;這部分我沒有實測整份清單,行為以程式碼為準。

跟站上先前介紹過的 yt-dlp 腳本用法相比,TubeTube 走的是另一條路:指令列換成網頁,參數換成一份 YAML 設定檔,下載佇列換成瀏覽器裡的一張表格。引擎是同一顆,差別在你把操作的入口放在哪裡。

這台機器會不會壞掉:它把追版交給了機器人

YouTube 下載工具的死法通常很固定:YouTube 改版,抽取邏輯失效,維護者沒跟上,工具就死了。TubeTube 對這件事的答法是把追版本外部化成一條自動化鏈:GitHub Actions 每天固定時間檢查(UTC 中午,換算台灣時間是晚間八點) yt-dlp 有沒有新版,有就自動改需求檔、自動 commit、自動加上新的版本標籤、自動發 release、自動重建 Docker 映像推上 GHCR。整條鏈不需要人醒著。

看 commit 歷史會覺得這專案「很忙」:2026 年 3 月到 8 月的提交幾乎全是「Update yt-dlp version to …」這種機器人訊息,對應 yt-dlp 上游每個月的改版節奏。映像裡錨定的 yt-dlp 版本是 2026.08.19。功能本身的迭代其實很少,2026 年 8 月 20 日一口氣把版號推到 v1.0.0,隔天上午就補到 v1.0.3,內容多是啟動腳本與說明文件的修正。

對讀者來說,這種維護模式有兩面。好的一面:YouTube 改版後通常幾天內映像就自己追上了,你重新拉一次映像就好,這正是自架比依賴線上下載站可靠的核心理由(線上版的對照可以看先前介紹過的 yt1d,那是另一種商業模式)。要留神的一面:單人加機器人的專案,沒有社群在後面接手,官方說明寫錯或行為不符合預期時,你自己讀程式碼改設定檔的能力就是使用前提。

實測:下載流程與成品規格

我在 macOS 上用 Python 3.11 把原始碼直接跑起來(yt-dlp 用了與專案需求檔相同的 2026.08.19 版),以 Blender 基金會以 CC 授權釋出的開放短片《Big Buck Bunny》4K 版當測試標的,這樣下載測試本身不踩版權問題。這裡先講清楚:我跑的是原始碼而不是 Docker 容器,容器內的行為(檔案權限、定時更新)以下只依官方文件描述。

影片模式丟入網址後,介面表格出現該項目,狀態從 Pending、Downloading 一路跳到 Complete,進度以百分比加即時速度顯示,我這輪的速度落在每秒 56 到 70 MiB 之間。十分半鐘的片子下完,用 ffprobe 檢查成品:VP9 編碼、3840×2160、60fps、音軌 AAC 44.1kHz 雙聲道 128kbps,檔案 1.37GB;封面以附加圖流的方式嵌在檔案裡,詮釋資料含標題、頻道名、發布日期、原始網址與分類。音訊模式切 Music 資料夾再下一輪,成品是 18.2MB 的 mp3,封面與詮釋資料同樣嵌好。檔案落地後暫存資料夾是空的,切片檔會自己清掉。

TubeTube 桌面版深色介面,下載佇列表格顯示一支已完成影片Pin
桌面版深色介面:網址輸入、音訊開關、資料夾選擇與下載佇列一頁完成

音訊成品有個轉碼事實要知道:這輪實際抓到的音軌是 128kbps 的 AAC(編號 140),這也是它格式排序偏好 AAC 的結果,YouTube 另外還供應位元率相當的 Opus 音軌;mp3 是 FFmpeg 再轉出來的有損轉碼,轉換時品質參數開到最高檔;要求「原始位元流不打折」的人,把資料夾的音訊副檔名設成 m4a 才是直存。併發部分,服務啟動時依執行緒數開 worker,預設四條同時消化佇列,啟動記錄裡列出的是 Worker-0 到 Worker-3 四條;一個讀程式碼才看得到的細節是,介面上的進度數字並非每個事件都更新,程式以隨機抽樣的方式節流回報,好處是長片下載時瀏覽器不被更新風暴塞爆,代價是數字偶爾停格一下,屬於無害的取捨。

佇列行為有個小細節:同一個網址丟第二次會被擋下,介面跳出「Duplicate URL」提示,而且已經下載完成的項目會一直佔在清單裡,想重新下載同一部片得先手動移除該列(移除按鈕我實測可用)。另外介面是純英文,沒有多語言;我用 390 寬度的手機視口實測,版面是單欄排列不爆版,輸入框與下載鈕合成一組好按,主題有淺色、深色、跟隨系統三段切換,唯一的小瑕疵是資料夾下拉選單的提示文字在手機上會被截斷。

TubeTube 桌面版淺色介面,初始畫面與主題切換按鈕Pin
淺色主題初始畫面,底部有淺色、自動、深色三段切換
TubeTube 手機版深色介面,單欄排列的下載畫面Pin
手機視口單欄排列,輸入框與下載鈕合成一組,方便拇指操作

格式代碼是快照,落空時它不會告訴你

TubeTube 的畫質控制在 settings.yaml 裡,寫法是 YouTube 的格式編號(itag):預設影片用 625 加 140,直譯就是「1080p VP9 影軌加 128k AAC 音軌」。問題在於 itag 不是承諾,是 YouTube 當下有沒有提供那個轉碼的編號。我的測試片是 60fps 版本,用 yt-dlp 列出該片全部可用格式:1080p 在這支片上是 303、299、399 這些 60fps 專用編號,625 根本不存在。

不存在的時候會怎樣?程式裡的格式字串寫的是「指定編號加音軌,不行就用 bestvideo 加 bestaudio,再不行用 best」。結果就是我拿到 4K VP9 的 1.37GB 檔案,而不是設定檔名義上的 1080p。過程沒有任何警告,落空的那次下載在介面上看不出任何異狀。換句話說,README 教你填的那組數字在不少影片上會靜默失效,失效時的行為是往上跳到最高畫質,硬碟空間跟著往上跳。itag 會漂的原因也不難理解:YouTube 按片源的每秒影格數、轉碼進度與地區供應不同組合,同一部片的可用編號清單本來就是動態的,任何寫死的編號都只是當時的快照。

想拿到穩定的 1080p,自己改 settings.yaml 是唯一解:60fps 的片源填 303(VP9)或 299(H.264),一般 30fps 片源 625 才用得上。格式排序上它還有一組偏好(音軌語言、音訊編碼偏 aac、視訊編碼偏 VP9),可以在環境變數調整,但格式編號這層沒有「鎖高度」的寫法,這是繼承自 yt-dlp 的使用門檻,TubeTube 沒有把它包得更簡單。連帶一個實務提醒:想要小體積檔案的人,與其跟編號搏鬥,不如直接用音訊開關拿 m4a,或接受 720p 級別的編號(60fps 片源對應 302 與 298),把選擇權留在自己手上。

這台機器沒有鎖

第二個沒寫在 README 裡的事實:整個網頁服務沒有任何登入機制。我用瀏覽器打開首頁,直接就是操作介面;用 curl 帶著一個假造的第三方網域送交叉來源預檢請求,伺服器照樣回應允許,而且連憑證一起放行。程式碼裡 Socket.IO 的跨來源設定是星號(允許所有來源),Flask 的密鑰則是寫死在檔案裡的佔位字串。

把這幾件事合起來看:如果你的 TubeTube 執行在 NAS 上、port 又映射到路由器的對外側,等於任何人都能用你的下載器。更實際的情境是區網:跨來源全開加零鑑別,代表理論上你瀏覽到的任何網頁,都能嘗試對你區網裡的這台服務下指令,把你的頻寬與硬碟當成別人的下載農場。服務預設監聽所有網路介面,所以防護要自己做,做法從輕到重:docker-compose 的 port 映射寫成只綁本機迴路(例如 127.0.0.1:6543:6543),要從手機用就在 NAS 防火牆限來源網段;要對外就一定要在前端掛反向代理加帳號密碼;那個寫死的 Flask 密鑰雖然在這種單人自用場景影響有限,正式對外前也該一併換掉。官方文件對這些隻字未提,自架工具的預設值預設你會自己處理網路邊界。

同場加映一個讀程式碼才會看到的細節:Windows 環境下 FFmpeg 路徑寫死成 D 槽根目錄,那是作者自己機器的痕跡,也說明這專案的主要目標環境就是 Docker。

SponsorBlock:它默默幫你剪掉的段落

程式裡有個 README 完全沒提的預設行為:每支影片下載時都會查詢 SponsorBlock 的群眾標記資料庫,把標記為「贊助片段」的段落剪掉,再把剩餘章節縫合起來。這個行為寫死在下載流程裡,沒有設定開關。

我的測試片在資料庫裡沒有任何標記,所以剪輯沒有發生;對一般有標記的影片,效果取決於群眾標記的覆蓋品質,這是外部資料庫的變數,工具本身不保證。標記由觀眾投稿、按時間軸標出贊助段起訖,熱門片的標記通常又快又準,冷門片可能整支無人標記(我的測試片就是),所以「會被剪掉多少」每支片都不一樣。立場因人而異:有人視自動跳過廣告段為基本舒適,有人在意那正是創作者的收益來源。我自己的看法是把選擇權還給使用者會更好,至少給個開關;現狀是你若不想剪,得自己改程式碼重 build 映像。

順帶一提,這也是「GUI 包 CLI 引擎」這類工具的通病:引擎端做的事(格式選擇、贊助段剪輯、封面嵌入)都被介面藏在後面,說明文件只寫得出看得見的那層。同樣的結構先前在 Fluent-M3U8 那篇也出現過,差別在 TubeTube 綁的引擎會每天自動追版,Fluent 綁的是落後上游十五個月的固定版本。

上路:最短的一片設定

官方給的 docker-compose 只有一個服務:映像 ghcr.io/mattblackonly/tubetube、port 6543、幾個掛載點。比較值得理解的是它的資料夾概念:容器內 /data 底下照你 settings.yaml 裡定義的名字開資料夾,每個資料夾可以指定自己的格式與副檔名,預設給了 Video、Music、Podcast、General 四個,分別對應影片、mp3 音訊、m4a 音訊與混合用途。介面裡的資料夾下拉選單就是這份 YAML 的鏡像,音訊開關打開時只列有音訊設定的資料夾。

環境變數能調的東西不算少:執行緒數(預設 4)、偏好音軌語言、音訊與視訊編碼偏好、字幕寫出或嵌入(含自動字幕 fallback)、詮釋資料截短、以及容器內每天定時把 yt-dlp 升到最新或 nightly 版的開關。最後這個開關值得多看一眼:映像出廠錨定的是發布當天的 yt-dlp 版本,出廠後引擎何時升級就交給容器裡的排程;不想依賴排程的人,固定重拉 latest 映像也能達到同一件事,兩條路取一即可。字幕功能只認有實際字幕的影片,沒有時依設定退回自動生成的版本,想要繁中字幕記得把語言變數設好。cookies.txt 放進設定資料夾就能以登入狀態下載需要會員的內容,這條路能不能走、該不該走,責任在使用者自己。

版權這條線值得單獨講清楚。TubeTube 與 yt-dlp 都是自由軟體,工具本身站得住;它跟那些靠廣告變現、幫你繞過浮水印的商業下載站是不同物種。但「工具合法」不等於「下載什麼都合法」:備份你自己上傳的內容、下載 CC 授權的素材(像我的測試片)、抓自己需要的公開講座存檔,這些是自用的正當場景;大量重製有版權的商業內容、繞過付費牆,那條紅線是你自己的,跟工具無關。YouTube 的服務條款對下載行為另有立場,自架自用的風險與責任最終都落在使用者身上,這句話不含糊地寫在這裡。

誰該裝,誰該繞路

適合裝的人大致有個共同點:家裡已經有台常開的機器,而且不怕打開 YAML 改兩行字。你在找的是手機貼網址就能排隊下載、檔案直接進媒體庫資料夾、成品自帶封面與詮釋資料的作業流,TubeTube 這條鏈我實測是通的,維護面有每日機器人追版撐著引擎壽命。幾個具體場景:訂閱的頻道想留檔重看、把訪談轉成 mp3 進自己的播放器、幫長輩把操作影片存進平板能直接播的資料夾,這些都是它順手的地方。

該繞路的情況也明確:你要的是「給我 1080p 就永遠是 1080p」的確定性,不想理解 itag 是什麼,那格式代碼地雷會持續困擾你;你打算把這台服務開給家人以外的任何人用,零鑑別的介面撐不起這個場景;你需要中文介面或文件層級的支援,這裡都沒有。另外兩種人也可以直接略過:只是偶爾下載一支片的人,裝個 yt-dlp 指令列或瀏覽器書籤工具負擔小得多;要下載的是大量商業影片的人,該先想清楚的是授權與責任,不是工具。直播錄製與容器內的定時更新我這次沒有實測,官方功能清單列了直播支援、程式裡也有從頭錄起的參數,要用的話先拿小場景試跑再上。

TubeTube 是「引擎老老實實、殼有稜有角」的自架下載器。它把最難的兩件事(引擎壽命、檔案整理)處理得比預期好,把最該講清楚的兩件事(格式落空行為、網路暴露面)留在程式碼裡沒說。裝之前把 settings.yaml 的格式編號改成你實際要的,裝之後確認它只聽你信任的網路,剩下的就是它好好工作的部分。

Sliven 褚崇名
Sliven 褚崇名

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

文章: 1581

發佈留言

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


Share to...