安全解析并临时下载公开微博视频:无需微博账号或 Cookie,逐跳校验链接,自动选择 500 MB 内最高可用画质,生成文件在 30 分钟后自动清理。
公开微博视频下载服务的 TypeScript 单仓。当前代码包含 Task 11 的生产部署能力:在安全微博链接解析、受保护 MP4、资源限制、磁盘降级、Redis 持久化、异常恢复和脱敏结构化日志之上,提供生产 Compose、HTTPS 自动续期、资源边界、稳定持久卷、GitHub CI 与部署运维脚本。
当前页面可以解析公开微博视频,展示标题、封面、时长、最高可用画质、预计大小和剩余解析额度;确认后可创建任务、轮询排队/下载/合并状态,并在完成后下载 MP4。
- Node.js 22+
- pnpm 10.15+
- Docker Desktop 或 Docker Engine + Compose
复制可选环境变量:
cp .env.example .env构建并启动全部服务:
pnpm dev检查服务:
curl http://localhost:8080/api/health/live
curl http://localhost:8080/api/health/ready
docker compose ps停止服务:
pnpm dev:down安装依赖:
pnpm install运行完整检查:
pnpm check也可以单独运行:
pnpm format:check
pnpm typecheck
pnpm test
pnpm test:acceptance
pnpm buildpnpm check 包含 pnpm test:acceptance,因此完整检查需要 Docker 正在运行。验收测试会创建隔离的临时 Redis 容器和真实 Worker 进程,测试结束后自动清理。
edge是唯一映射宿主机端口的容器,提供页面、API 代理和 Nginx 内部 MP4 文件传输。api提供/api/health/live和/api/health/ready。存活检查只反映 API 进程;就绪检查分别报告 Redis、Worker、下载目录和磁盘准入状态。主机磁盘达到 80% 或下载目录容量不足时拒绝新下载任务,但继续提供解析和已有文件下载能力。api通过POST /api/previews接收标准微博视频 URL 或t.cn短链接,逐跳完成域名、DNS 和连接目标校验后返回预览。worker写入 Redis 心跳,并以 BullMQ 全局单并发调用yt-dlp下载、调用ffmpeg -c copy无损复用为 MP4。单任务最多运行 15 分钟;未知大小的任务实际输出达到 500 MB 时终止整个进程组,并清理所有不完整产物。主机磁盘达到 90% 时暂停领取新任务,恢复后自动继续。redis通过appendonly yes、appendfsync everysec和持久卷保存 BullMQ 队列、任务授权、额度、生成/存储预留、复用引用、过期状态和 Worker 心跳,不映射公网端口。storage-init只负责把共享下载卷交给非 root 的 Node.js 用户,完成后退出。downloads是 API、Worker 和 Nginx 共享的 Docker 卷;Nginx 以只读方式挂载。
主要测试边界是 Fastify HTTP API。ExternalServices 统一封装时钟、DNS 和逐跳请求,测试可以逐项替换。createHttpHarness 动态启动隔离 Redis、真实 BullMQ Worker 和独立临时下载目录,通过假 yt-dlp/ffmpeg 完成确定性的端到端 MP4 任务,并统一负责清理。快速回归测试另行覆盖 Redis 故障、Worker 心跳过期和下载目录不可用。
预览接口只允许明确列出的微博域名,不接受用户信息、自定义端口或直接 IP;每个重定向目标都会重新解析并拒绝非公网地址,实际 HTTP 连接固定到该次已批准的 DNS 结果。预览凭证使用 PREVIEW_TOKEN_SECRET 加密认证,默认五分钟有效;访客用量主体使用独立且稳定的 VISITOR_SUBJECT_SECRET 派生。生产环境必须分别生成两个密钥。
每个来源 IP 每分钟最多解析 10 次、每个北京时间自然日最多 20 次,无效请求同样计数;下载任务默认每分钟和每天各 5 次。可通过 PRIVILEGED_IPS 为逗号分隔的精确 IPv4/IPv6 地址配置独立的解析与下载额度;未命中的来源仍使用默认额度,全局队列、每日字节和磁盘限制不会被绕过。全局最多同时执行两个真实解析,单次解析 20 秒超时。成功结果按规范化输入 URL 缓存五分钟,缓存命中仍消耗访客额度,但不重复访问微博。Nginx 会覆盖客户端传入的转发地址,API 只信任紧邻的一层反向代理,以免伪造来源绕过限额。
创建任务只接受服务端加密认证的五分钟预览凭证,客户端不能覆盖格式、标题或媒体地址。任务 Token 绑定创建 IP,并只通过对应任务路径下的 HttpOnly Cookie 保存;浏览器本地任务记录和下载 URL 都不携带 Token。API 授权后只返回 X-Accel-Redirect,MP4 正文和 Range 续传由 Nginx 的 internal 位置处理。
API 启动时会对账 BullMQ、下载账本、存储预留和文件目录,释放缺失任务留下的锁与预留并清理无引用文件。Worker 使用 BullMQ 锁保持全局单并发;异常退出后,下一次恢复会先终止登记的遗留媒体进程、删除不完整目录,再在剩余停滞恢复预算内继续任务。任务创建、状态变化、限流、重试、取消、清理和恢复均输出 JSON 行事件;日志字段会移除完整 IP、Token、URL 查询参数、内部路径和外部进程输出。
- 规格:
.scratch/weibo-video-downloader/spec.md - Task:
.scratch/weibo-video-downloader/issues/ - 技术方案:
docs/technical-solution.md - 生产部署:
docs/production-deployment.md - GitHub Actions:
.github/workflows/ci.yml构建并签名不可变 GHCR 镜像,.github/workflows/promote-production.yml经生产审批发布签名部署意图;服务器通过 systemd 主动 拉取、验签、部署和回滚,详见 签名镜像主动拉取部署 - Agent 约定:
AGENTS.md与docs/agents/