准备一台云服务器:选择安装Agent镜像(openclaw、Hermes等)

在这里插入图片描述
提醒!!懒人同志,请直接让你的云服务器安装Agent镜像,然后让你的Openclaw或者其它AI帮你打造一个即可,只需要把下面的内容复制给你的AI,直接等待就好啦。

从零打造私人音乐播放器:Vue 3 + Node.js 全栈实战教程

厌倦了音乐平台的广告和会员?本文带你从零搭建一个私人流媒体音乐播放器,支持在线播放、电台管理、播放历史,部署到自己的服务器,从此听歌自由。


一、功能概览

  • 🎵 扫描本地音乐文件,自动提取歌名、艺术家、专辑等 ID3 信息
  • ▶️ 在线流式播放,支持进度拖拽、音量调节、三种播放模式
  • 📻 创建电台频道,自由组织歌单
  • 🕐 播放历史记录
  • 🎨 类 Apple Music 浅色主题,毛玻璃效果

二、技术选型

层级技术选型选型理由
前端Vue 3 + TypeScript + ViteComposition API 开发体验好,构建快
状态管理PiniaVue 3 官方推荐,API 简洁
后端Express (Node.js)轻量、生态完善、与前端语言统一
数据库SQLite嵌入式数据库,零配置,适合单机部署
音频标签music-metadata支持 MP3/FLAC/OGG 等主流格式元数据解析
部署Nginx + PM2反向代理 + 进程守护,生产级

三、项目结构

streaming-app/
├── backend/              # Express 后端
│   └── src/
│       ├── index.js      # 入口,启动服务
│       ├── db.js         # SQLite 数据表初始化
│       ├── scanner.js    # 音乐文件扫描 + 标签解析
│       └── routes/
│           ├── music.js      # 音乐库 + 流媒体 API
│           └── stations.js   # 电台 CRUD API
├── frontend/             # Vue 3 前端
│   └── src/
│       ├── App.vue       # 根组件 + 底部 Tab 导航
│       ├── views/        # 页面(Library/Stations/History)
│       ├── components/   # 播放器组件
│       ├── stores/       # Pinia 状态管理
│       ├── api/          # Axios 请求封装
│       └── router/       # 路由配置
├── music/                # 音乐文件存放目录
└── nginx/                # Nginx 配置

四、后端实现要点

4.1 依赖安装

npm install express cors better-sqlite3 music-metadata mime-types

关键包说明:

  • better-sqlite3:同步 SQLite 驱动,性能优于异步版本
  • music-metadata:解析音频文件 ID3/Vorbis 标签
  • mime-types:根据文件扩展名获取 MIME 类型

4.2 数据库设计

三张表足矣:

  • stations(电台):名称、描述、创建时间
  • station_tracks(电台曲目):关联电台 + 文件路径 + 排序
  • play_history(播放历史):文件路径 + 歌曲信息 + 播放时间

4.3 音乐文件扫描

核心逻辑:递归遍历目录 → 过滤音频后缀 → 解析元数据

支持的格式:.mp3 .flac .wav .ogg .aac .m4a .opus .wma

解析成功则取 ID3 标签(歌名/艺术家/专辑/时长),失败则用文件名兜底。

4.4 流媒体传输(重点)

这是整个项目最关键的部分——如何让浏览器播放服务器上的音频文件并支持拖拽进度条:

实现 HTTP Range 请求:

  • 浏览器请求音频时带上 Range: bytes=xxx-yyy
  • 服务端返回 206 Partial Content + Content-Range
  • 按需读取文件片段,fs.createReadStream 管道输出

这样做的优势:

  • 用户拖到歌曲后半段,只请求后半段数据,不用等整首加载
  • 大文件也能秒开播放

4.5 API 接口一览

接口方法说明
/api/music/libraryGET返回完整音乐库列表(含元数据)
/api/music/stream?path=xxxGET流式播放音频文件
/api/music/cover?path=xxxGET提取音频内嵌封面图
/api/music/historyGET/POST查询/记录播放历史
/api/stationsGET/POST电台列表/新建电台
/api/stations/:idGET/PUT/DELETE电台详情/编辑/删除
/api/stations/:id/tracksPOST/DELETE添加/移除电台曲目

五、前端实现要点

5.1 播放器状态管理(Pinia Store)

这是前端的核心,全局管理一块状态:

  • 播放队列(queue)+ 当前索引(currentIndex)
  • 音频对象(Audio Element):动态创建、绑定 timeupdate/ended 事件
  • 播放模式(sequential / repeat / shuffle)
  • 交互方法play() pause() next() previous() seekTo(percent)

next() 的逻辑:

顺序播放 → 当前+1,到末尾停止
单曲循环 → (当前+1) % 队列长度
随机播放 → Math.random() × 队列长度

播放结束自动记录历史:

audio.addEventListener('ended', () => {
  musicApi.recordPlay({ file_path, title, artist, album });
  next(); // 自动切下一首
});

5.2 UI 设计思路

参考 Apple Music 风格,整体采用浅紫白渐变背景 + 毛玻璃卡片

页面布局:

  • 顶部:大标题 “Library” + 搜索图标 + 用户头像
  • 分类栏:横向滚动的胶囊标签(全部 / 各专辑 / 各文件夹)
  • 内容区:歌曲卡片列表(渐变色封面 + 悬浮播放按钮)
  • 底部:播放器控制栏 + Tab 导航栏(音乐库 / 电台 / 最近)

交互细节:

  • 卡片 hover 时:歌名图标淡出 → 圆形播放按钮淡入
  • 当前播放的歌曲卡片高亮显示
  • 进度条可点击跳转,hover 显示拖拽滑块
  • 播放队列以抽屉面板形式从播放器上方滑出

5.3 路由设计

三个页面,极简:

/ → 音乐库(Library.vue)
/stations → 电台(Stations.vue)
/history → 最近播放(History.vue)

六、部署上线

6.1 Nginx 配置要点

location /api/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;        # ⚠️ 必须关闭,否则无法拖拽进度
    proxy_read_timeout 600s;    # 长超时,大文件不断连
}

location / {
    try_files $uri /index.html; # SPA 路由回退
}

proxy_buffering off 是必须的,否则 Nginx 会先把整个音频文件缓存到内存再返回,导致 Range 请求失效。

6.2 PM2 守护

pm2 start src/index.js --name streaming-backend
pm2 save      # 保存进程列表
pm2 startup   # 设置开机自启

6.3 启动步骤

# 1. 安装依赖
cd backend && npm install
cd ../frontend && npm install

# 2. 构建前端
cd frontend && npm run build

# 3. 启动后端
cd ../backend && pm2 start src/index.js

# 4. 配置 Nginx 并启动
ln -s /path/to/streaming.conf /etc/nginx/sites-enabled/
nginx -t && nginx

# 5. 把音乐文件丢进去
cp -r /your-music/* /opt/streaming-app/music/

# 6. 打开浏览器访问 http://your-server:8081

更多推荐