Lofi Radio Web:把背景音樂與專注計時收進一個網頁的開源播放器

Lofi Radio Web 是 88lin 用 Next.js 16 開發的開源網頁 Lofi 播放器,收 21 個公開電台來源,內建專注計時與睡眠定時,支援 PWA。音樂來自 Bilibili、SomaFM 等第三方串流,計時資料只待在瀏覽器本地。MIT 授權,可自架於 Vercel 或 Docker。

用 AI 摘要這篇文章:

Lofi Radio Web 是一個在瀏覽器裡跑的 Lofi 播放器,作者 88lin 用 Next.js 16 把另一個桌面版的 lofi-radio 改寫成網頁應用,順手把專注計時和睡眠定時一起做進去。打開官網 lofi.88lin.eu.org 就能聽,不用登入、不用安裝、也不收錢,原始碼以 MIT 釋出在 GitHub。

它解的痛點其實很小:你想在寫程式或讀書時放一點不搶注意力的背景音,但又不想被 YouTube 的推播拉走、不想被 B 站直播的彈幕打斷,更不想為了臨時需求開一個 Spotify 重型客戶端。Lofi Radio Web 的處理方式是把 21 個精選 Lofi 與環境音源整理在同一個簡潔的播放器裡,需要的時候打開網頁、點掉就關掉。

Lofi Radio Web 官網首頁與浮動動態島播放器Pin
Lofi Radio Web 官網首頁,左下為可拖動的 macOS 風格動態島播放器,中央為黑膠唱片動畫與電台選擇。(圖片來源:lofi.88lin.eu.org,2026-07)

播放、計時、動態島:整個介面只留三件事

要理解 Lofi Radio Web 在幹嘛,得先理解它故意不做的部分。它沒有歌單推薦、沒有留言區、沒有社群、沒有個人化演算法,連帳號都不用註冊。整個介面只剩播放、暫停、切換電台、暗色亮色主題,以及一個 macOS 風格的「動態島」浮動小窗,可以拖到螢幕任意位置。

作者把心力放在三件大多數音樂平台不會花力氣的事上:一是把焦點計時器做進播放器(只在音樂播放時累計),二是睡眠定時(15、30、45、60、90、120 分鐘預設,或 1 到 480 分鐘自訂),三是 PWA 支援,可以透過 Chrome 或 Edge 把它「安裝」成桌面獨立小視窗。三件事加起來,等於把一個輕量番茄鐘跟播放器綁在一起,這是它跟一般音樂串流服務最大的差別。

老實說,這個定位很吃個人偏好。如果你期待的是「一個什麼歌都能搜的音樂庫」,那它顯然不合格;但如果你要的是一個開著不搶注意力、計時還會自己累積、用完即丟的背景音開關,這種減法反而成了優點。

21 個電台背後的音樂來源,是它最需要看清楚的地方

Lofi Radio Web 收錄的 21 個電台,依使用情境分成學習、編程、閱讀、放鬆、助眠、專注、其他七組。來源不是它自己錄製或擁有版權的音樂,而是把幾個公開的流媒體來源串起來,主要包括 Bilibili 的 Lofi Girl 直播流、Lofi Cafe、SomaFM 的幾個頻道(例如 Drone Zone、Groove Salad)、freeCodeCamp 的 Code Radio、瑞士古典電台 Swiss Classic,以及一些獨立的 Lofi 串流。

Lofi Radio Web README 電台分類清單,21 個電台分七組Pin
Lofi Radio Web README 的電台分類表,21 個電台依使用情境分七組,來源涵蓋 Bilibili、SomaFM、Lofi Cafe、Code Radio、Swiss Classic 等。(圖片來源:github.com/88lin/lofi-radio-web README,2026-07)

這件事必須講清楚:Lofi Radio Web 是一個聚合播放器,不是免版稅音樂庫。它播放的音樂,版權屬於原本的流媒體提供者。把它當作寫程式時的背景音源沒問題,但如果你打算把音樂錄下來、剪進要商業發布的影片配樂裡,請回原本的平台查授權條款,這條線作者自己在免責聲明裡也講得很明白。

Bilibili 直播流是它的一個實用特點。Lofi Girl 在 YouTube 上的官方直播因為地域授權的關係,有時連不上或被切換到其他版本;Bilibili 的直播流相對穩定,加上 HLS.js 與 flv.js 兩套播放庫做自動兜底,斷流時可以切到備援協定。當然,這也是它對第三方源穩定性的依賴:某個電台如果有一天轉圈圈轉不出聲音,多半是上游暫時斷掉或你的網路環境擋掉了那個來源,切別台通常比硬拗更省事。

專注計時與睡眠定時的資料,全部只待在你的瀏覽器裡

