【Android 进阶】仿抖音系列之列表播放视频(三)

简介: 在上一篇【Android 进阶】仿抖音系列之列表播放视频(二)中,我们实现列表播放视频,这一篇我们来对其做些优化。当我们滑动列表播放视频时,如果你设置了状态栏显示网速的话,可以看到网速占用比较大,我们需要实现边播边缓存,下次播放时,就可以从缓存中取,减少网络使用。

在上一篇【Android 进阶】仿抖音系列之列表播放视频(二)中,我们实现列表播放视频,这一篇我们来对其做些优化。

当我们滑动列表播放视频时,如果你设置了状态栏显示网速的话,可以看到网速占用比较大,我们需要实现边播边缓存,下次播放时,就可以从缓存中取,减少网络使用。

Github上已经有现成的缓存库,我们只要集成进来就好,这是链接 AndroidVideoCache

1、创建MyApp 继承 Application,并在AndroidManifest.xml 中注册

2、在MyApplication 中添加代码,可以设置缓存路径、缓存大小等,这里用默认路径,配置缓存大小为1G。



    private HttpProxyCacheServer proxy;

    public static HttpProxyCacheServer getProxy(Context context) {
        MyApp app = (MyApp) context.getApplicationContext();
        return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
    }

    private HttpProxyCacheServer newProxy() {
        return new HttpProxyCacheServer.Builder(this)
                .maxCacheSize(1024 * 1024 * 1024)       // 1 Gb for cache
                .build();
    }

3、在MyVideoPlayer中,重写setUp 方法,添加代码

  @Override
    public void setUp(String url, int screen, Object... objects) {
        HttpProxyCacheServer proxy = MyApp.getProxy(context);
        String proxyUrl = proxy.getProxyUrl(url);
        super.setUp(proxyUrl, screen, objects);
    }

就在我们以为万事大吉的时候,却发现并没有什么卵用,而且有时播放第二遍的时候还会卡死,这是什么鬼???

于是我们查看了app的缓存目录,发现同一个视频,会缓存多次,所以我们猜想,是不是缓存这里出了问题?

通过查看AndroidVideoCache的源码,我们发现AndroidVideoCache是通过代理的策略实现一个中间层将我们的网络请求转移到本地实现的代理服务器上,这样我们真正请求的数据就会被代理拿到,这样代理一边向本地写入数据,一边根据我们需要的数据看是读网络数据还是读本地缓存数据再提供给我们,真正做到了数据的复用。

img_d026c1a05c7b5e2512e75739b7249d40.png
image.png

更详细的可以查看这篇博客这是链接

我们打断点,查看下AndroidVideoCache返回的url

img_cfacc4984658ff328ddae593d5e08915.png
image.png

可以看到同一个视频,2次返回的url 是不一样的,再翻下AndroidVideoCache的源码,我们看到

  public Builder(Context context) {
            this.sourceInfoStorage = SourceInfoStorageFactory.newSourceInfoStorage(context);
            this.cacheRoot = StorageUtils.getIndividualCacheDirectory(context);
            this.diskUsage = new TotalSizeLruDiskUsage(DEFAULT_MAX_SIZE);
            this.fileNameGenerator = new Md5FileNameGenerator();
            this.headerInjector = new EmptyHeadersInjector();
        }

我们再查看Md5FileNameGenerator的源码

public class Md5FileNameGenerator implements FileNameGenerator {

    private static final int MAX_EXTENSION_LENGTH = 4;

    @Override
    public String generate(String url) {
        String extension = getExtension(url);
        String name = ProxyCacheUtils.computeMD5(url);
        return TextUtils.isEmpty(extension) ? name : name + "." + extension;
    }

    private String getExtension(String url) {
        int dotIndex = url.lastIndexOf('.');
        int slashIndex = url.lastIndexOf('/');
        return dotIndex != -1 && dotIndex > slashIndex && dotIndex + 2 + MAX_EXTENSION_LENGTH > url.length() ?
                url.substring(dotIndex + 1, url.length()) : "";
    }
}

这里我们可以看到,缓存的文件是上面url 进行md5之后的字符串,再加上原来的文件后缀名,这也是为什么缓存目录下同一个视频,会缓存多次的问题。

知道问题出在哪,就好解决了,我们可以对AndroidVideoCache 返回的路径进行截取,只取我们原先的路径,当做缓存的文件名就可以了

