用云盘搭一个不占带宽的影视库:STRM + 302 流媒体架构实战


一句话:把网盘上的影视文件,变成 Apple TV / Infuse 能直接串流的媒体库。服务器不落盘、不转码、不吃带宽,数据全部走云盘 CDN 直连。

为什么做这件事

网盘里存了上百 GB 的影视,问题来了:

  • 直接下载再播放 —— 占本地磁盘,下载慢,等不起。
  • Plex / Jellyfin 转码 —— 吃 CPU、吃服务器带宽,而且转码画质有损。
  • 挂载网盘(rclone / 挂载盘) —— 慢,不稳定,播放器兼容性差。

我想要的是一套零资源占用的方案:服务器不存数据、不转码、不吃带宽,播放器直接从云盘拉流。最终做出来的,就是这套 STRM + 302 流媒体架构。

架构总览

云盘 (139 / mcloud)
   │  API 拿 302 直链(指向 CDN)
   ▼
本地 STRM 库(每个影视 = 一个 .strm 文本文件)
   │
   ├── WebDAV (Infuse 直读)  ──►  Apple TV / Infuse
   └── 网页播放器 + API      ──►  浏览器 / VidHub

核心思想是服务器只指路,不搬数据:

  1. STRM 文件:每个影视对应一个 .strm 文本文件,内容是指向流地址的 URL。Infuse / VidHub 识别到 .strm 就按流地址去拉流,不落盘。
  2. 302 直链:服务器拿到云盘 CDN 的直链地址,直接返回 302 让播放器跳过去。数据从 CDN 到播放器,不过服务器——所以零带宽、零转码、零落盘。

听起来简单。真正做起来,坑全在云盘 CDN 的“怪癖”上。下面是我踩过并解决的真实问题。

核心难点 1:单连接限速,追不上播放

现象:30GB 的 REMUX 平均码率约 4.6 MB/s,而天翼 CDN 单连接只给约 4 MB/s——单连接根本追不上播放速度。

为什么 VLC 流畅、VidHub 卡死:VLC 会自己开多条连接并发拉流,所以流畅;VidHub 是单连接,就卡死。同一个库,换播放器结果完全不同。

解法:多连接并行中转。把文件按块切分,编号 i 的块固定由第 i % 4 条连接顺序拉取,对外按块号顺序输出(round-robin 消费各连接的队列,天然有序)。

实测结果:4 条并发合计 8.6 MB/s,跑满播放需求。8 条反而掉速,4 条是甜点。

两个细节调优:

  • 分块大小:2MB 太小,请求开销吃掉约 25% 带宽;改用 4MB 分块。
  • 内存背压:每条连接的队列有长度上限,反向背压。上限设为 4 连接 × 3 队列 × 4MB ≈ 48MB,内存可控。

核心难点 2:直链有“次数限制”

现象:云盘直链不是无限用的。实测:一条直链第 4 次 Range 请求必返回 403。

解法:设置 SAFE_PULLS = 3,一条直链拉满 3 个块就主动换链。配合“单条连接自己拉满几个块就换链”的后备机制,避免撞上 403。

这是云盘 CDN 设计上防滥用的机制,硬碰硬没用,理解它的限制再去匹配它。

核心难点 3:CDN 把 Content-Type 写错了

现象:天翼实测给 .mkv / .mp4 返回的是 application/x-www-form-urlencoded。播放器看到这个类型直接拒绝播放——表现为同一个库里有些片子能播、有些报格式错误,毫无规律。

解法:上游返回的 Content-Type 只在可信白名单(video/、audio/、image/)内沿用;否则按扩展名 / 文件头魔数重判。魔数嗅探兜底:ftyp → mp4,1A 45 DF A3 → mkv,RIFF....AVI → avi 等。

核心难点 4:CDN 有“坏 IP”

现象:同一个域名下挂着不同 IP,实测其中一对里一个 IP 有 40% 握手失败。而 httpx 自己不重试,单靠随机选中好 IP,就会让约 20% 的请求凭空失败。

解法:每次连接把成败结果回填给 DNS hook,下次优先选健康的 IP。连接层失败(ConnectError / SSL)换 IP 重试,最多 3 次。

踩坑记录(不写代码,写判断)

  • 网盘删片后 .strm 不会消失:网页播放器不显示,但 Infuse 会列出来,点进去报 502。要用工具实测判定:对 strm 地址发 Range: bytes=0-0 且不跟随跳转,30x 算存活,404/410/502 判失效。
  • 别用“file_id 不在注册表里”当删依据:实测过 22 个此类条目,只有 1 个真失效,其余 21 个仍可正常播放。判定只认实测。
  • 代理会把云盘 CDN 搞坏:所有请求一律 trust_env=False 直连,不走系统代理。
  • 139 云盘认证对代理节点敏感:统一认证服务(idaas.cmpassport.com)和网盘服务(*.139.com)对海外/代理节点敏感,代理分流必须设为直连。

这套方案的本质

服务器只指路,数据走 CDN。所以:

  • ✅ 零带宽(数据不经服务器)
  • ✅ 零转码(原始画质直出)
  • ✅ 零落盘(本地只有几 KB 的 .strm 文本文件)

而真正难的不是架构——架构一句话就讲完了。难的是和云盘 CDN 的怪癖斗争:限速、次数限制、错 Content-Type、坏 IP。这些是生产环境的真实脾气,只有踩过才知道。

启发:这类“看似简单、实则坑很多”的方案,价值不在架构图,而在你为适配真实环境踩过的每一个坑。这大概就是自托管最大的乐趣和最大的学费。