很多人對「計時器」這類工具的隱私疑慮,在於「我什麼時候工作、工作多久」這種行為紀錄會不會被送上伺服器。這部分 Lofi Radio Web 的處理是乾淨的:專注時長與睡眠定時的設定都用瀏覽器的本地儲存(localStorage),每日自動重置,不上傳任何使用者帳號或行為資料,因為它根本沒有帳號系統。

這也是它能維持「打開即用」的原因之一。沒有登入流程,就不會有密碼外洩的問題;沒有雲端同步,就不用擔心你的專注紀錄被當成產品分析資料。代價是你的累計時數不會跨裝置同步,換一台電腦就從零開始。對一個訴求「打開即用、聽完即關」的輕量工具來說,這個取捨合理;但如果你把專注時長當成長期生產力追蹤的一部分,那它不適合當主力記錄工具,請搭配其他有雲端同步的番茄鐘應用。

部署層面它託管在 Vercel 上,這也是作者最推薦的自架路徑。想要自己跑一套的人,Fork 原始碼到自己的 GitHub 帳號,匯入 Vercel、選 Next.js、設定 Node.js 20.9 以上,通常一鍵就能跑起來;作者也提供了 Dockerfile 與 Caddyfile 給有自己伺服器的人。唯一要留意的是它包含一個服務端 API(/api/bilibili-stream),用來解析 Bilibili 直播位址,所以部署環境必須支援 Node.js runtime 與服務端對外連線,純靜態託管平台(例如某些 Cloudflare Pages 設定)跑不起來。

怎麼用、怎麼自架:從打開網頁到 Fork 一份自己的版本

Lofi Radio Web 的使用門檻分兩層。第一層是純使用者,什麼都不用設定,打開 lofi.88lin.eu.org、選一個電台、按播放,就這樣。鍵盤快速鍵也設計得很精簡:空格鍵播放或暫停、左右方向鍵切電台、M 鍵靜音、T 鍵切主題。沒有選單層層疊疊,沒有設定頁要挖,第一次用的人不會迷路。

第二層是想自架的人。作者把這條路寫得相當完整,主要給三條部署路線。第一條是 Vercel,先把倉庫 Fork 到自己的 GitHub 帳號,到 Vercel 匯入這個 Fork,框架預設會自動抓到 Next.js,Build Command 用預設的 npm run build,Node.js 版本設到 20.9 以上,公開功能通常不需要任何環境變數,按下 Deploy 就能跑。

第二條是自己的 Linux 伺服器或 VPS。這條路走的是標準 Next.js Node 服務:npm install 裝依賴、npm run build 建構、npm run start 啟動,預設監聽 3000 連接埠,前面掛 Nginx 或 Caddy 做反向代理即可。倉庫裡附了一份 Caddyfile 當參考。

第三條是 Docker。倉庫根目錄有現成的 Dockerfile,docker build -t lofi-radio-web . 建好映像檔,docker run -d -p 3000:3000 --restart unless-stopped lofi-radio-web 跑起來,容器內部會自動執行 npm run start。這條路對已經用 Docker 管基礎設施的人最省事。

要特別注意的是,作者在 README 明白標示 Cloudflare Pages 與 Netlify 不是他主推的部署路徑。不是因為完全跑不起來,而是這個專案包含服務端 API,需要 Node.js runtime 與服務端對外連線,而這兩個平台對 Next.js server runtime 的支援與網路策略各有差異,硬套模板反而容易踩坑。如果你不是很熟悉這些平台,照作者的建議走 Vercel、標準 Node 伺服器或 Docker 會更穩。

技術架構:Next.js 16、HLS.js 與 flv.js 撐起來的播放層

從技術角度看,Lofi Radio Web 是一份滿完整的現代前端範例。底層是 Next.js 16(App Router)加 React 19,狀態管理用 Zustand,樣式用 Tailwind CSS v4,動畫用 Framer Motion,圖示用 Lucide。這套組合在 2026 年是相當主流的網頁應用技術棧,對想學 Next.js 16 實戰的人來說,這個倉庫本身就是一份可讀性不錯的參考。

真正有意思的是它的播放層。Lofi Radio Web 同時用了 HLS.js 與 flv.js 兩套串流庫。HLS.js 處理的是 HLS 協定的來源(HTTP Live Streaming,蘋果主推的協定,多數網頁串流用它);flv.js 處理的是 FLV 格式,這條路主要是為了 Bilibili 直播流而準備的,因為 Bilibili 的直播是 FLV 或 HLS 兩種協定並存,播放器會根據來源自動切換或兜底。這也是為什麼前面提到它需要服務端 API 來解析 Bilibili 直播位址,純前端解不開。

