Exoplayer 的 缓存-- 一 使用简介

文章目录

  • 创建下载服务
  • 创建下载管理器
  • 添加下载
  • 删除下载
  • 开始和停止下载
    • 设置和清除下载停止原因
    • 暂停和恢复所有下载
    • 设置下载进度要求
    • 设置最大并行下载数
  • 查询下载
  • 监听下载
  • 播放下载的内容
    • 媒体源配置
  • 下载和播放自适应流

原文链接

ExoPlayer 提供了媒体离线下载功能。在大多数用例中,即使应用程序在后台,也可以继续下载。应用实现这个工呢,应用程序应该继承子类DownloadService 并实例化,并向DownloadService发送命令以添加、删除和控制下载。下图显示了涉及的主要类。

**图 1.**下载媒体的类。箭头方向表示数据流向。

  • DownloadService: 包装 一个DownloadManager并将命令转发给它。DownloadManager即使应用程序在后台,该服务也允许继续运行。
  • DownloadManager:管理多个下载,并使用DownloadIndex 加载 存储它们的状态,根据网络连接等要求启动和停止下载等。要下载内容,DownloadManager通常会读取从 HttpDataSource 下载的数据 ,并将其写入Cache.
  • DownloadIndex:保存下载状态。

创建下载服务

要创建DownloadService,需要对其进行子类化并实现其抽象方法:

  • getDownloadManager():返回要使用的DownloadManager

  • getScheduler(): 返回一个可选 Scheduler
    

    当满足挂起下载进度所需的要求时,它可以重新启动服务。ExoPlayer 提供了这些实现:

    • PlatformScheduler,它使用JobScheduler(最低 API 为 21)。有关应用权限要求,请参阅PlatformScheduler javadocs。
    • WorkManagerScheduler,它使用WorkManager。
  • getForegroundNotification():返回服务在前台运行时显示的通知。您可以使用 DownloadNotificationHelper.buildProgressNotification默认样式创建通知。

最后,需要在AndroidManifest.xml文件中定义服务:

<service android:name="com.myapp.MyDownloadService"android:exported="false"><!-- This is needed for Scheduler --><intent-filter><action android:name="com.google.android.exoplayer.downloadService.action.RESTART"/><category android:name="android.intent.category.DEFAULT"/></intent-filter>
</service>

DemoDownloadService有关具体示例,请参见AndroidManifest.xmlExoPlayer 演示应用程序。

创建下载管理器

以下代码片段演示了如何实例化 一个 DownloadManager,可以在 实例化的DownloadService 中的getDownloadManager() 返回。

// Note: This should be a singleton in your app.
databaseProvider = new StandaloneDatabaseProvider(context);// A download cache should not evict media, so should use a NoopCacheEvictor.
downloadCache = new SimpleCache(downloadDirectory,new NoOpCacheEvictor(),databaseProvider);// Create a factory for reading the data from the network.
dataSourceFactory = new DefaultHttpDataSource.Factory();// Choose an executor for downloading data. Using Runnable::run will cause each download task to
// download data on its own thread. Passing an executor that uses multiple threads will speed up
// download tasks that can be split into smaller parts for parallel execution. Applications that
// already have an executor for background downloads may wish to reuse their existing executor.
Executor downloadExecutor = Runnable::run;// Create the download manager.
downloadManager = new DownloadManager(context,databaseProvider,downloadCache,dataSourceFactory,downloadExecutor);// Optionally, setters can be called to configure the download manager.
downloadManager.setRequirements(requirements);
downloadManager.setMaxParallelDownloads(3);

DemoUtil在演示应用程序中查看具体示例。

添加下载

要添加下载,需要创建一个DownloadRequest并将其发送到您的 DownloadService. 对于自适应流可以使用DownloadHelper可用于帮助构建一个DownloadRequest,如本页下方所述。以下示例显示了如何创建下载请求:

DownloadRequest downloadRequest =new DownloadRequest.Builder(contentId, contentUri).build();

