【android 视频播放那些事之缓存】
视频缓存解决问题:
1.回看时不再重新网络请求。
2.提前缓存,加速播放。
现有轮子:
AndroidVideoCache
git地址:
https://github.com/danikula/AndroidVideoCache
使用很简单参考git说明就可以。
AndroidVideoCache的用法 1.添加依赖 compile 'com.danikula:videocache:2.7.1' 2.在Application里面创建全局单例 HttpProxyCacheServer,代码如下 public class App extends Application { private HttpProxyCacheServer proxy; public static HttpProxyCacheServer getProxy(Context context) { App app = (App) context.getApplicationContext(); return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy; } private HttpProxyCacheServer newProxy() { return new HttpProxyCacheServer(this); } } 3.在给播放器设置url的时候通过生成代理url来实现视频的缓存,示例代码如下 private void startVideo() { //拿到全局的单例 HttpProxyCacheServer HttpProxyCacheServer proxy = App.getProxy(getActivity()); //注册下载缓存监听 proxy.registerCacheListener(this, url); //生成代理url String proxyUrl = proxy.getProxyUrl(url); //给播放器设置播放路径的时候设置为上一步生成的proxyUrl videoView.setVideoPath(proxyUrl); videoView.start(); } 以上就是AndroidVideoCache的使用,是不是特简单!当然它还可以设置缓存的大小,缓存路径、缓存文件的数量等,在初始化的时候设置即可,代码如下 private HttpProxyCacheServer newProxy() { return new HttpProxyCacheServer.Builder(this) .cacheDirectory(Utils.getVideoCacheDir(this))//缓存路径 .maxCacheFilesCount(100)//最大缓存文件数量 .maxCacheSize(500 * 1024 * 1024)//最大缓存大小 .build(); }
现实原理:
参这张图,非常清析。
由代码去请求远程数据。本地文件流返给videoView显示。
问题解决
包冲突问题加入以下代码
//包冲突解方法
implementation ('org.slf4j:slf4j-api:1.7.24',{
exclude group:'slf4j-api'
})
优化播放速度的思路
想要做到快速播放那必须提前缓存。方法是模拟videoView加载播放。预测哪个视频会在将来播放就先缓存起来,当播放时视频打开速将大幅提高。
package com.dueeeke.dkplayer.util.cache; import com.danikula.videocache.HttpProxyCacheServer; import com.dueeeke.videoplayer.util.L; import java.io.BufferedInputStream; import java.io.File; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.ExecutorService; public class PreloadTask implements Runnable { /** * 原始地址 */ public String mRawUrl; /** * 列表中的位置 */ public int mPosition; /** * VideoCache服务器 */ public HttpProxyCacheServer mCacheServer; /** * 是否被取消 */ private boolean mIsCanceled; /** * 是否正在预加载 */ private boolean mIsExecuted; @Override public void run() { if (!mIsCanceled) { start(); } mIsExecuted = false; mIsCanceled = false; } /** * 开始预加载 */ private void start() { L.i("开始预加载:" + mPosition); HttpURLConnection connection = null; try { //获取HttpProxyCacheServer的代理地址 String proxyUrl = mCacheServer.getProxyUrl(mRawUrl); URL url = new URL(proxyUrl); connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5_000); connection.setReadTimeout(5_000); InputStream in = new BufferedInputStream(connection.getInputStream()); int length; int read = -1; byte[] bytes = new byte[8 * 1024]; while ((length = in.read(bytes)) != -1) { read += length; //预加载完成或者取消预加载 if (mIsCanceled || read >= PreloadManager.PRELOAD_LENGTH) { L.i("结束预加载:" + mPosition); break; } } if (read == -1) { //这种情况一般是预加载出错了,删掉缓存 L.i("预加载失败:" + mPosition); File cacheFile = mCacheServer.getCacheFile(mRawUrl); if (cacheFile.exists()) { cacheFile.delete(); } } } catch (Exception e) { L.i("异常结束预加载:" + mPosition); } finally { if (connection != null) { connection.disconnect(); } } } /** * 将预加载任务提交到线程池,准备执行 */ public void executeOn(ExecutorService executorService) { if (mIsExecuted) return; mIsExecuted = true; executorService.submit(this); } /** * 取消预加载任务 */ public void cancel() { if (mIsExecuted) { mIsCanceled = true; } } }
其它问题:
分类:
android
标签:
android 视频播放
, slf4j-api
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)