You need to enable JavaScript to run this app.
文档中心
视频点播

视频点播

复制全文
下载 pdf
进阶功能
下载视频
复制全文
下载 pdf
下载视频

播放器 SDK 支持下载功能。用户可在有网络的条件下将视频下载至本地,随后在无网络的环境下观看。播放器 SDK 支持下载 DirectUrl 视频源和 Vid 视频源,并提供开始、暂停、恢复、删除等控制下载任务的方法。本文介绍如何接入播放器 SDK 的下载功能,包含功能介绍、前提条件、集成步骤等内容。

注意

如需下载 HLS 视频,请集成 Android 播放器 SDK 1.36.2.11 或以上版本。

初始化下载功能

使用下载功能前,您需要先在播放器 SDK 初始化过程中对下载功能进行一些必要的配置,例如是否开启下载 HLS 视频的能力、设置下载路径。此外您还可以设置最大并发数和空闲磁盘空间大小的限制等。

注意

需要特别注意的是,初始化代码的时序对下载功能是否能正常工作有直接影响:

  • 如果您需要下载 HLS 视频,需要在初始化播放器 SDK 之前开启 HLS 下载功能。
  • 自定义下载文件存储路径,也需要在初始化播放器 SDK 之前设置。
  • 其余下载配置需要在初始化播放器 SDK 之后调用。

示例代码如下:

//(非必需)自定义下载文件存储路径,默认路径:"/data/user/0/包名/cache/video_cache/mdlDownload"。
// 如需自定义下载文件存储路径,必须在播放器 SDK 初始化之前调用。
TTVideoEngine.setStringValue(DATALOADER_KEY_STRING_DOWNLOAD_DIR, getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());

// 开启 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);
// 方式二:保留数量限制,例如最多缓存 500 个视频;按业务需求调整
VideoModelDBManager.setEnableSizeLimit(true);
VideoModelDBManager.setCacheSize(500);

//(非必需)设置最大并发下载数,默认值为 1。
Downloader.getInstance().setMaxDownloadOperationCount(1);

//(非必需)设置空闲磁盘空间大小的限制(单位为 Byte)。默认值为 1 GB,如果剩余磁盘大小不足 1 GB,则返回 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 也提供了不同数据源的下载能力。

说明

视频源的参数说明详见快速开始 - 设置播放数据源。

创建 DirectUrl 视频源下载任务

适用于下载来自火山引擎或第三方 CDN 的视频 URL 地址。通过传入视频的直接播放地址来指定播放内容。除了 url,您还必须提供以下两个关键参数:

  • vid:视频的唯一标识。可以是您自己的视频管理系统中的唯一标识,也可以在 App 层自行生成一个 ID。此 ID 会用于播放器 SDK 的日志上报、预加载、预渲染等功能中。
  • cacheKey:视频的缓存索引 Key。为确保唯一性,推荐使用 URL 的 MD5 值。为确保播放器缓存和下载功能的稳定性,强烈建议您遵循以下规范来设置 cacheKey:
    • 使用字符范围:cacheKey 的取值应仅包含字母 (a-z, A-Z) 和数字 (0-9)。
    • 避免特殊符号:不要在 cacheKey 中使用任何特殊符号,例如 _、-、/、?、& 等。
// 视频源
String[] urls = { httpUrl };
// 缓存 key,不可为空,需与视频源一一对应,比如使用 HTTP URL 的 MD5 值
String cacheKey = TTVideoEngine.computeMD5(httpUrl);
String vid = "videoID"; 
DownloadTask downloadTask = Downloader.getInstance().urlTask(urls, cacheKey, vid);

创建 Vid 视频源下载任务

适用于下载已上传至火山引擎视频点播服务的视频。通过视频的 Vid 和其对应的临时播放凭证 PlayAuthToken 来指定播放内容。这两个参数通常由您的业务服务端下发,客户端直接使用即可。详情请见通过临时播放 Token 播放。

// 视频 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();

注意

下载任务删除后,该任务对应的视频文件也会被删除。

获取下载状态和进度

为了让您的应用能够实时响应下载过程中的各种变化,例如在 UI 上展示进度条、更新任务状态或处理下载结果,您需要实现 IDownloaderListener 接口。SDK 会在任务进度更新、状态变更(如等待、运行中、暂停)以及最终完成或失败时,自动调用您实现的回调方法。