其中contentId是内容的唯一标识符。在一般的情况下, contentUri通常可以用作contentId,但是应用程序可以自由使用最适合其用例的任何 ID 方案。DownloadRequest.Builder还有一些可选的设置器。例如,setKeySetIdsetData可用于分别设置应用希望与下载关联的 DRM 和自定义数据。也可以使用 指定内容的 MIME 类型setMimeType,在contentUri无法推断媒体类型的情况下使用。

创建后,可以将请求发送DownloadService到添加下载:

DownloadService.sendAddDownload(context,MyDownloadService.class,downloadRequest,/* foreground= */ false)

其中MyDownloadService是app的DownloadService子类, foreground参数控制服务是否会在前台启动。如果您的应用程序已经在前台,那么该foreground 参数通常应该设置为false,因为DownloadService如果它确定它有工作要做,它将把自己置于前台。

删除下载

可以通过向 发送删除命令来删除下载DownloadService,其中contentId标识要删除的下载:

DownloadService.sendRemoveDownload(context,MyDownloadService.class,contentId,/* foreground= */ false)

您还可以使用 删除所有下载的数据 DownloadService.sendRemoveAllDownloads

开始和停止下载

满足下面四个条件,下载才会进行:

  • 下载没有停止原因。
  • 下载不会暂停。
  • 满足下载进度的要求。需求可以指定对允许的网络类型的约束,以及设备是否应该空闲或连接到充电器。
  • 未超过最大并行下载数。

所有这些条件都可以通过 DownloadService 控制

设置和清除下载停止原因

可以设置一个或所有下载停止的原因:

// Set the stop reason for a single download.
DownloadService.sendSetStopReason(context,MyDownloadService.class,contentId,stopReason,/* foreground= */ false);// Clear the stop reason for a single download.
DownloadService.sendSetStopReason(context,MyDownloadService.class,contentId,Download.STOP_REASON_NONE,/* foreground= */ false);

其中stopReason可以是任何非零值(Download.STOP_REASON_NONE = 0是一个特殊值,表示下载不会停止)。有多种停止下载原因的应用程序可以使用不同的值来跟踪每次下载停止的原因。设置和清除所有下载的停止原因与设置和清除单个下载的停止原因相同,但contentId应设置为null

设置停止原因不会删除下载。部分下载将被保留,清除停止原因将导致下载继续。

当下载有非 STOP_REASON_NONE 原因时,它将处于 Download.STATE_STOPPED状态。停止原因 DownloadIndex保留在 中,如果应用程序进程被杀死并稍后重新启动,则保留原因。

暂停和恢复所有下载

所有下载都可以按如下方式暂停和恢复:

// Pause all downloads.
DownloadService.sendPauseDownloads(context,MyDownloadService.class,/* foreground= */ false);// Resume all downloads.
DownloadService.sendResumeDownloads(context,MyDownloadService.class,/* foreground= */ false);

当下载暂停时,它们将处于Download.STATE_QUEUED状态。与设置停止原因不同,这种方法不会保留任何状态更改。它只影响DownloadManager.

设置下载进度要求

Requirements可用于指定继续下载必须满足的约束。可以通过 DownloadManager.setRequirements()在创建时调用来设置要求DownloadManager,如上例所示。它们也可以通过向以下位置发送命令来动态更改DownloadService

// Set the download requirements.
DownloadService.sendSetRequirements(context,MyDownloadService.class,requirements,/* foreground= */ false);

当由于不满足要求而无法进行下载时,它将处于Download.STATE_QUEUED状态。您可以使用 查询未满足的要求DownloadManager.getNotMetRequirements()

设置最大并行下载数

可以通过调用来设置最大并行下载数 DownloadManager.setMaxParallelDownloads()。这通常在创建 时完成DownloadManager,如上例所示。

当由于已达到最大并行下载数而无法继续下载时,它将处于Download.STATE_QUEUED状态。

查询下载

可以查询所有下载的状态,包括已完成或失败的下载DownloadIndex。 可以通过调用DownloadManager获得。然后可以通过调用来获得遍历所有下载的游标 。或者,可以通过调用查询单次下载的状态。DownloadIndex``DownloadManager.getDownloadIndex()``DownloadIndex.getDownloads()``DownloadIndex.getDownload()

