Reflection King:给 VRChat 播放器喂视频的抓取转码后端
Reflection King 是给 VRChat 播放器喂视频的后端。那个播放器挑食,只肯吃能直接 GET 到的老实媒体地址,遇到要登录、要跑 JS 解析、或者编码不认的源就摆烂。这东西的活儿就是:丢一个页面 URL 进去,它帮你解析、转码,落地成服务器上的 raw 地址,播放器那头直接拿去播,省掉每次手动 yt-dlp 再传图床。
后端 Axum,前面配个 React 控制台看任务状态。核心是一条持久化任务队列,存在 SQLite 里,进程重启任务不丢。URL 进来先做资源发现,内部串了 yt-dlp、you-get、streamlink,能抠流地址就抠;抠不出来的复杂站点交给 Playwright sidecar,真开个浏览器嗅探。发现阶段往往不止一个候选,所以每个候选打分,明显要跪的先拦掉——地区限制、DRM、夹广告都打风险标记,免得转码跑一半才发现是死路。选定候选就 ffmpeg 上场,该转码转码,能 remux 就 remux,最后统一给 MP4 加 faststart,边下边播不用等整个文件。产物挂在 /media/{id}/{file} 这个 raw URL 上,支持 HTTP Range,拖进度条不卡。
踩了三个点。一是安全:它本质就是你给 URL 它就去请求,典型 SSRF 温床,私网地址、内网段必须请求前拦死,不然公网部署等于内网门户大开;管理接口强制带密钥,sidecar 的 CDP/VNC/调试端口一个都不能露。二是登录态:有些源不登录根本看不到,所以加了服务器端浏览器 Profile/Cookie 导入,让 sidecar 带会话去探测,这块最敏感,.env、Cookie JSON、浏览器 Profile、SQLite 库绝对不进 Git。三是站点适配:通用解析器覆盖不全,Bilibili、Hanime1 还有一批 MacCMS 资源站得单独写适配,最费时间也最没成就感,站点一改版适配就得跟着改。
部署公网 VPS 一行脚本:
curl -fsSL https://raw.githubusercontent.com/dwgx/Reflection_King/master/install.sh | sudo bash
不想本地编译 Rust + Playwright 就拉 GHCR 预构建镜像,docker compose 跑更快。记牢 RK_PUBLIC_BASE_URL 必须填外部客户端真能访问到的地址,否则 /media/... 只在本机有效,VRChat 那头拿到也播不了。更细的写在仓库 docs/DEPLOYMENT.md 和 docs/SECURITY.md 里。
工程拆成几个 crate:reflection-core 放配置、模型、任务存储、URL 安全和下载转码;reflection-api 是 HTTP API 加队列调度;浏览器探测单独做成 reflection-browser sidecar;控制台是独立 React app。还留了个 reflection-worker 的壳,给以后 worker 拆出去独立跑用,目前没到那一步。