功能: - StarLight Yggdrasil 第三方登录(后端中转,accessToken 不落地) - 管理员可视化权限管理(用户列表 + 一键授予/移出) - 设置页热配置(11 项可编辑,立即生效) - 循环池(每流独立手动歌单,队列空时随机不重复抽取) - 登录页统一主站浅色风格 - 全站改名「Starlight专属电台」 - 删除关于页 安全: - 全局 CSRF 防护(双提交 Cookie) - 登录限流防 XFF 伪造、错误信息脱敏 - 权限中间件 requireAdminForWrites(读放行/写 admin) - 密码哈希存储(scrypt/sha256) - SSRF 防护(封面下载域名白名单) - 空 catch 加日志、SSE 连接上限 修复: - 多角色账号 selectedProfile 缺失 - 普通用户越权删歌(V4) - streams 写操作越权(V9) - 设置页布局溢出 测试:38 项全绿(api16 / e2e17 / write5)
4.8 KiB
4.8 KiB
Starlight专属电台 · v2
把 audio/ 目录里的歌曲用 FFmpeg 切成 HLS 切片,拼成多路永不停播的直播流,并提供 Web 控制面板管理播放列表、导入音源(网易云 / 本地上传)。前后端一体的 Node.js 应用。
v2 相比 v1 的变化
- 数据库:JSON(playlist/heat/metadata)→ SQLite(better-sqlite3,WAL 模式),支持多路流隔离
- 鉴权:可选 Bearer Token → Cookie 会话登录(面板 + API 全保护,HLS 流不锁)
- 多路流:单流 → 多路独立直播流,各自播放列表,
/hls/{streamId}/index.m3u8 - 导入:仅网易云下载 → 增加本地上传导入(自动匹配作者/封面)
- 删除:无 → 级联删除(音频 + 切片缓存 + DB + 播放列表引用)
- 本地化:CDN 依赖 + 封面图 → 全部本地(
public/vendor/、public/covers/),系统字体 - 模块化:1233 行单文件 →
src/分模块
环境要求
| 依赖 | 版本 |
|---|---|
| Node.js | >= 18 |
| FFmpeg | 含 ffmpeg 与 ffprobe,在 PATH 中 |
安装与启动
npm install
npm start
首次启动若未设密码,控制台会打印随机登录密码:
[AUTH] 未设置 PANEL_PASSWORD,已生成随机登录密码: xxxxxx
建议固定密码:
# Windows PowerShell
$env:PANEL_PASSWORD="你的密码"; npm start
# Windows CMD
set PANEL_PASSWORD=你的密码 && npm start
# Linux / macOS
PANEL_PASSWORD=你的密码 npm start
访问 http://127.0.0.1:3000,用密码登录。
目录结构
demo/
├── index.js # 入口,委托 src/server.js
├── src/
│ ├── server.js # 主程序:装配路由、启动服务
│ ├── config.js # 配置(环境变量)
│ ├── logger.js # 日志(分级 + 落盘 + 面板可查)
│ ├── db.js # SQLite 初始化 + schema
│ ├── store.js # 数据访问层(全部 SQL 收敛于此)
│ ├── util.js # 工具函数
│ ├── media.js # ffprobe / FFmpeg 切片 / 并发队列
│ ├── metadata.js # 网易云 API / 封面本地化 / 元数据补全
│ ├── livestream.js # LiveStream 类 + 多路流管理 + 缓存
│ ├── scanner.js # audio/ 目录监听与同步
│ ├── auth.js # 会话鉴权
│ ├── sse.js # SSE 推送
│ └── routes/ # API 路由(auth / music / resources / streams / system)
├── public/ # 前端(index.html / login.html / css / js / vendor / covers)
├── scripts/fetch_vendor.py # 一次性下载前端 CDN 资源到本地
├── audio/ # 音频文件
├── data.db # SQLite 数据库(自动生成)
└── hls/ hls_cache/ # 直播流与切片缓存(自动生成)
API 一览
所有 /api/*(除 /api/auth/*)需登录。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/auth/login |
登录(body: {password}) |
| POST | /api/auth/logout |
登出 |
| GET | /api/resources |
资源列表 |
| GET | /api/music/search?keyword= |
网易云搜索 |
| POST | /api/music/detail |
网易云详情 |
| POST | /api/music/download |
网易云下载入库 |
| POST | /api/music/import |
本地上传导入(multipart) |
| POST | /api/music/delete |
删除音频(级联) |
| POST | /api/music/delete-batch |
批量删除 |
| POST | /api/music/enrich |
重新匹配元数据 |
| GET | /api/streams |
流列表 |
| POST | /api/streams |
创建流 |
| DELETE | /api/streams/:id |
删除流 |
| POST | /api/streams/:id/start|stop |
启停流 |
| GET | /api/streams/:id/playlist |
播放列表 |
| POST | /api/streams/:id/playlist/add|remove|reorder|clear|next|prev|jump |
播放列表操作 |
| GET | /api/system/cache |
缓存信息 |
| POST | /api/system/cache/cleanup |
手动清理缓存 |
| GET | /api/system/logs?tail= |
查看日志 |
| GET | /api/events |
SSE 实时推送 |
直播流地址
- 默认流:
http://127.0.0.1:3000/hls/main/index.m3u8 - 其它流:
http://127.0.0.1:3000/hls/{streamId}/index.m3u8
可用 VLC、PotPlayer、ffplay 打开。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
PANEL_PASSWORD |
随机 | 面板登录密码 |
PORT |
3000 | 端口 |
HLS_TIME |
5 | 切片时长(秒) |
SLIDE_WINDOW |
15 | 滑动窗口段数 |
MAX_CACHE_MB |
1000 | 缓存上限 |
FFMPEG_CONCURRENCY |
3 | 转码并发 |
SESSION_TTL_HOURS |
72 | 登录有效期(小时) |
LOG_LEVEL |
info | 日志级别 |
技术栈
Node.js · Express · better-sqlite3 · Multer · Chokidar · FFmpeg(HLS)· SortableJS · Bootstrap Icons