Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IFNET Video Relay

安全解析并临时下载公开微博视频:无需微博账号或 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

打开 http://localhost:8080

检查服务:

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 build

pnpm 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 yesappendfsync 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.mddocs/agents/

About

安全解析并临时下载公开微博视频:逐跳校验、无需 Cookie、500 MB 上限、30 分钟自动清理。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages