产品
热门产品
人工智能
存储
网络
SaaS基础设施
视频云
物联网
应用PaaS
研发运维
专有部署
热门产品
云舟观测 GC
一站式数据采集与应用监控观测平台
人工智能
AI平台
天纪大模型开发 TLM
大模型微调、训练
天纪AI开发 TAI
全流程AI开发平台
天纪智能体开发 ADP
大模型驱动的智能体开发
天纪智能问答 RDP
检索增强生成(RAG)的问答
AI应用
内容审核 CM
图片审核|文本审核|音频审核|视频审核
人脸人体识别 FHR
人脸识别|人体识别|人脸比对|摔倒检测
OCR识别 OCR
卡证识别|通用文本识别|车牌识别
图像技术 IA
面向图片场景提供的多种人工智能技术
模型市场 MaaS
图片、音频、视频等多场景的算法模型
视觉分析
视图计算 VEC
云边融合 AI赋能的智能视图计算
存储
对象存储 OBS
稳定、安全、可靠的云存储服务
文件存储 QHDFS
具有标准HDFS访问协议的分布式文件系统
网络
内容分发网络 CDN
安全、稳定、低延时的分发加速服务
P2P内容分发 PCDN
利用闲置资源而构建的低成本高品质CDN
SaaS基础设施
API文档管理 APICloud
API文档、调试、MOCK一体化协作平台
统一身份认证 IAM
统一的身份认证、授权管理
幕印企业学堂 MuYin
企业培训|内容付费|知识营销
视频云
视频直播 LIVE
大规模实时转码、低延时的直播服务
视频点播 VOD
视频流畅播放服务
音视频通话 RTC
便捷的跨平台实时音视频互动直播服务
媒体处理 MPC
简洁的云媒体转码及内容合成处理服务
视频工具 SDK
视频剪辑SDK | 播放SDK
易讲教室直播 YiJiang
视频技术与传统教室融合
物联网
帝视物联网 IOT
低延时、海量存储的物联网视频监控服务
企业物联网平台
设备管理|设备接入|规则引擎|应用开发
生活物联网平台
针对消费级智能设备的物联网平台
应用PaaS
云短信 SMS
融合三网,安全可信的短信服务
研发运维
云舟观测 GC
一站式数据采集与应用监控观测平台
三六零天御加固保 JiaGu
提供安全可靠的加固防护产品及服务
兼容性测试 OpenTest
提供数百款TOP机型的云测服务
真机租用 RentPhone
远程真机租用,流畅体验如手机在手
iOS预审 iOSPre
智能扫描、分析、筛查ios审核的被拒风险点
专有部署
360云计算管理平台 Stack
规划、建设、运维一体的云计算解决方案
奇麟大数据 QiLin
企业级一站式大数据平台
360容器管理平台 Container
可对外私有化的容器云平台
360AI开发平台专有版 Prophet
全流程机器学习开发平台
更多产品,敬请期待
解决方案
产品解决方案
行业解决方案
产品解决方案
视频
通用直播解决方案
短视频解决方案
公共语音房聊天室解决方案
物联网
儿童手表音视频通话
云端NVR解决方案
数据上云
通用存储解决方案
IoT设备
AI+IPC解决方案
智能门锁解决方案
安防传感解决方案
智能网关解决方案
个护健康解决方案
账号体系
360用户帐号体系解决方案
行业解决方案
智慧城市
智慧社区解决方案
智慧交通解决方案
电商视频解决方案
电商视频解决方案
电商平台收款解决方案
教育
在线教育解决方案
互动课堂解决方案
全屋智能
智慧公寓解决方案
智慧酒店解决方案
家庭智能解决方案
智慧安防解决方案
医疗
健康看护解决方案
智能制造
工业物联网解决方案
游戏
游戏音视频解决方案
更多解决方案,敬请期待
帮助支持
技术社区
关于我们
控制台
登录
注册
云点播
云直播
产品文档
常见问题
API文档
云点播
产品文档
快速入门
API文档
CDN
产品文档
API文档
云存储
产品文档
SDK手册
API文档
互动直播
产品文档
API文档
操作指南
SDK管理
播放SDK
上传SDK
剪辑SDK
媒体处理
产品文档
API文档
帝视
产品文档
API文档
操作指南
支付平台
产品列表
产品文档
渠道接入解析
内容审核
产品文档
API文档
OCR识别
产品文档
API文档
人脸与人体识别
产品文档
API文档
SSL证书
产品说明
购买指南
电子签章
产品介绍
接入流程
云短信
接口文档
物联网平台
产品简介
快速入门
幕印企业学堂
产品介绍
生活物联网平台
产品简介
快速入门
图片处理
产品介绍
接口文档
视图计算
产品介绍
快速入门
常见问题
易讲-教室直播
产品介绍
帮助说明
产品说明
云点播介绍
服务优势
产品功能
应用场景
控制台操作指南
服务创建
上传视频
准备工作
视频列表
操作指南
转码说明文档
支持https播放
API文档
转码任务添加
使用场景
业务回调
访问日志格式说明
媒体文件删除
视频上传
获取截图
SDK参考
上传SDK
IOS版本说明
IOS开发文档
Android版本说明
Android开发文档
播放SDK
IOS版本说明
IOS开发文档
Android版本说明
Android开发文档
WEB端开发文档
拍摄SDK
IOS版本说明
IOS开发文档
Android版本说明
Android开发文档
剪辑SDK
IOS版本说明
IOS开发文档
Android版本说明
Android开发文档
Net SDK
IOS版本说明
IOS开发文档
Android版本说明
Android开发文档
常见问题
常见问题
首页
>
开发者中心
>
云点播
>
SDK参考
>
上传SDK
>
Android开发文档
### Android上传SDK开发文档 ### Android上传SDK简单介绍 智汇云以SDK形式提供上传服务,可以帮助开发者快速上传文件并进行管理。SDK包含jar包、demo及开发文档。 ### 功能说明 系统属性 - Android 4.0及以上 - CPU armeabi-v7a架构(同时兼容armeabi、arm64-v8a、x86、x86_64) 功能列表 - 文件上传 - 日志上传 - 断点续传 - 上传限速 ### 业务流程 ![image](http://p8.qhimg.com/d/inn/cdfef489/t0150df63a7d8e54d11.png) 详细信息请参考:[云存储-用户手册-编程模型](https://live.360.cn/index/doc?type=s3&id=189)。 ### SDK集成 #### 下载SDK sdk下载链接:[https://live.360.cn/index/sdkdownload](https://live.360.cn/index/sdkdownload) - jar - qhvc_tools_sdk.jar - videosdk_upload.jar - so - armeabi-v7a/libtranscore.so demo下载链接:[https://github.com/360livecloud/android_demo.git](https://github.com/360livecloud/android_demo.git) #### 配置说明 将qhvc_tools_sdk.jar、videosdk_upload.jar放到工程libs目录下,在build.gradle中配置: ``` dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') } ``` 将libtranscore.so放到工程src/main/jniLibs/armeabi-v7a/目录下,在build.gradle中配置: ``` android { defaultConfig { ndk { // 设置支持的CPU架构,目前只支持armeabi-v7a架构(该架构兼容armeabi、arm64-v8a、x86、x86_64架构) abiFilters 'armeabi-v7a' } } } ``` 注: 1. 若qhvc_tools_sdk.jar、libtranscore.so已在接入其他模块时引入,请保留高版本,版本号可通过`Stats.getVersion()`获取 2. 若需减小APK体积,请参考#插件化支持# 在build.gradle中配置第三方依赖库: ``` dependencies { compile 'com.squareup.okhttp3:okhttp:3.2.0' } ``` #### 权限配置 ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` #### 混淆规则 ``` -keep class com.qihoo.livecloud.** { <fields>; <methods>; } -keep class com.qihoo.videocloud.** { <fields>; <methods>; } -keep class net.qihoo.videocloud.** { <fields>; <methods>; } ``` #### SDK初始化 需要调用`QHVCSdk.getInstance().init()`,接口说明如下: appId(也叫businessId)是为业务分配的业务ID(appId获取地址:登录[视频云官网](https://zyun.360.cn/)-控制台-SDK-应用管理-新建应用)【见下图】;version为业务端APP的版本号;machineId为设备唯一标识;uid为业务方用户标识,只要保证唯一即可。 ![创建AppId截图](http://p5.qhimg.com/t011da35ea7b6063845.png) [点此查看应用ID](https://zyun.360.cn/console/sdk/application) > 对appId和channelID这两个参数的引入,在设计之初目的是为了每个业务有独立的ID,通过appId来获取云端的一些参数控制,特别是视频缓冲策略、P2P行为、硬解码黑白名单以及解码库类型;channelID更多的为数据统计打点的唯一标注,可以通过云点播和云直播的服务标识来获取,以此获取播放数据反馈。UserID的设计是为了业务方和视频云唯一的沟通桥梁,只要保持唯一即可,一般为用户ID的加密字符串,通过UserID可以排查到一个用户的级别的失败日志; ``` QHVCSdkConfig.Builder builder = new QHVCSdkConfig.Builder(this) .setAppId("businessId") .setAppVersion("version") .setMachineId("machineId") .setUserId("uid"); QHVCSdk.getInstance().init(builder.build()); ``` #### APPID合法性验证 需要调用 `public int validityCheck(String appId, String authorization, long authTime, int randomNum, final QHVCAppAuth.ResultCallback<String> callback)`,接口说明如下: 合法性验证需要用到appId, Access Key(简称AK)和Secret Key(简称SK)。AK、SK获取地址: 登录[视频云官网](https://zyun.360.cn/)-用户中心-秘钥管理【见下图】。 只有appId、Access Key以及Secret Key相匹配,才能通过鉴权,否则将无法正常使用SDK。 ![秘钥获取](http://p2.qhimg.com/t0146c3d44e71ae7a62.png) [点此查看秘钥](https://zyun.360.cn/console/usercenter/accesskey) ==注意:此接口必须在启动APP后120秒内调用,否则将无法正常使用SDK。== appId使用和SDK初始化时同样的内容,callback可以用来监听合法性验证结果。 计算authorization时需要使用AK、SK以及当前系统的时间戳和随机数。 **为了保证AK、SK的安全,请业务接入时,务必把AK和SK存储在服务端,并且把authorization的计算也放在服务端来做。** 计算authorization的示例代码如下: ``` private void videocloudValidCheck() { int randomNum = new Random(100000000).nextInt(); //随机数 long authTime = System.currentTimeMillis() / 1000; //时间戳 (unix时间戳(10位)) //TODO 为了保证ak、sk的安全,请业务接入时,务必把AK和SK存储在服务端,并且把authorization的计算也放在服务端来做。 String authorization = getServerAuthorization(appId, AK, SK, randomNum, authTime); QHVCSdk.getInstance().validityCheck(appId, authorization, authTime, randomNum, new QHVCAppAuth.ResultCallback<String>() { @Override public void onSuccess(String data) { Logger.i(TAG, "validityCheck onSuccess, data: " + data); } @Override public void onFailed(int errCode, String errMsg) { Logger.e(TAG, "validityCheck onFailed, errCode: " + errCode + ", errMsg: " + errMsg); } }); } private String getServerAuthorization(String appID, String ak, String sk, int randNum, long authTime) { HashMap<String, String> mapParams = new HashMap<>(); mapParams.put("appid", appID); String strParams = getParams(mapParams); String paramSign = makeParamSign(strParams, randNum); String authString = ak + "\n" + authTime + "\n" + randNum + "\n" + paramSign; String encryptString = null; try { encryptString = encryptHMAC(authString, sk); } catch (Exception e) { e.printStackTrace(); } Logger.i(TAG, "apiAuth(), encryptString: " + encryptString); return ak + ":" + encryptString; } private String getParams(Map<String, String> mapParams) { String strParams; if (mapParams == null || mapParams.isEmpty()) { strParams = ""; } else { StringBuilder sbParams = new StringBuilder(); Object[] key_arr = mapParams.keySet().toArray(); Arrays.sort(key_arr);/*key升序排列*/ for (Object key : key_arr) { String value = mapParams.get(key); if (!TextUtils.isEmpty(value)) { sbParams.append("&").append(key).append("=").append(value); } } strParams = sbParams.substring(1); } return strParams; } private String makeParamSign(String param, int randNum) { return MD5.encryptMD5(MD5.encryptMD5(param) + randNum); } public String encryptHMAC(String data, String key) throws Exception { final String KEY_MAC = "HmacSHA1"; SecretKey secretKey = new SecretKeySpec(key.getBytes(), KEY_MAC); Mac mac = Mac.getInstance(KEY_MAC); mac.init(secretKey); byte[] rawHmac = mac.doFinal(data.getBytes()); return Base64.encodeToString(rawHmac, Base64.DEFAULT); } ``` 相关错误码: ``` int AUTH_OK = 1; //鉴权成功 int AUTH_FAILED = -11001; //鉴权未通过(鉴权失败) int AUTH_NOT_INVOKED = -11002; //未调用鉴权接口 ``` #### 调试 为便于接入时定位问题,可以在开发版本中打开logcat日志,上传相关的日志TAG为Upload。 ``` DebugUtils debugUtils = new DebugUtils(); debugUtils.setWriteLogs(true); QHVCSdkConfig.Builder builder = new QHVCSdkConfig.Builder(this) .setBusinessId("businessId") .setAppVersion("version") .setUserId("uid"), .setDebugUtils(debugUtils); QHVCSdk.getInstance().init(builder.build()); ``` ### 接口说明 #### 上传文件 用于上传文件,其中token需要由业务请求业务服务端返回,也就是说需要在业务服务端来生成校验token。拿到token后,传给上传SDK,需要注意的是单文件表单上传和分片上传的token获取方式是不一样的。 表单上传的token计算规则见:https://dev.s3.360.cn/doc/page?did=143 分片上传的token计划规则见:https://dev.s3.360.cn/doc/page?did=136 客户端模拟代码可以参考demo。 ```java /** * 上传文件 * * @param file 待上传的文件 * @param token 验证Token * @param config 配置信息 * @param listener 上传结果监听 * @return 返回上传管理器QHVCUploadEvent,使用QHVCUploadEvent.cancel()可以取消当前的上传操作 */ QHVCUpload.uploadFile(File file, String token, QHVCUploadConfig config, OnUploadListener listener); ``` 可以调用`QHVCUpload.getParallel()`接口判断使用单文件表单上传还是分片上传。若该接口返回0,表示使用单文件表单上传;大于0时表示分片上传。 ``` /** * 获取分配上传队列数,用于业务计算token * * @param fileSize 文件大小,单位:字节 * @return 上传使用的队列数为0时表示使用单文件上传,大于0时,表示分配上传的队列数 */ QHVCUpload.getParallel(long fileSize); ``` #### 上传内存数据 ``` /** * 上传内存数据<br> * 注:上传内存数据默认使用的是表单上传,所以建议数据大小不超过1M。 * * @param data 要上传的内存数据 * @param name 存储的文件名字 * @param token 验证Token * @param config 配置信息 * @param listener 上传结果监听 * @return 返回上传管理器QHVCUploadEvent,使用QHVCUploadEvent.cancel()可以取消当前的上传操作 */ QHVCUpload.uploadData(byte[] data, String name, String token, QHVCUploadConfig config, OnUploadListener listener); ``` #### 取消上传 调用`QHVCUploadEvent.cancel()`方法即可,其中QHVCUploadEvent为`QHVCUpload.uploadFile()`或`QHVCUpload.uploadData()`的返回值。 #### 上传日志 智汇云SDK为便于跟踪线上版本问题,提供记录本地日志文件功能,开启后,各功能模块(如推流、播放、上传等)将在本地生成对应的日志文件。若用户遇到问题,业务方可通过以下接口将用户的本地日志文件上传到智汇云日志服务器。 ``` /** * 上传日志 * * @param config 配置信息 * @param listener 上传结果监听 * @return 返回上传管理器UploadEvent,使用UploadEvent可以取消当前的上传操作 */ QHVCUpload.uploadLog(QHVCUploadConfig config, OnUploadListener listener); ``` #### 断点续传 断点续传仅支持分片上传,上传状态、进度等信息需要由业务方自行实现持久化存储。 上传前SDK通过`QHVCRecorder.get()`获取上一次上传的状态等信息,上传过程中会调用`QHVCRecorder.set()`记录当前上传状态等信息,上传结束后或断点续传过期时调用`QHVCRecorder.del()`删除当前上传状态等信息,业务方需要自行实现以上接口。 注意:上传状态等信息以KV形式存储,业务方需要实现`QHVCKeyGenerator.gen()`接口生成待上传文件的唯一KEY(需要保证文件名及文件内容的唯一性)。 ``` /** * 上传文件(支持断点续传) * * @param file 上传的文件 * @param token 验证Token * @param config 配置信息 * @param listener 上传结果监听 * @param recorder 本地持久化存储管理接口 * @param keyGenerator 本地持久化存储KEY生成接口 * @return 返回上传管理器UploadEvent,使用UploadEvent可以取消当前的上传操作 */ QHVCUpload.uploadFile(File file, String token, QHVCUploadConfig config, OnUploadListener listener, QHVCRecorder recorder, QHVCKeyGenerator keyGenerator); ``` ``` /** * 本地持久化存储KEY生成接口 */ public interface QHVCKeyGenerator { /** * 本地持久化存储生成KEY,需要保证文件名及文件内容的唯一性 * * @param file 本地文件 * @return 本地持久化存储KEY */ String gen(File file); } ``` ``` /** * 本地持久化存储管理接口 */ public interface QHVCRecorder { /** * 新建或更新本地持久化存储内容 * * @param key 本地持久化存储KEY,通过{@link QHVCKeyGenerator#gen(File)}生成 * @param data 本地持久化存储内容 */ void set(String key, byte[] data); /** * 获取本地持久化存储内容 * * @param key 本地持久化存储KEY,通过{@link QHVCKeyGenerator#gen(File)}生成 * @return 本地持久化存储内容 */ byte[] get(String key); /** * 删除本地持久化存储内容 * * @param key 本地持久化存储KEY,通过{@link QHVCKeyGenerator#gen(File)}生成 */ void del(String key); } ``` #### 上传限速 为避免上传抢占业务网络带宽,业务方可以设置上传最大速度,通过限速策略避免业务网络请求受影响。 ``` /** * 设置上传的最大速度 * * @param speed 上传的速度,0 表示无限大,不限速。单位kBps 注意是Byte,不是bit */ QHVCUpload.setUploadLimitSpeed(int speed); ``` #### 网络测速 云存储服务一般会提供多个域名,上传SDK会自动测速选择上传速度最快的域名,业务方也可调用以下接口主动测速。 ``` /** * 开始测速 * * @param context 全局上下文 用于监听网络变化 * @param config 配置信息 */ QHVCUpload.startNetworkSpeedTest(Context context, QHVCUploadConfig config); ``` ``` /** * 是否已经完成测速,参见{@link #SPEED_TEST_STATE_UNKOWN}、{@link #SPEED_TEST_STATE_DOING}、{@link #SPEED_TEST_STATE_DONE} * * @return 0:未开始测速,1:测速中,2:完成测速 */ QHVCUpload.getSpeedTestState(); ``` ``` /** * 获取测速排序后的域名列表 * * @return 测速排序后的域名列表 */ QHVCUpload.getSortDomainList(); ``` #### 功能设置 上传默认域名由云控参数确定,业务方可以调用以下接口修改默认上传域名。 ``` /** * 设置默认的域名地址 * * @param defaultDomain 默认域名地址 */ QHVCUpload.setUploadDefaultDomainNames(String defaultDomain); ``` #### 插件化支持 为减小APK体积,上传SDK支持插件化方式接入,业务方仅需接入JAR包即可,不需要捆包带SO文件,最终APK体积预计增加290KB。 插件化基本流程: ![image](http://p2.qhimg.com/d/inn/1fc05675/upload_plugin_flow_chart.jpg) 上传SDK会自动识别APK是否自带插件(即SO库文件),若没有带则后台自动下载并加载插件。插件是否加载完成不影响上传功能。 ### 错误码说明 |状态码|含义| |:--:|:--| |-104|文件为空| |-105|文件不存在| |-108|不支持文件夹| |-109|重试多次(云控次数)后,仍然上传失败| |-110|用户取消上传| |-111|Token为空| |-112|上传的内存数据为空| |-113|上传的文件是0字节| |401|请求签名信息错误| ### 附录 #### QHVCUploadConfig说明 |字段|含义|是否必须|备注| |:--:|:--|:--|:--| |uid|用户唯一标识|否|便于分析定位问题,建议设置| |sid|会话标识|是|每个上传任务为一次会话,标识必须唯一| |cid|调度时使用的channel|否|便于分析定位问题,建议设置| |ver|业务方APP版本号|否|便于分析定位问题,建议设置| |net|网络标识|否|便于分析定位问题,建议设置| |rid|待上传文件路径|否|便于分析定位问题,建议设置| |mid|设备唯一识别码|是|
即刻开始使用
只需完成注册与实名认证,即可体验我们的贴心服务
立即使用
请您联系我们
邮箱
g-zyun@360.cn
电话
4000052360
小安提醒您
试用小安,请确保该账户已通过智汇云实名认证
前往认证中心>>
1对1免费
咨询智汇云专属顾问
为您量身定制产品解决方案
您的姓名 :
手机号 :
公司名称(选填) :
相关产品 :
留言内容 :
需求描述
产品建议
其他
提交
登录后才可以留言哦
立即登录
去注册账号