計時功能拆成三個自訂 Hook:useAudioPlayer 管播放邏輯、useFocusTimer 管專注累計、useSleepTimer 管睡眠定時。狀態統一透過 Zustand 的 store 管理,資料落地用瀏覽器 localStorage。這個分工的好處是每個關切點各自獨立,要改專注計時邏輯不會動到播放器,要加新 Hook 也不會打亂既有結構。對初學者來說,這個程式碼組織方式是很值得學的範本。

跟 lofi.cafe、Pomofocus 比起來,它卡在一個有點微妙的位置

把 Lofi Radio Web 放在同類工具的脈絡裡看,會比較清楚它的差異。lofi.cafe 是性質接近的網頁 Lofi 播放器,介面漂亮、電台分類清楚,但同樣是閉源的網頁服務,你想自架或改 UI 都沒辦法。Pomofocus 則是經典的純網頁番茄鐘,計時邏輯完整、統計清楚,但沒有音樂播放能力,得自己另外開一個分頁放音樂。

Lofi Radio Web 把這兩件事捏在同一個介面裡:你有 Lofi 音源可以放、有計時器可以累計、又能 PWA 安裝成桌面小窗。再加上它是 MIT 授權的開源專案,理論上你可以 Fork 之後加自己喜歡的電台、改主題配色、換掉動態島造型。對會寫一點前端的人來說,這個可塑性是 lofi.cafe 那類閉源服務給不了的。

但它的弱項也得說清楚。76 顆星、16 個 fork 的規模,意味著它的維護人力非常集中,主要靠作者一個人推;電台源的可用性完全取決於第三方,作者能做的只是換備援來源;它也不是免廣告保證,因為上游的 Bilibili 或 SomaFM 哪天在自家平台插廣告,Lofi Radio Web 也擋不住。把它想成一個開源的「Lofi 介面層」而非「音樂服務本身」,會更貼近它的真實定位。

工具 類型 計時功能 音樂播放 開源 自架
Lofi Radio Web 網頁+PWA 內建專注計時、睡眠定時 21 個精選 Lofi 與環境音源 MIT 支援 Vercel、Docker
lofi.cafe 網頁 多個 Lofi 頻道 閉源
Pomofocus 網頁 標準番茄鐘 開源
Forest 手機 App 種樹機制 閉源
Lofi Radio Web GitHub 專案主頁,MIT 授權、76 星標、TypeScriptPin
Lofi Radio Web GitHub 專案頁面。作者 88lin,MIT 授權,TypeScript 開發,76 stars、16 forks。(圖片來源:github.com/88lin/lofi-radio-web,2026-07)

跟 TechMoon 寫過的其他工具放在一起看

如果你習慣在工作時配一點聲音,但 Lofi Radio Web 的 21 個電台不夠你挑,可以回頭看我們之前介紹過的 AudioMass。它是免安裝的瀏覽器音訊編輯器,比較適合需要動手剪錄音檔的場景,跟 Lofi Radio Web 側重的「被動聆聽」是不同需求。

如果你想追蹤的是 AI 編程工具的用量而不是工作時長,CodexBar 把 50 多個 AI 工具的額度做進 Mac 選單列,概念上跟 Lofi Radio Web 的「把計時器收進播放器」是同一種把雜訊整合進單一介面的設計思路。

另外,若你在找的是用打字強迫記憶的學習工具,Qwerty Learner 那種以專注輸入驅動的背單字工具,跟 Lofi Radio Web 一樣都屬於「打開來就進入工作狀態」的輕量生產力工具,兩個搭在一起用剛好。

結論:把背景音與計時收進同一個網頁的開源工具

Lofi Radio Web 沒有挑戰主流串流平台的意思,作者 88lin 處理的問題更小、更具體:把「背景音」與「專注計時」這兩件工作時常被分開做的事捏在同一個網頁裡,並且把所有計時資料留在你的瀏覽器本地,把整套原始碼以 MIT 開放出來,讓你能自架、能改造。

它的限制很明確:音樂來源是第三方、規模小、電台源會斷、計時不跨裝置同步。但如果你本來就只想找一個打開網頁就能聽、計時自己跑、用完即關的背景音工具,而且你願意接受它對第三方音源的依賴,那 Lofi Radio Web 是少數把這個簡單需求做到乾淨、又把授權與資料流向講明白的選擇。對前端開發者來說,它也是一份用 Next.js 16 加 HLS.js 做網頁音訊播放器的良好學習參考。

想直接體驗的話,打開 lofi.88lin.eu.org 選一個電台就能開始聽;想深入了解原始碼或自己部署一套,作者在 GitHub 上準備了完整的 Vercel、Docker 與自架伺服器三條路線的文件。

Sliven 褚崇名
Sliven 褚崇名

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

文章: 617

發佈留言

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


目錄
Share to...