系统架构图
视频平台全局通信拓扑 — 模块关系与数据流
1. 全局架构总览
+------------------+
| 用户浏览器 |
| (手机/PC 客户端) |
+--------+---------+
|
+-----------------+------------------+
| |
v v
+-------------+-------------+ +---------------+--------------+
| Cloudflare Pages (前端) | | VIP 专线服务器 (Nginx) |
| videoagt / Next.js | | vip.mhana.top |
| mhana.top | | 137.175.4.97:443 |
| | | |
| - SSR/CSR 页面渲染 | | - secure_link MD5 验签 |
| - 视频播放器组件 | | - 本地磁盘直出视频/预览/缩略图|
| - VIP 配额计时 | | - 中国大陆优化带宽 |
+-------------+--------------+ | - PM2 + videoop --server |
| +------+--------+--------------+
| HTTPS API | |
v | |
+-------------+---------------------------+| |
| Cloudflare Worker (API 网关) || |
| videoworker / Hono || |
| videoserver.mhana.top || |
| || |
| +-- /api/feed --------- 推荐算法 ------+| |
| | (含 VIP URL 注入) || |
| +-- /api/video/stream -- R2 代理流 ----+| |
| +-- /api/auth --------- JWT 认证 ------+| |
| +-- /api/admin -------- 管理端点 ------+| |
| +-- /api/search ------- 语义搜索 ------+| |
| +-- cron (每日 3AM) --- 归档清理 ------+| |
+-----+--------+--------+---------+------+| |
| | | | | |
v v v v | |
+-----+-+ +---+--+ +---+--+ +----+--+ | |
| D1 | | R2 | | KV | |Analytics| | |
| 数据库 | | 存储 | | 缓存 | | 分析引擎 | | |
+---+---+ +---+--+ +------+ +--------+ | |
| | | |
| | rclone 全量同步 | |
| +------------------>--------+ |
| |
| D1 命令总线 (每 12s 轮询) |
+------------------------------>----------------+
|
+---------------------------------------------------+
| VIP 服务器上的 videoop (--server 模式) |
| - 轮询 D1 pipeline_commands 表 |
| - 接收 start/stop 命令 |
| - 执行采集→处理→上传流水线 |
| - 文件同时写入 R2 + 本地磁盘 |
+---+-----------------------------------------------+
|
v
+---------+---------+
| Telegram 频道 |
| (视频源) |
+-------------------+
2. 组件清单
| 组件 |
部署位置 |
技术栈 |
职责 |
| 前端 (videoagt) |
Cloudflare Pages |
Next.js / React |
用户界面、视频播放、VIP 配额计时、Admin 管理面板 |
| Worker (videoworker) |
Cloudflare Workers |
Hono / TypeScript |
API 网关、JWT 认证、推荐算法、R2 代理流、URL 签名、VIP URL 注入 |
| VIP 服务器 |
RAKsmart 137.175.4.97 |
Nginx + secure_link |
VIP 视频直出、签名验证、本地磁盘存储服务 |
| videoop (VIP) |
VIP 服务器 (PM2) |
Python + PM2 |
视频采集处理流水线、D1 命令轮询、写入 R2 + 本地磁盘 |
| D1 数据库 |
Cloudflare D1 |
SQLite (边缘) |
用户/视频元数据、命令总线、流水线状态 |
| R2 存储 |
Cloudflare R2 |
S3 兼容 |
视频/预览/缩略图 Blob 存储、归档备份 |
| KV 缓存 |
Cloudflare KV |
键值存储 |
用户已看列表 (SEEN_KV)、视频池缓存 (15min TTL) |
| Telegram |
外部服务 |
Telegram API |
视频源频道,videoop 通过 Telethon 客户端订阅下载 |
3. 核心数据流
3.1 普通用户看视频
用户浏览器
│
├─ 1. GET /api/feed ──────────────> Worker
│ (Bearer JWT) │
│ ├─ 查 D1: 用户信息、视频池
│ ├─ 查 KV: 已看列表 (去重)
│ ├─ 推荐算法选片 + HMAC-SHA256 签名
│ └─ 返回 FeedEntry[] (video_url 指向 Worker)
│
├─ 2. GET /api/video/stream/{key}?sig=...&exp=... ──> Worker
│ (Range: bytes=0-999999) │
│ ├─ HMAC 验签 (HMAC_SECRET)
│ ├─ 检查过期时间
│ ├─ R2.get(key, range)
│ └─ 返回 206 Partial Content
│
└─ 视频播放 (Cloudflare CDN 边缘缓存加速)
3.2 VIP 用户看视频 (Plan A: 直连)
用户浏览器
│
├─ 1. GET /api/feed ──────────────> Worker
│ (Bearer JWT) │
│ ├─ 查 D1: user.is_vip = true
│ ├─ 推荐算法选片
│ ├─ 生成普通签名 URL (video_url, 走 R2)
│ ├─ 生成 VIP 签名 URL:
│ │ MD5("{expires}/videos/{key}.dat {VIP_HMAC_SECRET}")
│ │ → Base64URL → vip_video_url
│ └─ 返回 FeedEntry[] (含 vip_video_url)
│
├─ 2. GET https://vip.mhana.top/videos/{key}.dat?st={md5}&e={expires}
│ (直连 VIP 服务器, 绕过 CF CDN)
│ │
│ └─> Nginx (vip.mhana.top:443)
│ ├─ secure_link 模块验证 MD5 签名
│ ├─ 检查过期时间
│ ├─ 从 /data/videos/{key}.dat 读取本地文件
│ └─ 返回 200/206 (中国大陆优化带宽)
│
└─ 视频播放 (中国大陆直连, 无 CF 中转, 低延迟)
关键差异:VIP 请求绕过 Cloudflare 网络,通过 DNS Only (灰色云) 解析直达 RAKsmart 中国优化带宽。
前端优先使用 vip_video_url,若超时/失败自动降级回 video_url (普通 R2 线路)。
3.3 视频采集处理流水线
Admin 管理页面 (前端)
│
├─ POST /api/admin/pipeline/command ──> Worker ──> D1 (pipeline_commands 表)
│ { action: "start", params: { channel: "...", limit: 50 } }
│
└─────────────────────────────────────────────────────────────────────┐
│
videoop (VIP 服务器, PM2 守护进程, --server 模式) │
│ │
├─ 每 12 秒轮询 ──> GET /api/admin/pipeline/commands/pending ──> D1 │
│ │ │
│ └─ 收到 "start" 命令 │
│ │
├─ 启动子进程: Telegram 频道采集 │
│ ├─ Telethon 连接 Telegram API │
│ ├─ 下载视频 (≤200MB, ≤3min) │
│ ├─ FFmpeg 压缩 + 生成预览 WebP + 提取缩略图 JPG │
│ ├─ NSFW 标签检测 │
│ ├─ 去重 (SHA256 哈希) │
│ └─ 上传处理: │
│ ├─ ──> R2 (videos/{uuid}, previews/{uuid}.webp, thumbs/{uuid}.jpg)
│ └─ ──> 本地磁盘 (/data/videos/, /data/previews/, /data/thumbs/)
│ │
├─ PATCH /api/admin/pipeline/status ──> Worker ──> D1 │
│ (每 1~5 秒推送进度: processed_count, current_file, speed...) │
│ │
└─ 子进程结束 → PATCH /api/admin/pipeline/commands/{id} │
{ status: "completed" } │
3.4 数据同步 (rclone)
R2 存储桶
│
├─ rclone sync r2:video-storage/videos/ /data/videos/ ──> VIP 服务器本地磁盘
├─ rclone sync r2:video-storage/previews/ /data/previews/ ──> VIP 服务器本地磁盘
└─ rclone sync r2:video-storage/thumbs/ /data/thumbs/ ──> VIP 服务器本地磁盘
│
└─ 已完成: 57,145 视频 + 57,144 预览 + 57,144 缩略图 ≈ 1.5 TB
注:初始全量同步已完成。后续新增视频由 videoop 直接写入本地磁盘 + R2 双写,无需再跑 rclone。
4. 通信矩阵
| 源 |
目标 |
协议 |
用途 |
认证方式 |
| 浏览器 |
Pages (前端) |
HTTPS |
页面加载 |
无 (公开) |
| 浏览器 |
Worker (API) |
HTTPS |
API 调用 |
JWT Bearer Token |
| 浏览器 |
VIP 服务器 |
HTTPS 直连 |
VIP 视频流 |
MD5 签名 URL (secure_link) |
| Worker |
D1 |
Binding |
元数据读写 |
Cloudflare 内部 |
| Worker |
R2 |
Binding |
文件读取/缓存 |
Cloudflare 内部 |
| Worker |
KV |
Binding |
已看列表/视频池 |
Cloudflare 内部 |
| videoop |
Worker API |
HTTPS |
D1 命令轮询/状态推送 |
WORKERS_ADMIN_TOKEN |
| videoop |
R2 |
S3 API |
上传视频/预览/缩略图 |
R2 Access Key |
| videoop |
本地磁盘 |
文件 I/O |
VIP 本地存储双写 |
- |
| videoop |
Telegram |
MTProto |
频道视频下载 |
API ID + Hash + Session |
| Nginx |
本地磁盘 |
文件 I/O |
读取视频文件并响应 |
secure_link 签名验证 |
| Admin 页面 |
Worker API |
HTTPS |
流水线控制命令 |
JWT (admin 角色) |
5. 安全架构
签名机制对比
| 线路 |
算法 |
密钥 |
格式 |
| 普通线路 (Worker) |
HMAC-SHA256 |
HMAC_SECRET |
/stream/{key}?sig={hmac}&exp={timestamp} |
| VIP 线路 (Nginx) |
MD5 (secure_link) |
VIP_HMAC_SECRET |
/videos/{key}.dat?st={base64url_md5}&e={timestamp} |
两条线路使用不同密钥和不同算法。VIP 签名 MD5 输入格式:"{expires}{uri} {secret}",
经 Base64URL 编码后拼入 URL 参数。Nginx secure_link_md5 指令在服务端重新计算并比对。
防护层次
- 前端认证:JWT Token,含用户 ID、角色、过期时间
- API 限流:每端点独立限速 (feed: 30/min, stream: 60/min, auth: 10/min)
- URL 签名:所有媒体 URL 带时效签名,过期返回 410 Gone
- CORS:Worker 和 Nginx 均配置
ALLOWED_ORIGINS 白名单
- VIP 配额:前端计时 + 服务端 30s 上报,用完降级回普通线路
- SSL:VIP 服务器使用 Let's Encrypt 证书 (certbot 自动续期)
- SSH:非标端口 14028,密码认证
6. 服务器规格
| 项目 |
VIP 服务器 |
Cloudflare 平台 |
| 位置 |
美国洛杉矶 (RAKsmart) |
全球边缘节点 |
| 网络 |
中国大陆优化独享带宽 |
Cloudflare CDN |
| CPU |
E5-2660v2 x2 (20C/40T) |
Serverless (自动伸缩) |
| 内存 |
64 GB DDR3 ECC |
128 MB / Worker |
| 存储 |
4.5 TB (LVM 双盘合并) |
R2: 无限 / D1: 10 GB / KV: 1 GB |
| 操作系统 |
Ubuntu 24.04 LTS |
- |
| 进程管理 |
PM2 (videoop --server) |
- |
7. DNS 配置
| 域名 |
类型 |
目标 |
CF 代理 |
用途 |
mhana.top |
CNAME |
Cloudflare Pages |
橙色云 (Proxied) |
前端页面 |
videoserver.mhana.top |
CNAME |
Cloudflare Workers |
橙色云 (Proxied) |
API 网关 |
vip.mhana.top |
A |
137.175.4.97 |
灰色云 (DNS Only) |
VIP 直连 |
关键:vip.mhana.top 必须保持灰色云 (DNS Only)。
如果开启橙色云,流量会经过 Cloudflare 代理,失去中国大陆优化带宽的直连优势。
8. 代码管理与部署
Git 仓库
| 项目 |
GitHub 仓库 |
本机分支 |
部署目标 |
| videoop |
sipangzi666/video-op |
master |
VIP 服务器 /opt/videoop/ |
| videoagt |
sipangzi666/video-agt |
feat/strategy-system |
Cloudflare Pages |
| videoworker |
sipangzi666/video-worker |
feat/strategy-system |
Cloudflare Workers |
开发 → 生产工作流
本机 (开发/测试) GitHub (私有仓库) VIP 服务器 (生产)
│ │ │
├── git commit │ │
├── git push ──────────────> │ │
│ │ <────── git pull ────────┤
│ │ ├── pm2 restart videoop
│ │ └── 生产环境已更新
│
├── wrangler deploy ──────────────────────> Cloudflare Workers (videoworker)
└── npx @cloudflare/next-on-pages ────────> Cloudflare Pages (videoagt)
videoop 部署步骤 (VIP 服务器)
# 1. 本机:提交并推送代码
cd /workspace/videoop
git add -A && git commit -m "feat: 你的改动描述"
git push
# 2. VIP 服务器:拉取并重启
ssh -p 14028 root@137.175.4.97
cd /opt/videoop
git pull origin master
pm2 restart videoop
# 3. 验证
pm2 logs videoop --lines 20 --nostream
注意事项
- 本地配置文件不入库:
.env、*.session、*.log、CLOUDFLARE_CREDENTIALS.md 均在 .gitignore 中,git pull 不会覆盖服务器上的这些文件
- wrangler.toml 含密钥:videoworker 的
wrangler.toml 包含 VIP_HMAC_SECRET 等密钥,GitHub 仓库中为占位值,本机保留真实值用于 wrangler deploy
- 依赖更新:如果修改了
pyproject.toml 新增依赖,pull 之后还需在服务器执行:.venv/bin/pip install <新包名>
- PM2 开机自启:已配置
pm2 startup + pm2 save,服务器重启后 videoop 自动恢复
9. 快速参考
关键路径
| 项目 | 路径 / URL |
| 前端代码 | /workspace/videoagt/ |
| Worker 代码 | /workspace/videoworker/ |
| Pipeline 代码 | /workspace/videoop/ |
| VIP 服务器 Pipeline | /opt/videoop/ |
| VIP 视频存储 | /data/videos/, /data/previews/, /data/thumbs/ |
| Nginx 配置 | /etc/nginx/sites-available/vip-video |
| PM2 配置 | /opt/videoop/ecosystem.config.js |
| SSL 证书 | /etc/letsencrypt/live/vip.mhana.top/ |
常用命令 (VIP 服务器)
# Pipeline 管理
pm2 status # 查看进程状态
pm2 logs videoop --lines 50 # 查看日志
pm2 restart videoop # 重启流水线
# Nginx 管理
nginx -t && systemctl reload nginx # 测试并重载配置
certbot renew --dry-run # 测试 SSL 续期
# 存储查看
du -sh /data/videos/ /data/previews/ /data/thumbs/ # 磁盘占用
df -h /data/ # 剩余空间
# rclone 增量同步 (如需)
rclone sync r2:video-storage/videos/ /data/videos/ --transfers=8 -P