自托管的影视发现站 + 磁力检索。TMDB 榜单聚合、豆瓣/烂番茄评分、DHT 全网磁力搜索, 外加一个管控 DHT 爬虫的 Web 控制台。
依赖 bitmagnet(MIT)做 DHT 抓取与内容分类。 本仓库提供的是站点、爬虫管控与整套部署编排,不是 DHT 协议的重新实现。
- 发现:TMDB 热门/高分/趋势/正在上映等榜单,按电影、剧集、年份、类型筛选,支持收藏与打分
- 豆瓣 Top250:整榜 250 条按名次单独一页平铺;库内没有的(多为早于收录下限的老片, TMDB 榜单窗口之外)按片名单独搜 TMDB 补录进库,与列表同步进来的条目结构一致
- 搜索补录:搜不到时按片名顺带搜一遍 TMDB——归一化同名就直接补录进库,否则列出候选由你点选。 收录年份下限之外的片子各榜单查询取不到,这里是它们唯一的入库通道;补录的条目会自动回捞, 不会被 180 天过期清理删掉
- 评分:TMDB 之外补齐豆瓣与烂番茄(批量抓 + 详情页实时抓,带缓存与节流)
- 磁力:对每个条目实时检索 DHT 索引,按做种数、分辨率、中文字幕、季集整理,标注同名噪声
- 在线播放:磁力行上的「播放」直接开播——BT 边下边播,不等完整下载。浏览器能直接播的原文件直出, HEVC、10bit、AC3/DTS 等自动走 HLS 边转边播;转码用核显硬编(VAAPI),无核显自动退到 CPU 软转
- 演职员:详情页列出导演、编剧与主要演员,点任一人进入其作品页(按参演 / 导演 / 编剧分栏,
只列库内已收录的片)。电影收完整演员表;剧集用 TMDB 的
aggregate_credits并只收演过 5 集以上的角色, 滤掉一次性客串 - 爬虫控制台:网页上切换爬虫启停模式、抓取档位、运行时段,实时看运行状态、网速与种子总量/昨日新增
浏览页——语言 / 类型 / 年代 / 评分 / 排序多维筛选,卡片右上角的 🧲 是磁力命中数:
详情页——TMDB 之外补齐豆瓣与烂番茄;下半部分是实时检索到的磁力, 可按季与分辨率筛选,已剔除同名噪声后按匹配度与做种数排序:
三个核心组件(另有播放 sidecar 容器 stream,见快速开始 2),其中两个靠 文件协议 解耦——
这是刻意的设计,让站点容器不需要任何 Docker 权限,也不新增对外监听端口:
┌──────────────┐ ┌────────────────┐ ┌──────────────────┐
│ web │ │ crawler-agent │ │ bitmagnet │
│ (容器) │ │ (宿主机进程) │ │ (容器) │
├──────────────┤ ├────────────────┤ ├──────────────────┤
│ 站点 UI/API │ │ 每 2s 一轮收敛 │ │ DHT 爬虫 │
│ 榜单同步 │───────▶│ 改 config.yml │───────▶│ 内容分类 │
│ 磁力检索 │ 写期望 │ 启停容器 │ docker │ GraphQL API │
│ │◀───────│ 回写实际状态 │ │ PostgreSQL │
└──────────────┘ 读状态 └────────────────┘ └──────────────────┘
│ ▲
│ GraphQL 查询磁力 │
└──────────────────────────────────────────────────┘
data/crawler.json— 站点写、agent 读:用户在控制台表达的期望状态data/crawler-state.json— agent 写、站点读:爬虫的实际状态
agent 是收敛式而非触发器:每 2 秒把实际状态拉回期望状态。因此宿主重启、容器崩溃、
有人手动 docker compose up -d,都会在 2 秒内被自动纠正。
前置:Docker 与 Docker Compose、Node.js ≥ 20(仅 agent 需要,站点跑在容器里自带)、
一个 TMDB 凭据。
构建站点镜像时会执行 npm ci,需能访问 npm registry(国内通常要给 Docker daemon 配代理,
写进 /etc/systemd/system/docker.service.d/*.conf 后 systemctl daemon-reload && systemctl restart docker)。
git clone https://github.com/wxwxOk/mediasite /opt/mediasite
cd /opt/mediasitecd crawler
cp .env.example .env # 填入 TMDB_API_KEY
docker compose up -d bitmagnet-core postgres
docker compose create bitmagnet-crawler # 只创建、不启动bitmagnet-crawler 刻意不在这里启动——它由 agent 按控制台设定启停;
但容器必须先被创建出来,因为 agent 用的是 docker start/stop 而非 up。
爬虫监听 3333(GraphQL/Web UI),PostgreSQL 只绑 127.0.0.1:5432。
cd ../web
mkdir -p ../data # 必须先建:Docker 自动创建会属 root:root,容器内以 node 写不进去
cp .env.example .env
# 必填 TMDB_TOKEN;对外暴露时还要设 SITE_PASSWORD
# 需要代理才能访问 TMDB 时,把 .env 里 HTTP_PROXY / HTTPS_PROXY 两行取消注释
docker compose up -d --build该命令同时拉起播放 sidecar(stream 服务,首次拉镜像约 4.6GB)。播放走 BT 网络,
路由器/防火墙放行 6881(TCP+UDP)连通性更好;无核显的机器删掉 compose 里 stream 的
devices 两行(转码退到 CPU)。
首次启动会拉 TMDB 榜单(数千条,需几分钟),页面在 http://localhost:8899。
若日志只反复出现 sync failed, retrying in 5min,即是没配代理。
需要能免密执行 docker(sudo usermod -aG docker $USER 后重新登录)——
不要把密码写进脚本。
mkdir -p ~/.config/systemd/user
cp crawler/agent/crawler-agent.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now crawler-agent
loginctl enable-linger $USER # 未登录时也持续运行部署路径不是 /opt/mediasite 时,改 unit 里的 MEDIASITE_DATA_DIR 与 BITMAGNET_CONFIG。
控制台在站点的「DHT 爬虫」页。
├── data/ # 运行期共享目录(不提交):SQLite、封面缓存、控制状态文件
├── web/ # 站点:Fastify + node:sqlite
│ ├── src/
│ │ ├── playback.js # 播放 sidecar 客户端与流决策(直出 / HLS 转码)
│ │ ├── scraper.js # 榜单同步排期(热榜追新 + 轮转补旧)
│ │ ├── ratings.js # 豆瓣 / 烂番茄抓取
│ │ ├── titles.js # 单条 TMDB 条目的取回与落库(各补录路径共用)
│ │ ├── ondemand.js # 搜索兜底补录:TMDB 搜索、候选判重、回捞
│ │ ├── douban250.js # 豆瓣 Top250 榜单快照、片名解析与榜内缺片补录
│ │ ├── providers/ # 磁力来源:bitmagnet、Prowlarr,及相关性/季集/字幕解析
│ │ └── crawler.js # 控制协议的数据层(读写上面两个 JSON)
│ ├── sidecar/converter.py # 转码补丁(软解 + 核显硬编;HEVC 直拷强制 hvc1 tag;转码流 VOD 预声明)
│ ├── sidecar/fingerprint.py # 决策补丁(copy 分支带出源编码,供上者条件判断)
│ └── docker-compose.yml
└── crawler/ # DHT 爬虫栈
├── docker-compose.yml # bitmagnet core / crawler / postgres
├── config/config.yml # bitmagnet 配置(scaling_factor 由 agent 接管)
├── agent/ # 控制 agent + systemd unit
└── tools/ # 健康检查、种子导入
两处 .env(均已在 .gitignore 中):web/.env.example 与 crawler/.env.example
列了全部变量与说明。常改的几个:
| 变量 | 位置 | 说明 |
|---|---|---|
TMDB_TOKEN / TMDB_KEY |
web | TMDB 凭据,二选一 |
SITE_PASSWORD |
web | 访问口令;留空即不鉴权,此时务必保持 BIND_ADDR=127.0.0.1 |
SITE_SECRET |
web | 会话签名密钥,openssl rand -hex 32 生成 |
BIND_ADDR |
web | 0.0.0.0 才对外,前提是已设 SITE_PASSWORD |
HTTP_PROXY / HTTPS_PROXY |
web | 访问 TMDB / 豆瓣走代理;国内网络不填则同步一直失败(日志刷 sync failed) |
DOUBAN250_REFRESH_DAYS |
web | 豆瓣 Top250 快照与榜内补录的刷新周期(天),默认 7 |
TMDB_API_KEY |
crawler | bitmagnet 富化用 |
MEDIASITE_DATA_DIR |
agent | 站点 data/ 的绝对路径 |
NET_IFACE |
agent | 网速采样的网卡,默认自动取默认路由那块 |
本项目是索引、检索与播放工具:它不托管、不存储、不分发任何受版权保护的内容, 只查询公开的 DHT 网络与用户自行配置的索引源。在线播放经 BitTorrent 网络实时流式传输 (边下边播),内容来自网络中的其他节点,本地仅保留供播放的临时缓存并会被自动清理; 播放何种内容完全取决于你自己。
抓取 DHT 与使用磁力链接的合法性因司法辖区而异。请在部署前确认你所在地的法律, 并自行承担使用后果。请勿将其用于侵权用途。
MIT。bitmagnet 由 bitmagnet-io 以 MIT 许可发布, 本项目通过官方镜像调用它。
本开源项目已链接并认可 LINUX DO 社区。

