最近项目里面集成了阿里云直播的内容,其中需要相应的下载视频的功能,遇到了一些问题,在这里贴出来跟大家分享一下,

我在项目中使用的是基于阿里云高级播放器3.4.8的sdk,具体怎么导入sdk ,请移步官方文档,(ps:非常简单)

我下面所说的问题都是基于阿里云高级播放器 安全下载 所遇到的问题,

1.加密文件的获取:

加密文件可以使用官方demo里提供的算法工具类来生成sha1值,也可以使用 Terminal 来生成,

使用Terminal 生成的方法是    https://www.cnblogs.com/arxive/p/6978364.html

生成sha1值以后,就可以在阿里云官网的管理后台根据sha1值来获取加密文件了,是一个.dat 文件,

2.加密文件放入手机中

拿到加密文件以后,我们先把加密文件放入Android Studio 中的assets文件夹中(没有去创建,main包下面),然后,怎么放入手机中呢? 阿里云demo 里面有一个工具类,Commen ,直接拿过来用就可以了,稍后我会贴出来,

然后开始设置阿里云的初始化配置,只需要设置一次,视具体业务而定,

AliyunDownloadConfig config = new AliyunDownloadConfig();
//设置加密文件路径。使用安全下载的用户必须设置(在准备下载之前设置),普通下载可以不用设置。
Commen.getInstance(UIUtils.getContext()).copyAssetsToSD("encrypt", ConstantUtil.EncryptedPath);
config.setSecretImagePath(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + ConstantUtil.EncryptedPath + "/encryptedApp.dat");
//设置保存路径。请确保有SD卡访问权限。File file = new File(UIUtils.getSDCardCachePATH(ConstantUtil.VideoSavePath));
if (!file.exists()) {file.mkdir();
}
config.setDownloadDir(UIUtils.getSDCardCachePATH(ConstantUtil.VideoSavePath));
//设置最大下载个数,最多允许同时开启4个下载
config.setMaxNums(4);
AliyunDownloadManager.getInstance(UIUtils.getContext()).setDownloadConfig(config);

3.开始下载

阿里云提供三种方式下载,这里我采用了阿里云推荐的STS方式来下载,首先确认一个配置,后台生成STS的那个代码里面,不要设置policy,把request.setPolicy(policy);注释(否则下载会失败)

STS的下载需要凭证,一共三个字段  后台提供

String accessKeyId;
String accessKeySecret;String securityToken

在开始下载之前,要先注册阿里云下载的监听,便于在状态改变的时候及时更新本地数据库中的状态,

downloadManager.setDownloadInfoListener(mDownloadInfoListener);

然后,设置vids 过期的回调,目的是当vids过期之后能够重新请求vids的信息,防止下载失败,

在  new AliyunRefreshStsCallback() 的onSuccessData回调中要走本地请求下载凭证信息的接口,
downloadManager.setRefreshStsCallback(mRefreshStsCallback);

然后,准备下载,downloadManager.prepareDownloadMedia(aliyunVidSts);

在准备完成的回调函数里面加入下载队列,开始下载,

public void onPrepared(List<AliyunDownloadMediaInfo> list) {
//筛选你需要下载 的视频质量信息 开始下载for (int i = 0; i < list.size(); i++) {if (list.get(i).getQuality().equals(IAliyunVodPlayer.QualityValue.QUALITY_LOW)) {info = list.get(i);}}
downloadManager.addDownloadMedia(info);
downloadManager.startDownloadMedia(info);

到这里基本就可以下载了,遇到下载失败,可以查看阿里云文档或者提交工单进行咨询

4.下载视频的播放

下载视频播放,使用url 的播放方式进行播放,(跟直播传入的url 一样),传入本地文件的绝对路径作为url,

//播放方式二:使用URL播放(直播用户推荐使用)

String url = getIntent().getStringExtra("url");

AliyunLocalSource.AliyunLocalSourceBuilder asb = new AliyunLocalSource.AliyunLocalSourceBuilder();

asb.setSource(url);

//aliyunVodPlayer.setLocalSource(asb.build());

AliyunLocalSource mLocalSource = asb.build();

aliyunVodPlayer.prepareAsync(mLocalSource);

如果播放失败,请检查.dat 加密文件是否有效

到此,视频下载和阿里云服务器对接基本完成,

5.遇到问题以及常用解决方案

在项目中有一个下载全部的功能,就是把所有下载项一下子都加入下载列表,这里需要控制视频的下载时机,必须在上一个视频

的onStart 方法或者onError方法回调之后,才控制开始下一个视频的下载,(add然后start),否则以前的会下载出错。我在这里使用的是List 集合,查找正在下载的info 的索引,然后开启 索引+1 的下载 的方式进行控制的,也可以使用其他方法

如果 错误码是 109 错误信息是 Invalid secret image ,那么去手机的文件管理检查你的应用目录下是否有生成的.dat 的加密文件

还有,查看视频下载进度的时候,最后一点会变得特别慢,这里阿里云也是给出了解释,因为:

1)当前版本的SDK3修改了3.4.6上的cpu占用过高的问题,SDK故意设置了结尾处速度下降的情况。2)在到90%后视频下载需要对视频文件本身进行合成处理,因此需要一段时间。

