mirror of
https://github.com/nianzhibai/91.git
synced 2026-06-15 08:45:41 +08:00
7e5e67697e
Implement a new GuangYaPan cloud drive integration across the backend, admin UI, playback proxy, and Spider91 migration flow. Backend changes:\n- Add a GuangYaPan drive driver with token refresh, QR/device login support, directory listing, stream link resolution, directory creation, rename/delete operations, OSS multipart upload, and upload task polling.\n- Register GuangYaPan as a supported storage kind in configuration, catalog normalization, admin APIs, public drive labels, and 302 playback redirects.\n- Allow Spider91 crawler uploads to target GuangYaPan through a dedicated migration adapter.\n- Add scan, thumbnail, preview, and fingerprint cooldown handling for GuangYaPan based on explicit HTTP status codes, Retry-After values, and structured provider codes instead of natural-language message matching.\n- Tighten existing provider cooldown detectors so OneDrive, Google Drive, 115, PikPak, 123pan, Wopan, and media workers avoid treating arbitrary response text as a rate-limit signal.\n- Keep large videos eligible for preview generation unless the user disables preview generation. Admin and tooling changes:\n- Add GuangYaPan as a selectable drive type with QR login UI and token/root-path credential fields.\n- Add crawler upload target support for GuangYaPan in the admin UI.\n- Add drive branding, labels, metadata display, and docs/config examples for GuangYaPan.\n- Include a standalone GuangYaPan QR login helper script for manual credential acquisition. Tests:\n- Add GuangYaPan driver, QR login, proxy, admin API, crawler upload target, fingerprint, cooldown, and form coverage.\n- Update rate-limit tests to assert that message-only throttling text no longer starts cooldowns.\n- Cover explicit HTTP status parsing through shared drive helper tests.
216 lines
11 KiB
Markdown
216 lines
11 KiB
Markdown
# backend
|
||
|
||
视频聚合站的 Go 后端。提供三件事:
|
||
|
||
1. 多家网盘统一抽象(夸克 / 115 / PikPak / 联通网盘 / 光鸭网盘 / OneDrive / Google Drive / 本地存储)
|
||
2. 视频元数据目录(SQLite)+ 扫描 + 预览视频预生成
|
||
3. REST API(前台)+ 管理后台 + 直链代理
|
||
4. 标签池、视频隐藏、按网盘统计和详情页来源网盘类型展示能力
|
||
|
||
## 目录
|
||
|
||
```
|
||
cmd/server/main.go 入口
|
||
internal/
|
||
config/ YAML 配置
|
||
catalog/ SQLite 元数据
|
||
drives/
|
||
iface.go Drive 接口
|
||
quark/ 夸克(自己实现,参考 OpenList quark_uc)
|
||
p115/ 115(壳子 + SheltonZhu/115driver)
|
||
pikpak/ PikPak(自己实现,参考 OpenList pikpak)
|
||
wopan/ 联通网盘(壳子 + OpenListTeam/wopan-sdk-go)
|
||
guangyapan/ 光鸭网盘(参考 AList GuangYaPan)
|
||
onedrive/ OneDrive(OpenList 在线续期 + Microsoft Graph 文件接口)
|
||
googledrive/ Google Drive(OpenList 在线续期 + Google Drive API;播放走后端代理)
|
||
localstorage/ 本地目录扫描(服务器已有视频目录)
|
||
scanner/ 扫目录 → 落库
|
||
preview/ ffmpeg 抽封面和生成多段预览视频
|
||
proxy/ /p/stream/*、/p/preview/* 代理
|
||
auth/ 管理员 session
|
||
api/ REST 路由
|
||
config.example.yaml 配置模板
|
||
```
|
||
|
||
## 开发环境(Windows)
|
||
|
||
本仓库假设工具都装在用户目录,不需要管理员权限。
|
||
|
||
```
|
||
C:\Users\<you>\tools\
|
||
go\bin\go.exe Go 1.23+
|
||
ffmpeg\bin\ffmpeg.exe 任意 ≥ 4.x 版本
|
||
```
|
||
|
||
并加到 `PATH`。
|
||
|
||
### 第一次启动
|
||
|
||
Git Bash / WSL 环境推荐从仓库根目录启动完整开发环境:
|
||
|
||
```bash
|
||
npm install
|
||
./start.sh # 默认前端 production preview,无热更新
|
||
```
|
||
|
||
需要前端开发热更新时再用 `FRONTEND_MODE=dev ./start.sh --restart`。
|
||
|
||
PowerShell 下可以分两个终端手动启动,后端命令如下:
|
||
|
||
```powershell
|
||
cd F:\VideoProject\backend
|
||
go run ./cmd/server
|
||
```
|
||
|
||
首次启动会在当前目录创建:
|
||
|
||
- `config.yaml`(从 `config.example.yaml` 复制)
|
||
- `data/video-site.db`
|
||
- `data/previews/`
|
||
|
||
默认监听 `127.0.0.1:9192`。首次部署如果仍是默认管理员配置,登录页会要求先设置用户名和密码,并写回 `config.yaml`。如果本地已有旧的 `config.yaml`,请确认 `server.listen` 与前端代理端口一致。
|
||
|
||
### 连接前端
|
||
|
||
`vite.config.ts` 已经把 `/api`、`/p`、`/admin/api` 代理到 `127.0.0.1:9192`。
|
||
|
||
```
|
||
npm run build 构建前端静态资源
|
||
npm run preview 前端 9191,无热更新
|
||
go run ./cmd/server 后端 9192
|
||
```
|
||
|
||
## 添加一个盘
|
||
|
||
推荐在前端管理后台 `/admin/drives` 新增网盘。保存后会立即挂载并触发扫描;视频结果可在 `/admin/videos` 按网盘查看,每页 100 条,页面会同时显示各网盘预览视频已生成、待生成、失败数量。
|
||
|
||
也可以直接调用后端接口:
|
||
|
||
1. 先在浏览器访问 `/login` 完成首次管理员设置,或使用已有管理员账号登录:`POST /admin/api/login`
|
||
2. 新建盘:`POST /admin/api/drives`
|
||
```json
|
||
{
|
||
"id": "my-quark",
|
||
"kind": "quark",
|
||
"name": "我的夸克盘",
|
||
"rootId": "0",
|
||
"credentials": {
|
||
"cookie": "粘贴浏览器 F12 复制的 pan.quark.cn Cookie"
|
||
}
|
||
}
|
||
```
|
||
3. 手动触发扫描:`POST /admin/api/drives/my-quark/rescan`
|
||
|
||
各网盘的凭证字段:
|
||
|
||
| kind | credentials 字段 |
|
||
|--------|---------------------------------------------------------------|
|
||
| quark | `cookie` |
|
||
| p115 | `cookie`(形如 `UID=...; CID=...; SEID=...; KID=...`) |
|
||
| pikpak | `username`、`password`(token、验证码和设备 ID 由服务端自动处理并保存) |
|
||
| wopan | `access_token`、`refresh_token`,可选 `family_id` |
|
||
| guangyapan | 推荐后台扫码登录自动写入 `access_token`、`refresh_token`;也可手工填写 token;可选 `root_path` |
|
||
| onedrive | `refresh_token` |
|
||
| googledrive | 默认只需 `refresh_token`;自建 OAuth 客户端模式还需 `use_online_api=false`、`client_id`、`client_secret` |
|
||
| localstorage | `path`(服务器上的已有视频目录,如 `/mnt/videos`) |
|
||
|
||
### PikPak 速度说明
|
||
|
||
`disable_media_link` 默认按 `true` 处理,会使用 PikPak 的 `web_content_link` 原始下载链接;在当前服务器实测,单连接通常只有约 2.8-3 MiB/s。把该字段设置为 `false` 后,驱动会请求 `usage=CACHE` 并优先使用 `medias[].link.url`,当前服务器实测 `/p/stream` 64 MiB Range 可到约 8.9 MiB/s。
|
||
|
||
当前服务器同时存在 sing-box TUN 透明代理,PikPak 默认出站会被 `tun0` 接管;但强制直连物理网卡并没有更快,慢速的主要差异来自 PikPak 取链方式。media/cache CDN 节点仍有波动,偶尔可能遇到慢节点;如果播放变慢,可重新获取直链或重新挂载 PikPak 后再测。
|
||
|
||
OneDrive 按 OpenList 默认应用方式调用 `https://api.oplist.org/onedrive/renewapi` 在线刷新 token,不需要配置 Azure 应用的 `client_id` / `client_secret` / `redirect_uri`。后台新建 OneDrive 时只需要填 OpenList 代刷得到的 `refresh_token`;服务端会默认挂载根目录并自动回写新 token。
|
||
|
||
Google Drive 默认按 OpenList 在线 API 调用 `https://api.oplist.org/googleui/renewapi` 刷新 token。后台新建 Google Drive 时只需要填 OpenList Google Drive 获取到的 `refresh_token`。如果不想依赖 OpenList 在线 API,可以关闭“使用 OpenList 在线续期 API”,并填写同一个 Google OAuth 客户端授权得到的 `refresh_token`、`client_id`、`client_secret`,服务端会直接请求 Google OAuth token 接口续期。Google Drive 下载地址必须携带 `Authorization` 头,浏览器不能直接 302 使用,所以本站会由后端代理 `/p/stream` 播放,不加入零带宽 302 白名单。
|
||
|
||
## 文件名约定
|
||
|
||
扫描器按以下顺序解析文件名,用于提取标题和作者:
|
||
|
||
1. `[前缀] 标题 - 作者.mp4`
|
||
2. `[前缀] 标题.mp4`
|
||
3. `标题 - 作者.mp4`
|
||
4. `标题.mp4`
|
||
|
||
开头的 `[前缀]` 只会从标题里剥离,不会按分隔符作为任意标签入库。视频标签来自三类规则:
|
||
|
||
1. 文件名、作者和目录名命中系统标签或已有标签的标签名 / 别名。
|
||
2. 符合条件的目录名会自动创建 `collection` 合集标签,并给同目录视频打上该标签。
|
||
3. 常见番号类噪声会统一归并到 `AV`,避免把每个番号都变成独立标签。
|
||
|
||
当前内置系统标签为:`后入`、`奶子`、`口交`、`臀`、`人妻`、`女大`、`AV`。解析结果可在管理后台覆盖;手动保存后,该视频会标记为人工标签,后续扫描不会再自动覆盖。
|
||
|
||
## 视频去重
|
||
|
||
项目有三层去重:
|
||
|
||
1. 同一网盘同一文件按 `(drive_id, file_id)` 形成稳定视频 ID,重复扫描只更新同一行。
|
||
2. 扫描时优先按网盘侧 `content_hash` 去重;没有 hash 时退化为 `file_name + size_bytes`。
|
||
3. 扫描、本地上传或服务启动挂载网盘后,后台指纹 worker 会异步读取视频的少量 Range 片段,生成 `sampled_sha256`。前台列表、首页、搜索、推荐会按 `size_bytes + sampled_sha256` 只展示最早入库的 canonical 视频。
|
||
|
||
`sampled_sha256` 是文件级去重:适合识别同一个视频文件被复制到 115 / PikPak / OneDrive / Google Drive 等不同网盘的情况。它不会删除任何网盘文件,也不用于识别转码、裁剪、加水印后的同源视频。
|
||
|
||
封面和预览视频仍然优先生成,不等待指纹完成。夜间流水线最后会做一次重复资产清理:对 `size_bytes + sampled_sha256` 命中的非 canonical 视频,只删除本机生成的重复封面和预览视频,并把对应字段重置为 `pending`。网盘原文件和视频元数据记录不会被删除;如果 canonical 视频以后被移除,这些重复项会重新进入生成队列。
|
||
|
||
## 管理能力
|
||
|
||
- `/admin/drives`:新增、编辑、删除网盘,触发扫描。
|
||
- `/admin/videos`:按网盘筛选视频,每页 100 条分页,查看各网盘预览视频统计,编辑标题/作者/分类/标签,单条或全量重生预览视频;拉黑视频页可查看被删除或被隐藏的视频,并支持移出黑名单后在下次扫盘重新入库。
|
||
- `/admin/tags`:新增标签并用内置规则自动匹配已有视频;删除非系统标签时会从所有视频上同步移除该标签。
|
||
- 播放页视频信息会展示来源网盘类型,并提供删除入口。被删除或被隐藏的视频会进入黑名单,不会再出现在首页、列表、搜索和详情接口中;在后台移出黑名单后,会在下次扫盘时重新发现并入库。
|
||
|
||
## 预览视频生成
|
||
|
||
scanner 扫到新视频会把 `(driveID, videoID)` 丢进 worker 队列。worker 会先用 `ffprobe` 探测时长,再用 `ffmpeg` 抽封面和生成无声预览视频:
|
||
|
||
```
|
||
ffmpeg -ss <起点> -headers "UA/Cookie/Referer" -i <直链> \
|
||
-t 3 -an -vf scale=480:-2 -c:v libx264 -preset veryfast -crf 28 \
|
||
-movflags +faststart -y <local>.mp4
|
||
```
|
||
|
||
当前策略是每段固定 3 秒;30 秒以下最多 3 段,30 秒及以上固定 4 段;长视频在 20% 到 80% 区间均匀取段。生成的预览视频和封面都只保存在本地 `data/previews/`,不会回写到网盘;旧数据中的 `preview_file_id` 会被忽略。
|
||
|
||
服务启动或网盘重新挂载时,如果预览视频开关已开启,后端会把历史 `pending` 任务重新入队,避免重启后长期停在“待生成”。OneDrive 扫盘和直链生成预览视频 / 封面时可能触发 Microsoft Graph 429、`TooManyRequests`、`activityLimitReached` 或 throttled 文本;Google Drive 可能返回 429、`usageLimits`、`userRateLimitExceeded`、`downloadQuotaExceeded` 等限制标识。后端会识别这类错误并让当前网盘进入冷却期,保留任务为 `pending`,避免连续请求触发更严重限流。扫盘阶段会按 `Retry-After` 或默认冷却时间等待后继续当前目录。
|
||
|
||
前端卡片的 `previewSrc` 统一指向 `/p/preview/<videoID>`,后端只从本地 `preview_local` 文件读取。
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
# 前端,在仓库根目录执行
|
||
npm run lint
|
||
npm run build
|
||
node --test tests/previewIntent.test.ts
|
||
|
||
# 后端,在 backend/ 执行
|
||
go test ./... -count=1
|
||
```
|
||
|
||
## 部署到 Linux
|
||
|
||
推荐先使用根目录的预编译安装脚本:
|
||
|
||
```bash
|
||
sudo bash install.sh
|
||
```
|
||
|
||
它会从 GitHub Release 下载预编译包,安装运行依赖、写入 systemd 服务并启动。下面是手动部署方式,适合你想自己接管构建和服务管理时使用。
|
||
|
||
```bash
|
||
# 交叉编译
|
||
GOOS=linux GOARCH=amd64 go build -o video-server ./cmd/server
|
||
|
||
# 目标机
|
||
sudo apt install ffmpeg
|
||
scp video-server user@host:/opt/video-site/
|
||
ssh user@host
|
||
cd /opt/video-site
|
||
cp config.example.yaml config.yaml
|
||
# 改密码、监听地址
|
||
./video-server
|
||
```
|
||
|
||
配 systemd + nginx 反代到 `/` 和 `/api`、`/p`、`/admin`。
|