Android 阿里云 视频直播安全下载踩坑实录
最近项目里面集成了阿里云直播的内容,其中需要相应的下载视频的功能,遇到了一些问题,在这里贴出来跟大家分享一下,
我在项目中使用的是基于阿里云高级播放器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.什么是视频直播 2.视频直播架构 3.官方文档链接 二.使用流程 1.使用条件 2.添加推流域名和播流域名 3.配置CNAME 4.关联推流域名和播流域名 5.生成推流地 ...
- java SpringBoot 集成 阿里云视频直播 完成直播功能
经历了几天的周折,近期才把项目完成,在这里与大家分享一下踩坑之路,也方便日后有类似项目,可以借阅一番 开发直播前先满足已下条件 1.开通视频直播功能 2.购买好了OSS存储 3.购买两个域名并且备案好 ...
- 阿里云视频直播PHP-SDK
阿里云 视频直播 配置 及 PHP-SDK 接入教程 准备工作 域名管理 配置鉴权 地址生成器及DEMO演示-熟悉鉴权 接入SDK 推流回调的配置 阿里云 视频直播 配置 及 PHP-SDK 接入教程 ...
- 阿里云视频直播推流和播流地址生成
记录学习阿里云视频直播 准备环境: 1.已开通阿里云视频直播服务. 2.2个域名:一个用于推流,一个用于播流. 3.在视频直播服务里面找到域名配置,配置好播流和推流域名之间的关系. 4.下载Vlc和o ...
- 阿里云视频直播,使用obs推流验证是否成功
阿里云视频直播推流地址验证 首先,根据上篇文章得到推流地址以及播流地址,从官方下载obs工具和vlc工具,下面开始验证地址是否正确? 演示 1.打开obs工具,找到右下角的设置按钮,点击推流,将推流地 ...
- 阿里云视频直播产品使用流程
1 阿里云视频直播使用流程 1.1 域名配置,及CNAME映射 开通视频直播,开通服务免费,产生的流量付费: 1.1.1 开通后,进入管理控制台: 使用阿里云视频直播,必须有一个审核通过的域名.没有的 ...
- H5直播之阿里云视频直播的实现
转自https://blog.csdn.net/hanierming/article/details/52769424 由于公司需要开发一款直播软件,以前也并没有接触过直播这一方面,所以就来从0开始做 ...
- java SpringBoot 集成 阿里云视频直播 完成直播功能
经历了几天的周折,近期才把项目完成,在这里与大家分享一下踩坑之路,也方便日后有类似项目,可以借阅一番 该项目是一个H5直播,采用m3u8格式完成直播的展示.通过推流地址,借助第三方推流工具实现直播效果 ...
- 首批唯一!阿里云视频直播服务获信通院首批唯一认证
简介:阿里云视频直播服务 7 月 28 日,由中国信息通信研究院主办的 2021 可信云大会上,阿里云凭借在视频直播 "云 - 边 - 端" 的产品技术优势,以最高标准通过了可信云 ...
最新文章
- openssl 证书生成手册
- 现在的便签本都这么社会了!?重复写万次还能云端保存
- 如果你跟夕小瑶恋爱了...(上)
- flush什么意思中文翻译_flush是什么意思
- 组策略最佳实践之“降龙十八掌”
- javascript调用ActiveX接口失败的解决方案及使用心得
- jmeter断言 判断响应数据是否符合预期
- 带你了解APP开发的具体流程
- 关于 Nim游戏与SG函数 的一点研究
- 彻底永久禁止Win10自动更新工具Windows Update Blocker v1.6 汉化版
- 智慧工地、智慧建筑、项目GIS、工程信息化协同管理平台、BIM一体化项目管理平台、工程进度管理、计划进度、施工模拟、BIM视图、模型管理、质量管理、安全管理、施工管理、文档管理、建筑施工、工程展板
- linux mp4box安装,视频处理利器 MP4Box常用的12个命令
- Word在生成PDF后,PDF左侧导航书签没有目录
- android 自定义剪裁,Android自定义View实现照片裁剪框与照片裁剪功能
- Facebook第三方登录对接
- Sklearn_LearningCurve
- 股票/期货分仓系统都能实现什么功能?
- macOS 使用 X11 运行远端 linux 中的 x11 client 图形程序
- 深度学习attention机制中的Q,K,V分别是从哪来的?
- java面试一些问题汇总
热门文章
- Vue编程的团队代码规范
- 牛视源码定制,抖音矩阵系统,别和谐啊、、、
- 【最具价值CTO评选秀】出门问问CTO雷欣:从技术极客到核心管理的秘密
- 如何添加pwa网站到桌面
- 文旅景区夜游该如何设计项目
- Linux安装PHP(最新版)
- 一个公开了源码的Android UI 设计器,很好很强大,不知道的可以看看
- IService和他的多个ServiceImpl
- 苹果xr如何关机_iPhone X强制关机集合
- Factor_mimicking_portfolio(模仿因子的投资组合):EAP.fama_macbeth.Factor_mimicking_portfolio