基于 Vue 3 的网络收音机,编译为桌面应用软件

基于 Vue 3 的网络收音机:从本地 stations.json 加载电台清单,在浏览器或 Electron 桌面端 直连公开直播流(MP3 / AAC 等直链与 HLS),无需自建音频后端。

https://github.com/yichuancq/net-rediohttps://github.com/yichuancq/net-redio

核心功能点

  • 电台列表 :运行时 fetch public/stations.json;支持根为数组,或 { "channels": [...] } / { "stations": [...] }(与 SomaFM channels.json 等字段对齐时可带封面、genre、lastPlaying 等)。
  • 浏览与搜索 :默认「所有电台」按热度排序;侧栏按大洲/国家筛选(countrycode);顶栏搜索匹配名称、国家、标签、genre、描述、DJ、在播曲目等。
  • 收藏 :顶栏星标进入收藏列表;卡片上星标添加/移除;数据存 localStorage(与 stationMergeKey 一致)。
  • 播放 :选中即播;Icecast 类直链与 .m3u8(hls.js,Safari 可原生 HLS);底栏音量、静音、播放/暂停。
  • 主界面 :深浅色主题(html.theme-light,本地记忆);侧栏可折叠;上方黑胶舞台(可选唱臂、多色唱片底、转速);封面主色轻染舞台背景;下方网格单独滚动;底栏含示意性电平动画(非 Web Audio 真实频谱)、封面与曲目信息。
  • 设置页 :主题强调色(色板 + 最近使用,写入 --accent 等 CSS 变量);唱片底片颜色/转速;是否显示唱臂、是否显示示波器区域;均持久化 localStorage。

主界面截图

项目结构

net-redio/

├── electron/

│ └── main.js # Electron 主进程(窗口、生产环境加载 dist/index.html)

├── public/

│ ├── index.html

│ ├── stations.json # 运行时加载的电台清单(路径与 App.vue 中 fetch 逻辑一致)

│ └── favicon.ico

├── scripts/

│ └── update-somafm-stations.mjs

├── src/

│ ├── App.vue # 根布局、清单/导航/播放/HLS(核心)

│ ├── main.js

│ ├── composables/

│ │ ├── useNetRadioTheme.js # 明暗主题 + html 类名

│ │ ├── useThemeAccentColor.js # 自定义强调色、最近色、CSS 变量

│ │ ├── useVinylAppearance.js # 唱片色/转速、示波器、唱臂;localStorage

│ │ ├── useRadioFavorites.js # 收藏 ID

│ │ └── useStationArtAccent.js # 封面主色采样(canvas,供舞台背景)

│ ├── data/

│ │ ├── stationCatalog.js # 解析、规范化、搜索/排序/按国家

│ │ ├── radioContinentNav.js # 侧栏大洲 → 国家

│ │ ├── continentNavCountries.js # 各洲 ISO2 与中文名

│ │ └── themeAccentPalette.js # 设置页主题色色板

│ ├── styles/

│ │ ├── net-tv-tokens.css # CSS 变量(明暗、强调色默认值等)

│ │ └── net-tv-global.css

│ └── views/net-radio/ # 侧栏、工具栏、舞台、网格、底栏、示波器、设置

├── electron-builder.yml

├── vue.config.js # publicPath、devServer;Electron 构建见上文

├── package.json

└── README.md

实现要点

位置 说明
App.vue stationsCatalog 全量;filteredStations 由 activeNavKey(all / favorites / country:xx)与搜索共同决定。stationMergeKey:UUID 优先,否则 u:+URL,作收藏与当前台 id。attachStream 先 destroyHls(),再区分 HLS 与直链。
stationCatalog.js normalizeStation 须存在 url_resolved 或 url;兼容多种 API 字段;parseStationsPayload 识别数组或 channels / stations。
useThemeAccentColor.js 有存储时覆盖 documentElement 的 --accent、--accent-dim、--brand-end、--card-active-border;无存储则沿用 net-tv-tokens.css。
useVinylAppearance.js 黑胶渐变背景定义在同文件导出的 VINYL_DISC_BACKGROUNDS(NetRadioStage 使用)。
收藏 useRadioFavorites 的 id 与网格 stationMergeKey 一致;收藏列表从全量 stationsCatalog 过滤,避免子列表截断导致「收藏消失」。
相关推荐
paopaokaka_luck15 分钟前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
sm_9267870518 分钟前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
IMPYLH29 分钟前
HTML 的 <video> 元素
前端·html
溪语流沙1 小时前
【每天一个CSS | Day19】流光文字与一笔写成的手写签名
前端·javascript·css
逐光者9331 小时前
STM32——SPI 屏 · Flash · 高速
java·前端·stm32
To_OC1 小时前
同样是让 AI 写全栈,为什么别人一句话就够了
前端·前端框架·next.js
CDwenhuohuo2 小时前
electron pc项目打包成桌面端
前端·javascript·electron
前端大斗师2 小时前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
Jmyd01232 小时前
用 Web VR 引擎搭建 3D 虚拟展厅:从素材上云到多端实时渲染的完整数据链路
前端·3d·vr·三维数字化
刘天远3 小时前
Agent成本核算实现:事件表、状态分布与Python归集
前端·数据库·人工智能·python