public class MyFileNameGenerator implements FileNameGenerator {
    private static final int MAX_EXTENSION_LENGTH = 4;

    @Override
    public String generate(String url) {
        String extension = getExtension(url);
        int dotIndex = url.lastIndexOf('.');

        if (url.length() > 18 && dotIndex > 18) {
            return url.substring(dotIndex - 18);
        }
        String name = ProxyCacheUtils.computeMD5(url);
        return TextUtils.isEmpty(extension) ? name : name + "." + extension;
    }

    private String getExtension(String url) {
        int dotIndex = url.lastIndexOf('.');
        int slashIndex = url.lastIndexOf('/');
        return dotIndex != -1 && dotIndex > slashIndex && dotIndex + 2 + MAX_EXTENSION_LENGTH > url.length() ?
                url.substring(dotIndex + 1, url.length()) : "";
    }
}

修改MyApp 中的代码如下

   private HttpProxyCacheServer proxy;

    public static HttpProxyCacheServer getProxy(Context context) {
        MyApp app = (MyApp) context.getApplicationContext();
        return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
    }

    private HttpProxyCacheServer newProxy() {
        return new HttpProxyCacheServer.Builder(this)
                .maxCacheSize(1024 * 1024 * 1024)       // 1 Gb for cache
                .fileNameGenerator(new MyFileNameGenerator())
                .build();
    }

到这里,本篇文章也结束了

最后,献上完整代码。Github

目录
相关文章
|
4月前
|
XML Java Android开发
Android Studio App开发中改造已有的控件实战(包括自定义支付宝月份选择器、给翻页栏添加新属性、不滚动的列表视图 附源码)
Android Studio App开发中改造已有的控件实战(包括自定义支付宝月份选择器、给翻页栏添加新属性、不滚动的列表视图 附源码)
41 1
|
4月前
|
XML Java Android开发
Android Studio App开发之捕获屏幕的变更事件实战(包括竖屏与横屏切换,回到桌面与切换到任务列表)
Android Studio App开发之捕获屏幕的变更事件实战(包括竖屏与横屏切换,回到桌面与切换到任务列表)
39 0
|
4月前
|
XML Java Android开发
Android Studio App入门之列表视图ListView的讲解及实战(附源码 超详细必看)
Android Studio App入门之列表视图ListView的讲解及实战(附源码 超详细必看)
86 0
|
4月前
|
XML Java Android开发
Android Studio App开发之列表类视图中基本适配器BaseAdapter的使用及实战(附源码 超详细)
Android Studio App开发之列表类视图中基本适配器BaseAdapter的使用及实战(附源码 超详细)
47 0
|
4月前
|
编解码 监控 定位技术
抖音技术分享:抖音Android端手机功耗问题的全面分析和详细优化实践
本文结合抖音的功耗优化实践中产出了一些实验结论,优化思路,从功耗的基础知识,功耗组成,功耗分析,功耗优化等几个方面,对 Android 应用的功耗优化做一个总结沉淀。
205 0
|
7月前
|
XML Java Android开发
Android 仿抖音直播滑动清屏,完美解决滑动冲突
Android 仿抖音直播滑动清屏,完美解决滑动冲突
|
7月前
|
编解码 网络协议 Android开发
Android平台RTMP|RTSP直播播放器功能进阶探讨
很多开发者在跟我聊天的时候,经常问我,为什么一个RTMP或RTSP播放器,你们需要设计那么多的接口,真的有必要吗?带着这样的疑惑,我们今天聊聊Android平台RTMP、RTSP播放器常规功能,如软硬解码设置、实时音量调节、实时快照、实时录像、视频view翻转和旋转、画面填充模式设定、解码后YUV、RGB数据回调等:
106 0
|
8月前
|
Android开发
Android 根据时间的升序或降序把数据列表进行排序
Android 根据时间的升序或降序把数据列表进行排序
92 0
|
9月前
|
XML Java 数据处理
Android:RecyclerView封装,打造列表极简加载
此库的封装,除了刷新加载库使用了SmartRefreshLayout,其他的都是自己从0到1的开发,目前,自己已经在项目中使用,暂时没有出现任何问题,当然了,后续,也会不断的对其进行优化,增加一些其他的功能,希望有需要的小伙伴,长期关注。
236 0
|
11月前
|
Android开发
全网最优雅安卓列表项可见性检测
全网最优雅安卓列表项可见性检测
116 0