app-template/docs/superpowers/specs/2026-09-25-dandanplay-web-d...

8.6 KiB
Raw Blame History

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 实读)

说明:会话内 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. 浏览目录或扫描入库
  2. 打开视频 → stream 代理 → ArtPlayer
  3. 识别/拉弹幕(中继 + danmaku_cache)→ 弹幕层
  4. 节流上报 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