gsy-cache-and-download
概念
- 缓存(cache):
ProxyCacheManager内部起本地 HTTP 代理,拦截player的请求,把响应流一边喂给 player 一边写到本地;文件名是 URL MD5。 - 下载(download):与缓存共享目录,但一定要走"从头到尾"完整播完才能保证文件可复用为独立 mp4;提前 seek 会造成 range 分片,回放时代理会重新下载缺失段。
开启缓存
方式 1:setUp(url, true, title) 第二参数 cacheWithPlay=true。
方式 2:GSYVideoOptionBuilder:
setCacheWithPlay(true)setCachePath(File)(可选)
自定义缓存目录
File dir = new File(getExternalFilesDir(null), "videoCache");
builder.setCachePath(dir);
若使用不同 CacheManager(例如 Exo),传给 CacheFactory.setCacheManager(...) 前记得也走 setCachePath 或自定义 ICacheManager 实现。
ICacheManager API
见 ICacheManager。核心方法:
| 方法 | 说明 |
|---|---|
doCacheLogic(Context, IMediaPlayer, String url, Map<String,String> headers, File cachePath) |
播放前介入,把 url 换为代理 url |
clearCache(Context, File cachePath, String url) |
单条清除;url = null 清空整目录 |
hadCached() |
当前播放是否已"命中"缓存(100% 完成) |
setCacheAvailableListener(CacheAvailableListener) |
缓存进度回调 |
release() |
释放代理 |
ProxyCacheManager 关键静态方法
在 ProxyCacheManager 里:
clearAllCache(Context, File)—— 清空整个缓存目录。- 内部
HttpProxyCacheServer单例 lazy 初始化,第一次doCacheLogic时才起服务;Application 就绪即可。
ProxyCacheUserAgentHeadersInjector
自定义 UA / Cookie / Referer 注入到代理层:见 ProxyCacheUserAgentHeadersInjector。挂到 HttpProxyCacheServer.Builder.headerInjector() 上,或直接用 Map 传给 setUp。
离线下载
三步流程:
- 用
HttpProxyCacheServer单独跑一次预下载(不 attach 到 Player),或直接开一条播放并setStartAfterPrepared(false)静默走全长; - 事件
VideoAllCallBack#onAutoComplete触发 → 缓存文件已完整; - 用 FileUtils 拷贝 / 重命名到业务目录。
Demo:DetailDownloadPlayer(IJK)与 DetailDownloadExoPlayer(Exo)。
不缓存的场景
以下情况 cacheWithPlay 应设 false:
- 直播 / RTMP / RTSP(连续无尽流);
- HLS m3u8(代理逻辑对分片不友好,建议 Exo 内核 + Exo cache);
- DASH / SmoothStreaming;
- DRM 或私有加密。
常见坑
- 代理端口被占:
HttpProxyCacheServer首次启动失败会 fallback 到原始 url,缓存不生效。多进程时可能出现,建议仅主进程用。 - 缓存目录跨用户:
context.cacheDir是 per-user;用外部存储需要动态权限。 - 同 URL 缓存名冲突:MD5(url) 相同即命中;如果 URL 带一次性签名,每次不同 → 缓存穿透。可以先规范化 URL 再传给
setUp。 - HTTP header 变更失效:headers 参与代理请求生成,但缓存文件名只按 URL;同一 URL 换 UA 不会重新下载。