隽阜 发布时间: 2019-02-11 10:37:41 浏览 25 评论 0
加密
线程
配置
控制台
多线程
void
阿里云播放器
摘要: 基本介绍 优酷, 爱奇艺, 腾讯等主流的视频类 App 都有视频离线下载的功能, 主要目的是在 Wi-Fi 下将视频离线在本地, 然后在无网或者 4G 的情况下去观看离线视频. 那么阿里云播放器也提供了视频下载的功能. 这个功能主要针对的是点播视频, 也就是 vid 播放的视频的下载.
基本介绍
优酷, 爱奇艺, 腾讯等主流的视频类 App 都有视频离线下载的功能, 主要目的是在 Wi-Fi 下将视频离线在本地, 然后在无网或者 4G 的情况下去观看离线视频. 那么阿里云播放器也提供了视频下载的功能. 这个功能主要针对的是点播视频, 也就是 vid 播放的视频的下载.
https://www.atatech.org/articles/131369#1 主要问题
m3u8 如何下载? 我们知道 m3u8 是一个索引文件, 真正的视频文件是各个 ts 的分片, 那么如何下载成一个完成的视频呢?
如何对视频下载进行多线程控制? 在一些 App 中, 多个视频同时下载被认为是高级 VIP 才有的功能.
如何实现断点续传? 当在下载过程中突然中断了, 那么下次再启动的时候要能够实现续传.
下载过程中 sts 等信息过期怎么处理?
加密的视频下载到本地如何保障安全性呢?
https://www.atatech.org/articles/131369#2 实现原理
https://www.atatech.org/articles/131369#3 下载过程
阿里云播放器支持 mp4 文件和 m3u8 视频文件两种格式下载. 其下载过程基本一致. 流程图如下:
从上述流程图中可以看到, m3u8 文件的下载我们会 mux 成一个 mp4 文件, 首先将各个 ts 文件分别下载, 最后的过程中再进行 mux.
https://www.atatech.org/articles/131369#4 多线程控制
- /*
- 功能: 设置同时下载的数量, 最大 4 个
- 参数: count: 同时下载的个数
- */
- -(void)setMaxDownloadOperationCount:(int)count;
通过上述的接口, 可以设置并行下载的个数. 当添加到队列中的数量多于这个设定的个数后, 会在队列中进行等待, 当之前的下载完成后会自动进行下一个视频的下载.
https://www.atatech.org/articles/131369#5 异常中断
经常有的情况是: 不小心将 App 杀掉了, 或者手机没电关机了等其他中断的因素. 这个时候下次下载的时候要能够恢复之前的现场. 我们提供了一个回调来通知 App:
- /*
- 功能: 未完成回调, 异常中断导致下载未完成, 下次启动后会接收到此回调.
- 回调数据: AliyunDownloadMediaInfo 数组
- */
- -(void) onUnFinished:(NSArray<AliyunDataSource*>*)mediaInfos;
https://www.atatech.org/articles/131369#6 过期处理
通过 vid 的方式进行下载, 同样支持 vid+playAuth,vid+sts,vid+mps 的方式进行播放, 将这些信息添加到队列中, 如果之前一个视频下载时间较长, 那么后面排队的视频的输入信息可能会过期. 针对这种情况, 我们增加了过期的回调来重新输入信息:
- /*
- 功能: 开始下载后收到回调, 更新最新的 playAuth. 主要场景是开始多个下载时, 等待下载的任务自动开始下载后, playAuth 有可能已经过期了, 需通过此回调更新
- 参数: 返回当前数据
- 返回: 使用代理方法, 设置 playauth 来更新数据.
- 备注: 如通过请求数据来获取 playAuth, 请使用同步方法. 此代理方法在其他线程里, 不会存在卡线程问题.
- */
- -(NSString*)onGetPlayAuth:(NSString*)vid format:(NSString*)format quality:(AliyunVodPlayerVideoQuality)quality;
- /*
- 功能: 开始下载后收到回调, 更新最新的 stsData. 主要场景是开始多个下载时, 等待下载的任务自动开始下载后, stsData 有可能已经过期了, 需通过此回调更新
- 参数: 返回当前数据
- 返回: 使用代理方法, 设置 AliyunStsData 来更新数据.
- 备注: 如通过请求数据来获取 stsData, 请使用同步方法. 此代理方法在其他线程里, 不会存在卡线程问题.
- */
- - (AliyunStsData*)onGetAliyunStsData:(NSString *)videoID
- format:(NSString*)format
- quality:(AliyunVodPlayerVideoQuality)quality;
- /*
- 功能: 开始下载后收到回调, 更新最新的 MtsData. 主要场景是开始多个下载时, 等待下载的任务自动开始下载后, MtsData 有可能已经过期了, 需通过此回调更新
- 参数: 返回当前数据
- 返回: 使用代理方法, 设置 AliyunMtsData 来更新数据.
- 备注: 如通过请求数据来获取 mtsData, 请使用同步方法. 此代理方法在其他线程里, 不会存在卡线程问题.
- */
- - (AliyunMtsData*)onGetAliyunMtsData:(NSString *)videoID
- format:(NSString*)format
- quality:(NSString *)quality;
https://www.atatech.org/articles/131369#7 加密下载
加密下载到本地, 如何保证安全呢? 有几个问题就是下载后我们需要重新加密, 防止密钥泄露. 同时另外一个就是要防止视频被拷贝到其他 App 中进行播放. 比如存在下面的场景.
所以我们通过将用户密钥和用户 App 绑定的方式来保证安全性.
那么如何来做呢?
https://www.atatech.org/articles/131369#8 控制台配置
如果希望实现加密下载, 需要在阿里云控制台配置下载选项为安全下载. 同时, 填写校验及加密相关信息. 截图如下:
填写完成之后, 控制台将会生成一个 dat 校验文件. 这个校验文件需要配置到阿里云下载模块中, 供校验使用.
https://www.atatech.org/articles/131369#9 使用 dat 文件
有了 dat 文件后, 我们将文件设置到播放器中, 通过如下接口:
- /*
- 功能: 设置加密文件
- 参数: encrptyFile 为加密文件路径
- */
- -(void)setEncrptyFile:(NSString*)encrptyFile;
https://www.atatech.org/articles/131369#10 下载功能示例
以 Android 为例, Android 提供了 AliyunDownloadManager 这个单例类实现下载功能.
https://www.atatech.org/articles/131369#11 配置
AliyunDownloadConfig
下载之前, 需要配置 AliyunDownloadConfig.AliyunDownloadConfig 中需要配置如下几个参数:
setMaxNums: 设置最大同时下载的个数.
setDownloadDir: 设置下载的文件保存的位置.
setSecretImagePath: 设置校验文件的路径. 其中: setSecretImagePath 只需要在加密下载的时候设置. 其余两个参数均需要设置.
https://www.atatech.org/articles/131369#12 获取视频信息并下载
阿里云播放器支持 STS ,AUTH,MPS 等多种方式下载. 以 STS 举例.
1. 通过 sts 信息, 调用 prepare 接口, 获取可以下载的视频项:
- //1. 设置下载监听
- downloadManager = AliyunDownloadManager.getInstance(getContext());
- downloadInfoListener = new MyDownloadInfoListener(this);
- downloadManager.addDownloadInfoListener(downloadInfoListener);
- //2. 使用 vidsts 准备下载资源.
- AliyunVidSts adb = new AliyunVidSts();
- adb.setVid(mVid);
- adb.setAcId(akid);
- adb.setAkSceret(akSecret);
- adb.setSecurityToken(token);
- downloadManager.prepareDownloadMedia(adb);
prepare 成功后, 添加某一项到 AliyunDownloadManager 中, 并开始下载:
- @Override
- void onPrepared(List<AliyunDownloadMediaInfo> infos) {
- // 准备结束
- downloadManager.addDownloadMedia(infos.get(0));
- downloadManager.startDownloadMedia(info);
- }
接受下载回调, 更新界面:
- @Override
- public void onPrepared(List<AliyunDownloadMediaInfo> infos) {
- // 准备完成
- }
- @Override
- public void onStart(AliyunDownloadMediaInfo info) {
- // 下载开始
- }
- @Override
- public void onProgress(AliyunDownloadMediaInfo info, int percent) {
- // 下载进度
- }
- @Override
- public void onStop(AliyunDownloadMediaInfo info) {
- // 下载停止
- }
- @Override
- public void onCompletion(AliyunDownloadMediaInfo info) {
- DemoDownloadActivity downloadActivity = weakActivity.get();
- if (downloadActivity != null) {
- downloadActivity.onCompletion(info);
- }
- }
- @Override
- public void onError(AliyunDownloadMediaInfo info, int code, String msg, String reuqestId) {
- // 下载出错
- }
- @Override
- public void onWait(AliyunDownloadMediaInfo outMediaInfo) {
- // 等待下载
- }
https://www.atatech.org/articles/131369#13 移除下载项
AliyunDownloadManager 提供了移除接口, 用来从下载管理中移除下载. 移除之后, 下载的文件将也会被删除.
downloadManager.removeDownloadMedia(info);
具体使用示例, 可参考官网 demo
来源: https://yq.aliyun.com/articles/689888