本文介绍如何接入点播 SDK 的下载功能,包含功能介绍、前提条件、集成步骤等内容。
点播 SDK 支持下载功能。用户可在有网络的条件下将视频下载至本地,随后在无网络的环境下观看。点播 SDK 支持下载 DirectUrl 视频源和 Vid 视频源,并提供开始、暂停、恢复、删除等控制下载任务的方法。
在接入下载功能前,您需要阅读集成准备以及快速开始 - 初始化点播 SDK 章节,确保已经完成 SDK 的初始化。
说明
如需下载 HLS 视频,请集成 Android 点播 SDK 1.36.2.11 或以上版本。
使用下载功能前,您需要先在点播 SDK 初始化过程中对下载功能进行一些必要的配置,例如是否开启下载 HLS 视频的能力、设置下载路径。此外您还可以设置最大并发数和空闲磁盘空间大小的限制等。
注意
需要特别注意的是,初始化代码的时序对下载功能是否能正常工作有直接影响:
示例代码如下:
//(非必需)自定义下载文件存储路径,默认路径:"/data/user/0/包名/cache/video_cache/mdlDownload"。 // 如需自定义下载文件存储路径,必须在点播 SDK 初始化之前调用。 TTVideoEngine.setStringValue(DATALOADER_KEY_STRING_DOWNLOAD_DIR, "mnt/sdcard/testdownload"); // 开启 HLS 下载功能。可选,如业务中无需下载 HLS 视频,可跳过。 TTVideoEngine.setIntValue(DataLoaderHelper.DATALOADER_KEY_INT_ENABLE_HLS,1); // 开启 HLS TTVideoEngine.setIntValue(DataLoaderHelper.DATALOADER_KEY_ENABLE_HLS_PROXY,1); // 开启 HLS proxy // 点播 SDK 初始化,详见《快速开始》 Env.init(...); // Vid 下载时,会有下载数量限制,可通过以下两种设置方式调整限制 // 方式一:去除下载数量限制,存入 db 数据库直至磁盘空间不足 VideoModelDBManager.setEnableSizeLimit(false); // 方式二:根据业务需求自行设置下载数量限制 VideoModelDBManager.setCacheSize(Integer.MAX_VALUE); //(非必需)设置最大并发下载数,默认值为 1。 Downloader.getInstance().setMaxDownloadOperationCount(1); //(非必需)设置空闲磁盘空间大小的限制(单位为 byte)。默认值为 1G,如果剩余磁盘大小不足 1G,则返回 ERROR_CODE_DOWNLOAD_DISK_FULL错误。 Downloader.getInstance().setLimitFreeDiskSize(1024 * 1024 * 1024);
初始化后,调用 loadAllTasks
方法获取已有下载任务,包括已完成的任务和未完成的任务。执行完成后,SDK 会触发 downloaderDidLoadAllTask
回调。
说明
downloaderDidLoadAllTask
回调之后,才能创建和添加新任务。
// 加载已有下载任务,包括已完成的任务和未完成的任务。 // 执行完成会触发 downloaderDidLoadAllTask 回调。 // 初始化后即可调用此接口。 // 可用来做持久化:app 退出重新进入,通过调用此接口,可获取已下载完成和未完成的下载任务列表。 Downloader.getInstance().loadAllTasks(this.getApplicationContext());
点播 SDK 支持播放 DirectUrl 视频源和 Vid 视频源。与之对应,点播 SDK 也提供了不同数据源的下载能力。
说明
视频源的参数说明详见快速开始 - 设置播放数据源。
// 视频源 String[] urls = { httpUrl }; // 缓存 key,不可为空,需与视频源一一对应,比如使用 HTTP URL 的 MD5 值 String cachekey = MD5(httpUrl); String vid = "videoID"; DownloadTask downloadTask = Downloader.getInstance().urlTask(urls, cachekey, vid);
// 视频 ID String videoId = "your video id"; // 播放鉴权 token String playAuthToken = "your video id's play auth token"; // 分辨率 Resolution resolution = Resolution.High; DownloadTask downloadTask = Downloader.getInstance().vidTask(videoId, resolution, playAuthToken);
通过以下方法控制单个下载任务:
// 开始/恢复单个下载任务。 // 执行完毕后,SDK 会触发 downloaderDidResume 回调。 // 支持断点续传。 downloadTask.resume(); // 暂停单个下载任务。 downloadTask.suspend(); // 删除单个下载任务。 // 删除过程为异步,删除完成后 SDK 会触发 downloaderDidComplete 回调。回调参数 error 不为空,error.code 为 -9995。 downloadTask.invalidateAndCancel();
通过以下方法控制所有下载任务:
// 开始/恢复所有下载任务 Downloader.getInstance().resumeAllTasks(); // 暂停所有下载任务 Downloader.getInstance().suspendAllTasks(); // 删除所有下载任务 Downloader.getInstance().invalidateAndCancelAllTasks();
注意
下载任务删除后,该任务对应的视频文件也会被删除。
下载任务的完成情况、进度和状态等信息都需要通过监听器来获取。在完成初始化后,您需要设置下载监听器并实现相关的回调方法。示例代码如下:
Downloader.getInstance().setListener(new IDownloaderListener() { /** * 下载任务完成回调。 * * @param task 当前下载任务。 * @param error 错误。error 为 null 则表示下载任务成功,否则为下载任务失败。 */ @Override public void downloaderDidComplete(Downloader downloader, DownloadTask task, @Nullable Error error) { } /** * 下载任务进度回调。下载进度 = receivedSize / totalSize * 100% * * @param task 当前下载任务。 * @param receivedSize 已下载的文件大小,单位为 Byte。(HLS 不适用,见下方注意点) * @param totalSize 文件总大小,单位为 Byte。(HLS 不适用,见下方注意点) */ @Override public void downloaderProgress(Downloader downloader, DownloadTask task, long receivedSize, long totalSize) { } /** * 下载任务开始/恢复回调。 * * @param task 当前下载任务。 * @param fileOffset 已下载的数据量。 * @param expectedTotalBytes 该任务要下载的总数据量。 */ @Override public void downloaderDidResume(Downloader downloader, DownloadTask task, long fileOffset, long expectedTotalBytes) { } /** * 所有下载任务完成回调。 * * @param allTasks 所有任务列表,包含已完成的和未完成的。 */ @Override public void downloaderDidLoadAllTask(Downloader downloader, @Nullable List<DownloadTask> allTasks, @Nullable Error error) { } /** * 下载任务状态变更回调。 * * @param task 当前下载任务。 * @param state 当前下载任务状态: * - DOWNLOAD_TASK_STATE_INIT(0):初始化。 * - DOWNLOAD_TASK_STATE_WAITING(1):等待中。 * - DOWNLOAD_TASK_STATE_RUNNING(2):运行中。 * - DOWNLOAD_TASK_STATE_SUSPENDED(3):暂停。 * - DOWNLOAD_TASK_STATE_COMPLETED(4):正在取消。 * - DOWNLOAD_TASK_STATE_FAILED(5):完成。 */ @Override public void downloaderTaskStateDidChange(Downloader downloader, DownloadTask task, int state) { } });
注意
DownloadTask
中提供 getMediaType
用来获取下载的媒体类型。如果值是 HLS(M3U8),由于 SDK 无法知道整个 HLS(M3U8) 文件的大小,所以 downloaderProgress
回调中的 receivedSize
和 totalSize
并不是文件的字节数。您仅可通过以下公式计算下载进度:
下载进度百分比值 = receivedSize / totalSize * 100%
SDK 内部已经处理了下载缓存与播放的联动关系。SDK 会优先播放已经下载的视频,即使它们尚未完全下载完成,因此您播放时无需额外设置。
说明
// 播放已下载的 HLS 视频前必须设置以下 option ttVideoEngine.setIntOption(PLAYER_OPTION_INT_ALLOW_ALL_EXTENSIONS, 1); final String vid = "video id"; // 视频源与 vid 必须一一对应 final String url = "http://www.example.com/h264.mp4"; // 播放 cacheKey 与下载 cacheKey 保持一致 final String cacheKey = TTVideoEngine.computeMD5(url); // 1.组装 DirectUrl 视频源 StrategySource directUrlSource = new DirectUrlSource.Builder() .setVid(vid) .addItem(new DirectUrlSource.UrlItem.Builder() .setUrl(url) .setCacheKey(cacheKey) .build()) .build(); // 2.设置播放源 ttVideoEngine.setStrategySource(directUrlSource); // 3.播放 ttVideoEngine.play()
// 播放已下载的 HLS 视频前必须设置以下 option ttVideoEngine.setIntOption(PLAYER_OPTION_INT_ALLOW_ALL_EXTENSIONS, 1); // 离线播放已下载的文件需设置以下 option ttVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 1); ttVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE_FORCE, 1); // 设置强制播放本地缓存的视频 final String vid = "your video id"; // appServer 下发 final String playAuthToken = "your video id's play auth token"; // appServer 下发 final int encodeType = TTVideoEngine.CODEC_TYPE_H264; // final int encodeType = TTVideoEngine.CODEC_TYPE_H265; // final int encodeType = TTVideoEngine.CODEC_TYPE_H266; // 1.组装 Vid 播放源 StrategySource vidSource = new VidPlayAuthTokenSource.Builder() .setVid(vid) .setPlayAuthToken(playAuthToken) // 设置 Codec 类型(h264、h265、h266),不传则使用默认值 h264 .setEncodeType(encodeType) // 预期播放的分辨率,需和下载时设置的分辨率一致 .setResolution(Resolution.High) .build(); // 2.设置播放源 ttVideoEngine.setStrategySource(vidSource); // 3.播放 ttVideoEngine.play()
以下是下载任务完成回调中可能会返回的错误码及其说明:
枚举值 | 错误码 | 说明 |
---|---|---|
UserCancel | -9995 | 用户调用 invalidateAndCancel 方法删除某个下载任务。删除过程为异步,删除完成后 SDK 会触发 downloaderDidComplete 回调。回调参数 error 不为空,error.code 为 -9995。 |
NetworkNotAvailable | -9960 | 用户当前网络不可用。 |
SaveTaskItem | -9949 | 数据库发生错误,建议删除该下载任务。 |
SaveTaskWriteFile | -9948 | 磁盘写入错误,建议用户删除该下载任务,重新开始下载。 |
NotEnoughDiskSpace | -9947 | SDK 在触发一个下载任务时,会判断空闲空间的大小,如果小于 LimitFreeDiskSize 会有该错误。建议用户先清空一些空间再进行下载。 |
MediaLoaderNeedStart | -9946 | 在 loadAllTasks 时,如果没有先启动 SDK 的数据模块,会在 downloaderDidLoadAllTask 回调该错误。 |
URLUnavailable | -9945 | URL 不可用。建议更换 URL 后重试。 |
ServiceInaccessible | -9944 | URL 请求返回 500 等错误,无法下载资源。更换 URL 或提示无法下载(服务不可用)。 |
ParameterNull | -9999 | (VID 下载相关错误)参数为空。 |
InvalidVideoInfoRequest | -9990 | (VID 下载相关错误)鉴权失败,需更新 playAuthToken 。 |
ResultEmpty | -9997 | 服务端返回结果为空。 |
HTTPNotOK | -9994 | 网络问题,可重试。 |