DownloadManager还提供DownloadManager.getCurrentDownloads(),它只返回当前(即未完成或失败)下载的状态。此方法对于更新通知和其他显示当前下载进度和状态的 UI 组件很有用。

监听下载

您可以添加一个侦听器以DownloadManager在当前下载更改状态时收到通知:

downloadManager.addListener(new DownloadManager.Listener() {// Override methods of interest here.});

DownloadManagerListener在演示应用程序的DownloadTracker类中查看具体示例。

下载进度更新不会触发对DownloadManager.Listener. 要更新显示下载进度的 UI 组件,您应该DownloadManager以所需的更新速率定期查询。DownloadService 包含一个示例,它会定期更新服务前台通知。

播放下载的内容

播放下载的内容类似于播放在线内容,不同之处在于数据是从下载中读取的,Cache而不是通过网络读取的。

不要尝试直接从下载目录中读取文件,这一点很重要。相反,请使用如下所述的 ExoPlayer 库类。

要播放下载的内容,CacheDataSource.Factory请使用与下载相同的 实例创建一个,并在构建播放器时Cache将其注入 :DefaultMediaSourceFactory

// Create a read-only cache data source factory using the download cache.
DataSource.Factory cacheDataSourceFactory =new CacheDataSource.Factory().setCache(downloadCache).setUpstreamDataSourceFactory(httpDataSourceFactory).setCacheWriteDataSinkFactory(null); // Disable writing.ExoPlayer player = new ExoPlayer.Builder(context).setMediaSourceFactory(new DefaultMediaSourceFactory(cacheDataSourceFactory)).build();

如果相同的播放器实例也将用于播放未下载的内容,CacheDataSource.Factory则应将其配置为只读,以避免在播放期间也下载该内容。

一旦播放器配置了CacheDataSource.Factory,它将可以访问下载的内容进行播放。播放下载就像将对应MediaItem的文件传递给播放器一样简单。一个MediaItem 可以从Download 获得Download.request.toMediaItem,也可以直接从DownloadRequest获得DownloadRequest.toMediaItem

媒体源配置

上面的示例使下载缓存可用于所有 MediaItem 的播放。也可以使下载缓存用于单个MediaSource实例,可以直接传递给播放器:

ProgressiveMediaSource mediaSource =new ProgressiveMediaSource.Factory(cacheDataSourceFactory).createMediaSource(MediaItem.fromUri(contentUri));
player.setMediaSource(mediaSource);
player.prepare();

下载和播放自适应流

自适应流(例如 DASH、SmoothStreaming 和 HLS)通常包含多个媒体轨道。通常有多个轨道包含不同质量的相同内容(例如标清、高清和 4K 视频轨道)。也可能有多个相同类型的轨道包含不同的内容(例如,不同语言的多个音轨)。

对于流式播放,可以使用Track选择器来选择播放哪些Track。类似地,对于下载,DownloadHelper可以使用 Track选择器来选择下载哪些曲目。DownloadHelper 典型用法遵循以下步骤:

  1. DownloadHelper 使用其中一种方法构建一个 DownloadHelper.forMediaItem。 准备DownloadHelper并等待callback。

    DownloadHelper downloadHelper =DownloadHelper.forMediaItem(context,MediaItem.fromUri(contentUri),new DefaultRenderersFactory(context),dataSourceFactory);
    downloadHelper.prepare(myCallback);
    
  2. 或者,使用 和 检查默认选定的轨道, 并使用getMappedTrackInfogetTrackSelections进行调整。clearTrackSelections``replaceTrackSelections``addTrackSelection

  3. DownloadRequest通过调用为选定的Track 创建一个getDownloadRequest。如上所述,可以将请求传递给您DownloadService以添加下载。

  4. 使用 释放助手release()

播放下载的自适应内容需要配置播放器并传递相应的MediaItem,如上所述。

构建时MediaItemMediaItem.playbackProperties.streamKeys必须设置为与 中的匹配,DownloadRequest以便播放器仅尝试播放已下载的曲目子集。使用 Download.request.toMediaItemDownloadRequest.toMediaItem构建 MediaItem会为您解决这个问题。

Exoplayer的缓存 一 使用简介相关推荐

  1. 分布式缓存系统Memcached简介与实践(.NET memcached client library)

    原文:分布式缓存系统Memcached简介与实践(.NET memcached client library) 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加 ...

  2. Exoplayer的缓存 二 下载服务DownloadService

    Exoplayer的缓存 – 二 下载服务 DownloadService 文章目录 DownloadService send 指令 onStartCommand 解析Intent DownloadM ...

  3. ExoPlayer的缓存 三 SimpleCache的使用

    ExoPlayer的缓存 – 三 Cache的使用 文章目录 CacheDataSource 读取数据 创建 CacheDataSource TeeDataSource 写入缓存数据 CacheDat ...

  4. 分布式缓存系统Memcached简介与实践

    缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载.缓存是解决这个问题的好办法.但是ASP.NET中的虽然已经可以实现对页面局部进行缓存,但还是不够灵 ...

  5. 布式缓存系统Memcached简介与实践

    缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载.缓存是解决这个问题的好办法.但是ASP.NET中的虽然已经可以实现对页面局部进行缓存,但还是不够灵 ...

  6. 第二季2:视频缓存池的简介

    以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除. 一.视频缓存池的概念 (1)视频的本质是多帧图片,图片的本质是RGB或rawRGB数据,视频要占用一段连续内存. (2)视频的裁剪.缩放 ...

  7. 分布式缓存之Memcache

    〇.为什么要用分布式缓存 1.软件从单机到分布式 走向分布式第一步就是解决:多台机器共享登录信息的问题. 例如:现在有三台机器组成了一个Web的应用集群,其中一台机器用户登录,然后其他另外两台机器共享 ...

  8. 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )

    文章目录 一.Bitmap 内存缓存策略 二.LruCache 内存缓存 三.LruCache 常用操作 四.LruCache 工具类 五.源码及资源下载 官方参考 : Google 官方提供的 内存 ...

  9. 分布式缓存Redis介绍

    分布式缓存Redis介绍      简介:讲解为什么要用缓存和介绍什么是Redis,新手练习工具          1.redis官网 https://redis.io/download        ...

最新文章

  1. 查看mysql版本不一致_MySQL-版本不一致
  2. 用python可以免费下载音乐吗-利用Python来下载会员歌曲!想让我充会员?不存在的!...
  3. c++ static 存储类
  4. Python树莓派编程1.2 探索树莓派
  5. 第二章导数与微分思维导图_线性代数第二章 矩阵 思维导图
  6. CNN与MLP之间的关系,优缺点
  7. git-创建版本仓库-创建版本-查看版本
  8. 运行Eclipse出现:a java runtime environment(JRE) or java development kit(JDK) must be....
  9. Crontab使用心得
  10. error: x264_bit_depth undeclared (first use in this function) did you mean x264_picture_t
  11. CTP: 平昨仓与平今仓,log轻轻告诉你.......
  12. 【WPS】折线图数据点上添加标记(三角形、正方形、菱形等)
  13. Mstar数据集的获取和使用
  14. 2022年第十三届蓝桥杯大赛软件类决赛C/C++/Java/Python真题
  15. iphone4s更换电池_如果更换了iPhone电池后仍然出现问题该怎么办
  16. proftpd mysql_Proftpd mysql认证配置文档
  17. 如何做好提升领导力培训PPT课件?
  18. IBM developerWorks 技术主题 Linux 文档库
  19. C# 判断网络是否ping通
  20. 社区版pyCharm创建Django项目

热门文章

  1. 学c语言要背的英文字母,26个字母背诵顺口溜快速记背字母的口诀
  2. 创建型模式-单例模式、工厂模式
  3. PHP后台如何处理base64图片
  4. GJB 9001C质量管理体系文件构建(1、质量管理体系文件构架)
  5. 视觉感知(一):CV入门知识点
  6. 西电操作系统上机实验4
  7. 调制解调器(Modem) 是在模拟信号和数字信号之间转换用的
  8. 小规模纳税人今年要怎么缴纳增值税才能降至最低?
  9. Puppet部署与应用
  10. MCU - C51 单片机「实例」