ExoPlayer架构详解与源码分析(13)——TeeDataSource和CacheDataSource

系列文章目录

ExoPlayer架构详解与源码分析(1)——前言
ExoPlayer架构详解与源码分析(2)——Player
ExoPlayer架构详解与源码分析(3)——Timeline
ExoPlayer架构详解与源码分析(4)——整体架构
ExoPlayer架构详解与源码分析(5)——MediaSource
ExoPlayer架构详解与源码分析(6)——MediaPeriod
ExoPlayer架构详解与源码分析(7)——SampleQueue
ExoPlayer架构详解与源码分析(8)——Loader
ExoPlayer架构详解与源码分析(9)——TsExtractor
ExoPlayer架构详解与源码分析(10)——H264Reader
ExoPlayer架构详解与源码分析(11)——DataSource
ExoPlayer架构详解与源码分析(12)——Cache
ExoPlayer架构详解与源码分析(13)——TeeDataSource和CacheDataSource



前言

书接上回,继续贴下上文的蜘蛛网
在这里插入图片描述
铺垫了那么多的基础,本篇终于可以来分析下CacheDataSource,上篇重点讲完了图的Cache的下半部分,而将Cache和CacheDataSource关联起来的是一个叫TeeDataSource特殊DataSource。

TeeDataSource

这是一个3通阀门一样的DataSource,有一个输入端2个输出端,也可以理解为在正常的输入和输出端中间又接了一个输出端,类似于下图
在这里插入图片描述
upstream也是一个DataSource,一般是上游的原始数据源,如OkHttpDataSource获取的网络源,dataSink参照上篇ExoPlayer架构详解与源码分析(12)——Cache,这些参数在TeeDataSource初始化时设置的。
看下代码实现

  @Override
  //打开数据源
  public long open(DataSpec dataSpec) throws IOException {
   
    bytesRemaining = upstream.open(dataSpec);//打开上游数据源
    if (bytesRemaining == 0) {
   
      return 0;
    }
    if (dataSpec.length == C.LENGTH_UNSET && bytesRemaining != C.LENGTH_UNSET) {
   
      // 根据实际长度裁剪dataSpec,保证传给dataSink长度正确
      dataSpec = dataSpec.subrange(0, bytesRemaining);
    }
    dataSinkNeedsClosing = true;
    dataSink.open(dataSpec);//dataSink打开流,主要就是通过cache startFile打开缓存文件获取到流
    return bytesRemaining;
  }
  
  @Override
  //读取数据
  @Override
  public int read(byte[] buffer, int offset, int length) throws IOException {
   
    if (bytesRemaining == 0) {
   
      return C.RESULT_END_OF_INPUT;
    }
    //从上游读取数据
    int bytesRead = upstream.read(buffer, offset, length);
    if (bytesRead > 0) {
   
      // 在数据返回前,先通过dataSink将数据写入到上面打开的缓存文件流里
      dataSink.write(buffer, offset, bytesRead);
      if (bytesRemaining != C.LENGTH_UNSET) {
   
        bytesRemaining -= bytesRead;
      }
    }
    //输出数据
    return bytesRead;
  }

可以看到TeeDataSource实现很简单,TeeDataSource就是为了数据边读边缓存而实现的,只要是读取过的数据都会缓存到文件里,至于在什么时候使用TeeDataSource,这就要讲到本篇的重点CacheDataSource了。

CacheDataSource

读取和写入Cache的DataSource 。如果可能的话,请求会从缓存中获取。当数据未缓存时,会从上游DataSource请求数据并将其写入缓存。
CacheDataSource,主要包含3个DataSource

  • upstreamDataSource 上游原始数据的源,如果此时播放的是一个网络的URL文件,这个upstreamDataSource可能就是OkHttpDataSource,无需缓存或者当前已经在缓存时,就会使用此源。
  • cacheWriteDataSource 缓存写入源,默认的是TeeDataSource,通过它在数据读取时缓存到文件,当前资源未缓存且需要缓存时,就会使用此源。
  • cacheReadDataSource 缓存数据读取源,当前播放的数据已经被缓存时,就会通过这个源将缓存的数据读取出来,正常数据都是缓存在本地文件中的所以这里一般都是FileDataSource,当前资源已经查询到缓存时,就会使用此源。

上面几个源的关系可以在源码的openNextSource方法中看出来。

接下来看源码实现:

private CacheDataSource(
      Cache cache,
      @Nullable DataSource upstreamDataSource,
      DataSource cacheReadDataSource,
      @Nullable DataSink cacheWriteDataSink,
      @Nullable CacheKeyFactory cacheKeyFactory,
      @Flags int flags,
      @Nullable PriorityTaskManager upstreamPriorityTaskManager,
      int upstreamPriority,
      @Nullable EventListener eventListener) {
   
    this.cache = cache;
    //用于读取缓存的DataSource,只要是缓存在文件里这里一般都是FileDataSource
    this.cacheReadDataSource = cacheReadDataSource;
    //cacheKeyFactory 用于生成CacheContent的资源key,默认就是取DataSpec.key,没有则获取播放文件的URL
    this.cacheKeyFactory = cacheKeyFactory != null ? cacheKeyFactory : CacheKeyFactory.DEFAULT;
    //是否在缓存时阻塞
    this.blockOnCache = 
  • 22
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值