本地数据库的存储使用的是郭霖的Litepal 框架,挺好用的,给个github 链接:

https://github.com/LitePalFramework/LitePal/issues?page=1&q=is%3Aissue+is%3Aopen

(ps 更新于2019.1.17号:使用LitePal 的查询功能,where 条件查询支持占位符嵌套,比如说,我想查找符合某些条件的所有数据,就可以类似于这样写:LitePal.where("status in (?, ?)", "200", "300").find(DownLoadInfo.class)  )

下面贴一下 Commen 工具类源码 :

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** assets目录文件拷贝工具类*/
public class Commen {private static Commen instance;private static final int SUCCESS = 1;private static final int FAILED = 0;private Context context;private FileOperateCallback callback;private volatile boolean isSuccess;private String errorStr;private ThreadPoolExecutor threadPoolExecutor;private String srcPath;private String sdPath;public static Commen getInstance(Context context) {if (instance == null) {synchronized (Commen.class) {if (instance == null) {instance = new Commen(context);}}}return instance;}private Commen(Context context) {this.context = context;}private Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (callback != null) {if (msg.what == SUCCESS) {callback.onSuccess();}if (msg.what == FAILED) {callback.onFailed(msg.obj.toString());}}threadPoolExecutor.remove(runnable);context = null;instance = null;}};public Commen copyAssetsToSD(final String srcPath, final String sdPath) {this.srcPath = srcPath;this.sdPath = sdPath;threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());threadPoolExecutor.execute(Executors.defaultThreadFactory().newThread(runnable));return this;}private Runnable runnable = new Runnable() {@Overridepublic void run() {copyAssetsToDst(context, srcPath, sdPath);if (isSuccess) {handler.obtainMessage(SUCCESS).sendToTarget();} else {handler.obtainMessage(FAILED, errorStr).sendToTarget();}}};public void setFileOperateCallback(FileOperateCallback callback) {this.callback = callback;}private void copyAssetsToDst(Context context, String srcPath, String dstPath) {try {String[] fileNames = context.getAssets().list(srcPath);if (fileNames.length > 0) {File file = new File(Environment.getExternalStorageDirectory(), dstPath);if (!file.exists()) {file.mkdirs();}for (String fileName : fileNames) {// assets 文件夹下的目录if (!"".equals(srcPath)) {copyAssetsToDst(context, srcPath + File.separator + fileName,dstPath + File.separator + fileName);} else {// assets 文件夹copyAssetsToDst(context, fileName, dstPath + File.separator + fileName);}}} else {File outFile = new File(Environment.getExternalStorageDirectory(), dstPath);InputStream is = context.getAssets().open(srcPath);FileOutputStream fos = new FileOutputStream(outFile);byte[] buffer = new byte[1024];int byteCount;while ((byteCount = is.read(buffer)) != -1) {fos.write(buffer, 0, byteCount);}fos.flush();is.close();fos.close();}isSuccess = true;} catch (Exception e) {e.printStackTrace();errorStr = e.getMessage();isSuccess = false;}}public void onDestroy() {if (threadPoolExecutor != null && runnable != null) {threadPoolExecutor.remove(runnable);}if (handler != null) {handler.removeMessages(SUCCESS);handler.removeMessages(FAILED);handler = null;}instance = null;callback = null;context = null;}public interface FileOperateCallback {/*** copy success*/void onSuccess();/*** copy fail* @param error 错误信息*/void onFailed(String error);}}

Android 阿里云 视频直播安全下载踩坑实录相关推荐

  1. 阿里云视频直播使用详细步骤

    目录 一.阿里云视频直播 1.什么是视频直播 2.视频直播架构 3.官方文档链接 二.使用流程 1.使用条件 2.添加推流域名和播流域名 3.配置CNAME 4.关联推流域名和播流域名 5.生成推流地 ...

  2. java SpringBoot 集成 阿里云视频直播 完成直播功能

