From ddc89858af7d559a4972da0f1f31a1315f7a8a27 Mon Sep 17 00:00:00 2001 From: noelorin Date: Fri, 25 Sep 2026 01:44:43 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20Web=20=E7=89=88=E5=BC=B9=E5=BC=B9play?= =?UTF-8?q?=20=E8=AE=BE=E8=AE=A1=E8=A7=84=E6=A0=BC=EF=BC=88=E6=96=B9?= =?UTF-8?q?=E6=A1=88=20A=20+=20Bangumi=20=E5=88=AE=E5=89=8A=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../specs/2026-09-25-dandanplay-web-design.md | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-25-dandanplay-web-design.md diff --git a/docs/superpowers/specs/2026-09-25-dandanplay-web-design.md b/docs/superpowers/specs/2026-09-25-dandanplay-web-design.md new file mode 100644 index 0000000..1b1a966 --- /dev/null +++ b/docs/superpowers/specs/2026-09-25-dandanplay-web-design.md @@ -0,0 +1,219 @@ +# Web 版弹弹play(媒体中心)— 设计规格 + +- **日期**:2026-09-25 +- **状态**:已获设计批准,待实现计划(writing-plans) +- **仓库**:`app-template`(按**产品仓**维护,业务进入现有分层) + +## 1. 背景与调研结论 + +弹弹play 官方定位是**本地视频 + 在线弹幕**的全功能播放器(非音乐播放器),能力包括智能识别、媒体库、AI 字幕、远程访问(浏览器可连 PC 内嵌 API)、媒体库可挂 SMB/WebDAV/Emby 等。 + +本项目要做的是:**独立 Web 应用**(方案 A),提供类似的「挂载源 → 浏览 → 播放 + 弹幕 → 媒体库/进度」体验,**不依赖**本机运行的 PC 弹弹play。 + +| 能力 | 决策 | +|------|------| +| 范围 | A — 独立完整 Web 应用 | +| 播放器 | ArtPlayer | +| 弹幕 | 对接弹弹play **开放弹幕网络**(服务端中继)+ 本地 XML 导入兜底 | +| 存储源 | **仅通用 WebDAV**(OpenList 使用其 WebDAV 端点;不做 OpenList 原生 API) | +| 后端 | 挂载代理 + 弹幕中继 + 媒体库/进度 **全做** | +| 刮削 | **Bangumi**:扫描自动匹配 + 手动搜索改绑(C) | +| UI | 全页面:播放 / 文件浏览 / 媒体库 / 挂载管理 / 弹幕设置 | +| 账号 | **多用户**:注册登录;每人独立库与进度 | +| 架构方案 | **A — 紧凑垂直切片 `media`**(复制 `user` 切片模式) | +| 视觉 | **shadcn/ui Dashboard** 风格(侧栏 + 卡片 + 中性灰阶),不以模板深空工业 HUD 为产品主视觉 | +| 落点 | **B — 产品化本仓**:业务进入 `app/web`、`packages/*` | + +### 调研来源(Browser Use 实读) + +- https://www.dandanplay.com/ — 产品能力与远程访问/WebDAV 叙述 +- https://doc.dandanplay.com/open/library-api.html — PC 远程访问 REST(本项目**不**对接;仅作产品对照) +- https://doc.dandanplay.com/function/media-library.html — 媒体库信息架构参考 +- https://github.com/OpenListTeam/OpenList — AList fork;本项目只用 **WebDAV** 接入方式 + +> 说明:会话内 IAB 不可用,调研经 `cua_repl` + `managed-chromium` 完成 SERP 与正文阅读。 + +## 2. 系统架构(方案 A) + +``` +浏览器 @app/web(React islands,shadcn dashboard) + ├─ 登录 / 媒体库 / 文件浏览 / 播放(ArtPlayer+弹幕) / 挂载 / 弹幕设置 + └─ 仅经 tRPC 与 /api/stream(Range)访问 + │ + ▼ +服务层 trpc + service + dao(@app/trpc · dao) + ├─ mount.* WebDAV 列目录、凭据加密、测试连接 + ├─ stream Range 拉流代理 + ├─ danmaku.* 开放弹幕网络中继 + 缓存 + ├─ scrape.* Bangumi 搜索/绑定;扫描内自动刮削 + ├─ library.* 扫描入库、列表、海报 + └─ playback.* 进度节流写入 + │ + ┌─────┴──────┐ + ▼ ▼ + Drizzle/Turso 外部:WebDAV · 弹弹play 开放弹幕网络 · Bangumi API +``` + +**分层约束(沿用仓库 AGENTS)** + +- Schema 源:`@app/models`;查询:`@app/dao`;连接:`@app/db` +- 业务逻辑:`@app/trpc` service(调 dao);入参 Zod:`@app/types` +- UI:`@app/ui` + design tokens;页面在 `@app/web` +- **产品化本仓**:新增业务实体照 `user` 垂直切片扩展(本产品期间业务代码进入现有分层,视为对「模板不掺业务」的产品化豁免) + +### 播放主路径 + +1. 登录 → 2. 配置 WebDAV 挂载 → 3. 浏览目录或扫描入库 +4. 打开视频 → stream 代理 → ArtPlayer +5. 识别/拉弹幕(中继 + `danmaku_cache`)→ 弹幕层 +6. 节流上报 `playback_progress` + +### 首版不做 + +OpenList 原生 API · 本机弹弹play 远程 API 对接 · BT/RSS · 多刮削源 · NFO 优先 · 公网多租户硬化(SSO/套餐限流) + +## 3. 数据模型 + +### users(已有 auth) + +沿用模板用户表与会话,不重复造账号。 + +### mounts + +| 字段 | 说明 | +|------|------| +| id | PK | +| userId | → users,级联隔离 | +| name | 展示名 | +| type | 固定 `webdav`(预留枚举) | +| baseUrl | WebDAV 根 URL(含 OpenList WebDAV 地址) | +| username | 可选 | +| secretEnc | **服务端加密**密文;API 永不回传明文 | +| rootPath | 根路径前缀 | +| enabled | 启用 | + +### media_items + +| 字段 | 说明 | +|------|------| +| id | PK | +| userId | 所属用户 | +| mountId | 可空(扫描所得) | +| path | 挂载内路径;`userId+path` 唯一 | +| rawName | 原始文件名 | +| title | 展示标题(可被刮削覆盖) | +| size / mime | 文件元数据 | +| bangumiId? | 刮削绑定 | +| epNumber? | 集数启发式 | +| scrapeStatus | `pending` \| `ok` \| `failed` \| `unmatched` | +| scrapedAt? | 最近刮削时间 | +| posterUrl? | 海报(Bangumi CDN 或占位) | +| matchedHash? | 弹幕匹配指纹(预留) | +| scannedAt | 入库时间 | + +### playback_progress + +`id · userId · mediaItemId · positionMs · durationMs · updatedAt` +唯一:`(userId, mediaItemId)`。 + +### danmaku_cache(全局,不绑 user) + +`id · matchKey · payload/xml · source · expiresAt` + +### bangumi_cache(可选,限流) + +`bangumiId · payload JSON · expiresAt` + +### Zod(@app/types) + +- `mountCreateSchema` / `mountUpdateSchema` +- `scanMountSchema` · `playbackReportSchema` +- `danmakuQuerySchema` · `danmakuImportMetaSchema` +- `scrapeSearchSchema` · `scrapeBindSchema` + +## 4. 页面与交互 + +### 路由(shadcn dashboard 侧栏) + +| 路径 | 页面 | +|------|------| +| `/login` `/register` | 认证(登录前仅此可见) | +| `/library` | 媒体库(默认登录后):海报卡、筛选全部/未匹配、继续播放、扫描入口 | +| `/browse` | 文件浏览:选挂载 → 面包屑目录 → 行内播放/加入库 | +| `/watch` | 播放:ArtPlayer + 弹幕层 + 同目录剧集(可选)+ 弹幕开关/导入 XML | +| `/mounts` | 挂载管理:CRUD、测试连接、按挂载扫描 | +| `/danmaku` | 弹幕设置:默认开关/透明度/密度;导入说明 | + +### 主流程 + +1. 注册/登录 +2. 挂载管理添加 WebDAV → 测试 → 保存 +3. 文件浏览点选播放,或「扫描」→ 刮削管线 → 媒体库 +4. `/watch`:stream → 弹幕中继 → 进度保存 +5. 媒体库「继续播放」带 progress 打开 `/watch` +6. 未匹配项手动 Bangumi 搜索绑定;详情可重新刮削 + +### 刮削管线(扫描) + +1. 列目录,视频入 `media_items` +2. 文件名启发式 → Bangumi 搜索 +3. 命中 → 写元数据/海报/`bangumiId` +4. 低置信 → `unmatched`,UI 手动搜绑 +5. 重复扫描按指纹/缓存,避免打爆 Bangumi;**刮削失败不阻断入库** + +### 视觉 + +- shadcn 风格组件语义:侧栏 nav、卡片、primary 按钮、Sheet 挂载表单、Dialog 确认、Toast +- 可基于 `@app/ui` 对齐 shadcn API,产品主题为中性暗色 dashboard(非工业信号黄主视觉) +- 动效克制,尊重 `prefers-reduced-motion` + +## 5. 错误处理 + +| 场景 | 策略 | +|------|------| +| WebDAV 401/超时 | 明确文案;浏览 skeleton + 重试;引导改凭据 | +| stream 失败 | 播放器错误 + Toast;不暴露栈 | +| 弹幕网络失败 | 降级无弹幕,可播;可仅本地 XML | +| Bangumi 失败 | `scrapeStatus=failed`,可重试;不回滚文件 | +| 进度失败 | 静默重试,不打断播放 | +| 权限 | 所有 library/mount/progress 查询强制 `userId` | + +## 6. 测试与验证 + +- types:Zod 单测 +- dao/service:进度 upsert、刮削绑定、路径规范化(mock HTTP) +- tRPC:跨用户越权 +- web:主路径冒烟(登录→列表→播放页);无 CI 浏览器则手动清单 +- 命令:`yarn typecheck` · `yarn lint` · `yarn build:web` +- 不做重型视觉回归 + +## 7. 实现范围(一个计划可覆盖) + +**In scope** + +- media 垂直切片全栈(mount/stream/danmaku/scrape/library/playback) +- 六个 UI 面(含登录沿用) +- ArtPlayer 集成与弹幕层(开放网络 + XML 导入) +- Bangumi 自动/手动刮削 +- shadcn dashboard 信息架构与主题 + +**Out of scope(本规格)** + +见 §2「首版不做」及 §1 调研中未选路径。 + +## 8. 风险与开放问题(实现前可再核) + +1. **弹弹play 开放弹幕网络** 端点、鉴权与条款:实现时以官方文档/实测为准,service 单点适配 +2. **Bangumi API** 限流与字段:实现时核对官方 API 文档 +3. **WebDAV 流**:Range、HTTPS 混合内容、大文件内存——stream 用流式管道,禁止整文件缓冲 +4. 艺术墙纸/版权:用户自备片源与挂载凭据 + +## 9. 批准记录 + +| 节 | 结果 | +|----|------| +| 架构 + shadcn dashboard | OK | +| 数据模型 | OK | +| 页面与交互 + Bangumi 刮削 C | OK | +| 错误/测试/边界 | OK | +| 方案选型 | A |