- 01.前沿场景介绍一下
- 02.致敬优秀开源项目
- 03.边播边缓存原理
- 04.如何实现预加载
- 06.缓存满了怎么处理
- 14.视频缓冲后拖动问题
- 一些知名的视频app客户端(优酷,爱奇艺)播放视频的时候都有一些缓存进度(二级进度缓存),微信有关的小视频,还有一些短视频app,都有边播边缓的处理。
- 还有就是当文件缓存完毕了再次播放的话就不再请求网络了直接播放本地文件了。既节省了流程又提高了加载速度。
- 网络上比较好的项目:https://github.com/danikula/AndroidVideoCache
- 网络用的HttpURLConnection,文件缓存处理,文件最大限度策略,回调监听处理,断点续传,代理服务等。
- 但是存在一些问题,比如如下所示
- 文件的缓存超过限制后没有按照lru算法删除,
- 处理返回给播放器的http响应头消息,响应头消息的获取处理改为head请求(需服务器支持)
- 替换网络库为okHttp(因为大部分的项目都是以okHttp为网络请求库的),但是这个改动性比较大
- 然后看一下怎么使用,超级简单。传入视频url链接,返回一个代理链接,然后就可以呢
HttpProxyCacheServer cacheServer = ProxyVideoCacheManager.getProxy(this); String proxyUrl = cacheServer.getProxyUrl(URL_AD); mVideoPlayer.setUrl(proxyUrl); public static HttpProxyCacheServer getProxy(Context context) { return sharedProxy == null ? (sharedProxy = newProxy(context)) : sharedProxy; } private static HttpProxyCacheServer newProxy(Context context) { return new HttpProxyCacheServer.Builder(context) .maxCacheSize(512 * 1024 * 1024) // 512MB for cache //缓存路径,不设置默认在sd_card/Android/data/[app_package_name]/cache中 //.cacheDirectory() .build(); }
- 大概的原理
- 原始的方式是直接塞播放地址给播放器,它就可以直接播放。现在我们要在中间加一层本地代理,播放器播放的时候(获取数据)是通过我们的本地代理的地址来播放的,这样我们就可以很好的在中间层(本地代理层)做一些处理,比如:文件缓存,预缓存(秒开处理),监控等。
- 原理详细一点来说
- 1.采用了本地代理服务的方式,通过原始url给播放器返回一个本地代理的一个url ,代理URL类似:http://127.0.0.1:port/视频url;(port端口为系统随机分配的有效端口,真实url是为了真正的下载),然后播放器播放的时候请求到了你本地的代理上了。
- 2.本地代理采用ServerSocket监听127.0.0.1的有效端口,这个时候手机就是一个服务器了,客户端就是socket,也就是播放器。
- 3.读取客户端就是socket来读取数据(http协议请求)解析http协议。
- 4.根据url检查视频文件是否存在,读取文件数据给播放器,也就是往socket里写入数据(socket通信)。同时如果没有下载完成会进行断点下载,当然弱网的话数据需要生产消费同步处理。
- 其实预加载的思路很简单,在进行一个播放视频后,再返回接下来需要预加载的视频url,启用线程去请求下载数据
- 开启一个线程去请求并预加载一部分的数据,可能需要预加载的数据大于>1,利用队列先进入的先进行加载,因此可以采用LinkedHashMap保存正在预加载的task。
- 在开始预加载的时候,判断该播放地址是否已经预加载,如果不是那么创建一个线程task,并且把它放到map集合中。然后执行预加载逻辑,也就是执行HttpURLConnection请求
- 提供取消对应url加载的任务,因为有可能该url不需要再进行预加载了,比如参考抖音,当用户瞬间下滑几个视频,那么很多视频就需要跳过了不需要再进行预加载
- 问题描述
- 在播放视频的时候,你看到缓冲buffer缓冲到了5分钟,但这个时候你把网络一关闭。然后拖动到3分钟,发现缓冲的视频有时候无法播放,这个是为什么呢?