    经历了几天的周折,近期才把项目完成,在这里与大家分享一下踩坑之路,也方便日后有类似项目,可以借阅一番 开发直播前先满足已下条件 1.开通视频直播功能 2.购买好了OSS存储 3.购买两个域名并且备案好 ...

  3. 阿里云视频直播PHP-SDK

    阿里云 视频直播 配置 及 PHP-SDK 接入教程 准备工作 域名管理 配置鉴权 地址生成器及DEMO演示-熟悉鉴权 接入SDK 推流回调的配置 阿里云 视频直播 配置 及 PHP-SDK 接入教程 ...

  4. 阿里云视频直播推流和播流地址生成

    记录学习阿里云视频直播 准备环境: 1.已开通阿里云视频直播服务. 2.2个域名:一个用于推流,一个用于播流. 3.在视频直播服务里面找到域名配置,配置好播流和推流域名之间的关系. 4.下载Vlc和o ...

  5. 阿里云视频直播,使用obs推流验证是否成功

    阿里云视频直播推流地址验证 首先,根据上篇文章得到推流地址以及播流地址,从官方下载obs工具和vlc工具,下面开始验证地址是否正确? 演示 1.打开obs工具,找到右下角的设置按钮,点击推流,将推流地 ...

  6. 阿里云视频直播产品使用流程

    1 阿里云视频直播使用流程 1.1 域名配置,及CNAME映射 开通视频直播,开通服务免费,产生的流量付费: 1.1.1 开通后,进入管理控制台: 使用阿里云视频直播,必须有一个审核通过的域名.没有的 ...

  7. H5直播之阿里云视频直播的实现

    转自https://blog.csdn.net/hanierming/article/details/52769424 由于公司需要开发一款直播软件,以前也并没有接触过直播这一方面,所以就来从0开始做 ...

  8. java SpringBoot 集成 阿里云视频直播 完成直播功能

    经历了几天的周折,近期才把项目完成,在这里与大家分享一下踩坑之路,也方便日后有类似项目,可以借阅一番 该项目是一个H5直播,采用m3u8格式完成直播的展示.通过推流地址,借助第三方推流工具实现直播效果 ...

  9. 首批唯一!阿里云视频直播服务获信通院首批唯一认证

    简介:阿里云视频直播服务 7 月 28 日,由中国信息通信研究院主办的 2021 可信云大会上,阿里云凭借在视频直播 "云 - 边 - 端" 的产品技术优势,以最高标准通过了可信云 ...

最新文章

  1. openssl 证书生成手册
  2. 现在的便签本都这么社会了!?重复写万次还能云端保存
  3. 如果你跟夕小瑶恋爱了...(上)
  4. flush什么意思中文翻译_flush是什么意思
  5. 组策略最佳实践之“降龙十八掌”
  6. javascript调用ActiveX接口失败的解决方案及使用心得
  7. jmeter断言 判断响应数据是否符合预期
  8. 带你了解APP开发的具体流程
  9. 关于 Nim游戏与SG函数 的一点研究
  10. 彻底永久禁止Win10自动更新工具Windows Update Blocker v1.6 汉化版
  11. 智慧工地、智慧建筑、项目GIS、工程信息化协同管理平台、BIM一体化项目管理平台、工程进度管理、计划进度、施工模拟、BIM视图、模型管理、质量管理、安全管理、施工管理、文档管理、建筑施工、工程展板
  12. linux mp4box安装,视频处理利器 MP4Box常用的12个命令
  13. Word在生成PDF后,PDF左侧导航书签没有目录
  14. android 自定义剪裁,Android自定义View实现照片裁剪框与照片裁剪功能
  15. Facebook第三方登录对接
  16. Sklearn_LearningCurve
  17. 股票/期货分仓系统都能实现什么功能?
  18. macOS 使用 X11 运行远端 linux 中的 x11 client 图形程序
  19. 深度学习attention机制中的Q,K,V分别是从哪来的?
  20. java面试一些问题汇总

热门文章

  1. Vue编程的团队代码规范
  2. 牛视源码定制,抖音矩阵系统,别和谐啊、、、
  3. 【最具价值CTO评选秀】出门问问CTO雷欣:从技术极客到核心管理的秘密
  4. 如何添加pwa网站到桌面
  5. 文旅景区夜游该如何设计项目
  6. Linux安装PHP(最新版)
  7. 一个公开了源码的Android UI 设计器,很好很强大,不知道的可以看看
  8. IService和他的多个ServiceImpl
  9. 苹果xr如何关机_iPhone X强制关机集合
  10. Factor_mimicking_portfolio(模仿因子的投资组合):EAP.fama_macbeth.Factor_mimicking_portfolio