蘑菇影视官网更新后离线播放从不稳定到很稳:我只做了两步

更新后很多用户反映离线播放经常卡顿、无法跳转或加载失败。我把问题压缩成两个关键方向做了改造——不到一天,离线播放从“时好时坏”变成了“稳如磐石”。下面把我做的两步按可复制的方式讲清楚,适合直接应用到你的网站上。
第一步:在前端用 Service Worker 做“智能缓存 + 分段响应”
- 为什么要做:更新后资源加载路径和缓存策略混乱,导致播放器无法正确读取已缓存的视频或在离线时无法响应跳转请求。直接把视频全部缓存到 Cache Storage 并不能满足播放跳转(seek)需求。
- 实现要点:
- 拦截媒体请求:在 Service Worker 的 fetch 事件里优先响应已缓存的媒体资源。如果缓存完整文件,直接返回;如果缓存的是 ArrayBuffer,可以按 Range 头切片返回。
- 支持 Range 请求:当播放器发送 Range 请求(用于跳转或续播)时,从缓存的二进制数据里切出对应区间,返回 206 Partial Content,并带上合适的 Content-Range、Accept-Ranges、Content-Length 等头。这一步能让视频在离线环境下也能像在线一样支持跳转。
- 缓存策略:对视频采用“先缓存元数据/片段,再后台补全”的思路。关键片段或起始片段优先下载(保证秒开),后台继续下载剩余部分并写入 IndexedDB/Cache Storage,避免一次性占满存储或造成长时间阻塞。
- 容错与更新:对比版本号或 ETag,发现新版就清理旧缓存并平滑切换,避免更新后缓存混乱。
第二步:服务端与媒体文件优化,保证播放器“拿到的东西”就是可流式播放的
- 为什么要做:即便前端做得再好,如果服务器不支持字节范围或 MP4 文件结构不对,离线播放与跳转仍会失败。
- 实现要点:
- 打开字节范围支持:在服务器响应里添加 Accept-Ranges: bytes,同时保证对 Range 请求返回 206 并带 Content-Range。很多 CDN/服务器默认支持,但更新后配置可能被覆盖,务必检查。
- 把 MP4 的 moov atom 放到文件开头(faststart):这能让播放器在文件未完全下载前就能解码播放与跳转。使用 ffmpeg 或 qt-faststart 处理:ffmpeg -i in.mp4 -movflags faststart -c copy out.mp4。这个改动对离线首开和 seek 稳定性提升巨大。
- 设置正确的缓存与 CORS 头:Cache-Control、ETag、Access-Control-Allow-Origin(如果跨域),能配合 Service Worker 做平滑更新和跨域播放。
- 分段/切片策略(可选):对长视频采用分段(如 HLS/DASH)能进一步提升离线访问灵活性,但对已有 mp4 项目,faststart + Range 支持通常已足够可靠。
快速检查表(部署前后用)
- 在线打开视频能否秒开并能自由跳转?(有无 206 响应)
- 离线模式(断网)下能否打开已缓存视频并跳转?
- 更新后旧缓存是否能平滑过渡或被安全清理?
- 移动端和桌面端都测试一遍(不同浏览器对 Range/Service Worker 支持差异较大)