Downloader.getInstance().setListener(new IDownloaderListener() {
    /**
     * 下载任务完成回调。
     *
     * @param task 当前下载任务。
     * @param error 错误信息。如果 error 为 null,表示下载成功;否则表示下载失败。
     */
    @Override
    public void downloaderDidComplete(Downloader downloader, DownloadTask task, @Nullable Error error) {
        // 在此处理下载完成或失败的逻辑。
    }

    /**
     * @deprecated 该回调已废弃,请使用 downloaderOnProgress() 替代。
     *             对于 HLS 视频,其 receivedSize/totalSize 返回的是 TS 分片计数。
     */
    @Deprecated
    @Override
    public void downloaderProgress(Downloader downloader, DownloadTask task, long receivedSize, long totalSize) {
    
    }

    /**
     * (1.48.2 新增)下载任务进度回调。
     *
     * @param task 当前下载任务。
     * @param receivedSize 已下载的文件大小,单位为 Byte。对于 HLS,此值可以正确返回已下载的字节数。
     * @param totalSize 文件总大小,单位为 Byte。对于 HLS,由于总大小未知,此值在下载过程中为 -1,下载结束后才能获取。
     */
    @Override
    public void downloaderOnProgress(Downloader downloader, DownloadTask task, long receivedSize, long totalSize) {
        // 推荐调用 task.getProgress() 获取所有视频格式(包括 HLS)的精确下载百分比。
        float progress = task.getProgress(); // progress 范围为 [0.0, 1.0]。
        int percent = (int) (progress * 100);
        
        // 您现在可以使用 receivedSize 参数向用户展示 HLS 视频已下载的具体大小(例如 MB)。
        // 在此更新您的进度条 UI。
        // Log.d("Downloader", String.format("任务 %s 进度: %d%%, 已下载: %.2f MB", 
        //        task.getVid(), percent, receivedSize / 1024.0 / 1024.0));
    }

    /**
     * 下载任务开始或恢复时回调。
     *
     * @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) {
        // 在此可以根据任务状态更新 UI。
    }
});

播放视频

SDK 内部已处理下载缓存与播放的关联关系。SDK 会优先播放已经下载的视频,即使它们尚未完全下载完成,因此您播放时无需额外设置。

播放 DirectUrl 视频源

// 播放已下载的 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();

播放 Vid 视频源

if (/* 该 vid 的视频已下载完成 */) {
    // 离线播放已下载的文件需开启强制使用 VideoModel 缓存
    ttVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE_FORCE, 1);
}
// 播放已下载的 HLS 视频前必须设置以下 option
ttVideoEngine.setIntOption(PLAYER_OPTION_INT_ALLOW_ALL_EXTENSIONS, 1);
ttVideoEngine.setIntOption(PLAYER_OPTION_USE_VIDEOMODEL_CACHE, 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();

下载外挂字幕

播放器 SDK 支持在下载视频时一并下载外挂字幕,覆盖 DirectUrl 和 Vid 两种视频源。SDK 先下载视频,再从字幕列表中选择一条字幕下载,供后续离线播放时加载。

注意

外挂字幕下载自 Android 播放器 SDK 1.51.3.9 起支持,基础版、高级版和企业版均可使用。请集成 1.51.3.9 或以上版本。

前提条件

  • 下载字幕本身不要求高级版或企业版:只要 SDK 授权有效且版本满足要求,基础版也可以下载字幕文件。播放时加载并展示外挂字幕仍需高级版或企业版 License,详见添加外挂字幕和License 管理。
  • 已按本文完成初始化下载功能和获取已有下载任务。下载 HLS 视频时,还需完成 HLS 下载配置。
  • DirectUrl 方式:应用服务端需提供视频地址及字幕信息。字幕支持 WebVTT 和 SRT 格式。
  • Vid 方式:字幕已与 Vid 绑定,应用服务端需分别提供视频播放鉴权 Token 和字幕鉴权 Token。字幕鉴权 Token 的签发方式详见签发字幕鉴权 Token。

字幕信息

DirectUrl 方式下,应用服务端下发的字幕信息使用以下结构。示例中的 URL 需替换为实际可下载的字幕地址。

{
  "list": [
    {
      "language_id": 1,
      "language": "cmn-Hans-CN",
      "format": "webvtt",
      "url": "https://example.com/subtitles/chinese.vtt",
      "sub_id": 128934090
    }
  ]
}
字段类型说明
listArray字幕列表,可包含多条字幕。一个下载任务选择其中一条下载。
list[].language_idInteger必填,字幕语言 ID,取值详见语言。
list[].languageString可选,语言标识。
list[].formatString必填,字幕格式,使用 webvtt 或 srt。
list[].urlString必填,可下载的字幕文件地址。
list[].sub_idInteger必填,字幕 ID,用于选择下载的字幕;它与语言 ID、列表位置不同。
list[].cache_keyString可选,字幕缓存标识。未提供或为空字符串时由 SDK 生成;业务自定义时,下载和播放应使用相同值。

创建带字幕的 DirectUrl 下载任务

通过 SubDesInfoModel 构建字幕源,再调用带字幕参数的 urlTask 创建任务。以下代码在已有下载任务加载成功后执行。subtitleInfoJson 是应用服务端下发的字幕信息 JSON 字符串;为 null 或空字符串时,仅下载视频。

String videoUrl = "YOUR_VIDEO_URL";
String videoId = "YOUR_VIDEO_ID";
// 视频缓存标识应与后续播放使用的 cacheKey 一致。
String cacheKey = TTVideoEngine.computeMD5(videoUrl);

SubDesInfoModel subtitleModel = null;
if (!TextUtils.isEmpty(subtitleInfoJson)) {
    try {
        subtitleModel = new SubDesInfoModel(new JSONObject(subtitleInfoJson));
    } catch (JSONException e) {
        // 字幕信息不是有效 JSON,业务提示错误或重新获取数据。
        return;
    }
}

// null:下载字幕列表的第一条。
// 下载指定字幕时,传入该字幕的 sub_id;未匹配到时仍选择第一条。
Integer subtitleId = null;

DownloadURLTask task = Downloader.getInstance().urlTask(
        new String[] {videoUrl},
        cacheKey,
        videoId,
        subtitleModel,
        subtitleId);
if (task == null) {
    // 创建失败,检查视频地址、cacheKey 和 SDK 授权。
    return;
}

// 默认 false:字幕下载失败会影响整体任务结果。
// 可选:允许视频成功、字幕失败时整体任务仍成功,再取消下面的注释。
// task.setIgnoreSubtitleDownloadFailure(true);
task.resume();

subtitleModel 为 null 或字幕列表为空时,仅下载视频。只设置 subtitleId 不会触发字幕下载。

使用 VideoModel 数据源时,先按选中的视频档位取得 URL 和视频 cacheKey,再连同字幕模型调用同一个 urlTask 接口;字幕下载仍由 DownloadURLTask 完成。

创建带字幕的 Vid 下载任务

向 vidTask 传入视频播放鉴权 Token 和字幕鉴权 Token。SDK 获取字幕列表后,按 subtitleId 选择一条字幕下载。以下代码在已有下载任务加载成功后执行。

String videoId = "YOUR_VIDEO_ID";
String playAuthToken = "YOUR_PLAY_AUTH_TOKEN";
String subtitleAuthToken = "YOUR_SUBTITLE_AUTH_TOKEN";
Resolution resolution = Resolution.High;

// 已知目标字幕的 sub_id 时可指定该 ID。
// null 或未匹配到时,SDK 下载字幕列表的第一条。
Integer subtitleId = null;

DownloadVidTask task = Downloader.getInstance().vidTask(
        videoId,
        resolution,
        playAuthToken,
        subtitleAuthToken,
        subtitleId);
if (task == null) {
    // 创建失败,检查视频参数和 SDK 授权。
    return;
}

// 默认 false。业务允许忽略字幕失败时,再取消下面的注释。
// task.setIgnoreSubtitleDownloadFailure(true);
task.resume();

playAuthToken 用于视频鉴权,subtitleAuthToken 用于字幕鉴权,分别由应用服务端签发。subtitleAuthToken 为 null 或空字符串时,仅下载视频。

上述五参数接口默认下载 H.264 视频,并关闭 baseDashEnable。如需指定编码、DASH 或 HTTPS,使用以下重载,并与后续播放的清晰度和编码保持一致:

DownloadVidTask task = Downloader.getInstance().vidTask(
        videoId,
        resolution,
        TTVideoEngine.CODEC_TYPE_H265, // 示例为 H.265,按实际播放配置选择。
        false,                         // baseDashEnable,按视频源配置。
        true,                          // httpsEnable。
        playAuthToken,
        subtitleAuthToken,
        subtitleId);
if (task != null) {
    task.resume();
}

处理字幕下载结果

downloaderSubtitleDidComplete 表示字幕阶段结果,downloaderDidComplete 表示整体下载结果,业务应分别处理。将以下方法加入已有的 IDownloaderListener 实现:

@Override
public void downloaderSubtitleDidComplete(
        Downloader downloader, DownloadTask task, Error error) {
    if (error == null) {
        // 选中的字幕已下载成功。
    } else if (error.code == Error.SubNoSubtitle) {
        // 该视频无可用字幕,属于正常情况,整体任务仍成功。
    } else {
        // 字幕下载失败。
        // 即使已开启“忽略字幕下载失败”,这里仍返回真实错误。
    }
}

@Override
public void downloaderDidComplete(
        Downloader downloader, DownloadTask task, Error error) {
    if (error == null) {
        // 整体下载成功。
        // 字幕是否实际下载成功,按字幕完成回调的结果判断。
    } else {
        // 按错误信息处理任务失败或结束原因。
    }
}
情况字幕完成回调整体完成回调后续处理
视频、选中的字幕均下载成功error == nullerror == null可离线播放视频及该字幕。
未配置字幕,或 DirectUrl 字幕列表为空不触发字幕回调视频下载成功后,error == null仅下载视频。
VID 字幕接口返回无可用字幕error.code == Error.SubNoSubtitleerror == null按无字幕处理。
字幕下载失败,保留默认 false返回字幕错误返回错误处理错误后调用 task.resume(),重试字幕下载。
字幕下载失败,设置为 true仍返回字幕错误error == null视频可用,但失败的字幕不可用;对该已成功收尾的任务再次调用 resume() 不会补下字幕。
视频下载失败尚未进入字幕阶段,不触发字幕回调返回视频下载错误处理视频下载错误。

setIgnoreSubtitleDownloadFailure 在创建任务后、resume() 前设置,只影响字幕失败时的整体任务结果,不会忽略视频下载错误。

如需区分视频和字幕的下载阶段,可监听 downloaderVideoDidComplete 和 downloaderSubtitleWriteData:前者仅在视频下载成功、即将尝试下载字幕时触发;后者提供字幕下载的字节数和时间间隔。VID 传入非空字幕 Token 时,即使后续查询发现视频没有字幕,也会先触发视频完成回调;DirectUrl 字幕模型为 null 或列表为空时,不触发该回调。

视频进度达到 100% 后,字幕仍可能正在下载,整体结果以 downloaderDidComplete 为准。

离线播放字幕

视频播放源按播放视频配置:DirectUrl 保持视频 cacheKey 一致;VID 保持下载时的清晰度和编码设置,并启用视频信息缓存。

字幕仍需按添加外挂字幕配置功能开关、字幕源和内容回调。SDK 返回字幕文本,业务通过自己的 UI 展示。以下几点需要额外注意:

  • 可通过 DownloadURLTask.getSubtitleModel() 或 DownloadVidTask.getSubtitleModel() 获取任务保存的字幕列表,在设置视频播放源之后、调用 play() 之前,用 setSubDesInfoModel 设置给播放器。VID 任务的字幕列表在获取字幕信息成功后才可用;模型非空不代表字幕文件已下载成功。
  • 播放前开启 PLAYER_OPTION_ENABLE_OPEN_SUB_THREAD 和 PLAYER_OPTION_SUB_ENABLE_MDL;输出字幕时开启 PLAYER_OPTION_ENABLE_OPEN_SUB。通过 PLAYER_OPTION_SWITCH_SUB_ID 选择本次实际下载的 sub_id。
  • 下载时 subtitleId 为 null 或未匹配到时,实际下载的是列表第一条。离线播放应选择同一条字幕;列表中的其他字幕尚未因本任务下载。
  • 下载和播放的字幕 cacheKey 应相同。字幕模型带有非空 cache_key 时,两侧均优先使用该值;没有该字段或值为空时,下载侧使用 MD5(字幕 URL 的 path) + "_sub" 生成。
  • 未提供 cache_key 时,保持播放器默认的字幕 cacheKey 生成方式。若通过 setMDLCacheKeyGeneratorForSubModel 自定义了播放侧算法,下载侧不会自动采用该算法,离线播放可能无法命中字幕缓存。DirectUrl/VideoModel 可在字幕模型中提供一致的 cache_key;VID 模型无该字段时尤其需要核对生成方式。
  • 下载任务或字幕缓存被删除后,需要重新下载。
最近更新时间:2026.11.05 17:33:07
这个页面对您有帮助吗?
有用
有用
无用
无用