初体验-阿里云短视频 SDK For Android 快速接入

摘要: 近期的一些创意短视频 App 风靡年轻群体,比较典型的例如抖音、MUSE 等,阿里云也适时地推出了简单易用的短视频 SDK,帮助开发者们以较低的成本快速引入功能完备的创意短视频功能。本文主要介绍如何快速接入阿里云短视频 SDK 的三个版本(基础版、标准版和专业版)。

点此查看原文:https://yq.aliyun.com/articles/384547?spm=a2c41.11181499.0.0

前言

近期的一些创意短视频 App 风靡年轻群体,比较典型的例如抖音、MUSE 等,阿里云也适时地推出了简单易用的短视频 SDK,帮助开发者们以较低的成本快速引入功能完备的创意短视频功能。

本文主要介绍如何快速接入阿里云短视频 SDK 的三个版本(基础版、标准版和专业版)。帮助开发者以最快的速度了解接入的基本方式。

本文描述的阿里云短视频 SDK 版本基于 3.4.0,后续升级接口变动请参考 阿里云短视频 SDK 文档。
示例工程代码为 Kotlin,Java 接入类似。

正文

由于三个版本接入方式大同小异,本文将着重介绍基础版接入过程,标准版和专业版可以基于基础版方式接入,后续仅说明接入差异的地方。

基础版接入

  1. 引入 aar 以及 so
    目前 aar 平台版本最低要求 >= 4.3,先从SDK 下载页面下载相应版本的 SDK,解压之后,将 libs 文件夹下的 QuSdk-RC.aar 拷到 Android 工程模块中的 libs 文件夹下,将 jniLibs 文件夹下的 armeabi-v7a 文件夹也整体拷贝到 libs 文件夹下。
    拷贝完成之后目录的文件如下:
    图片描述

之后按照如下方式修改 Android 项目工程主模块下的 build.gradle 文件:

Step1. 修改 jniLibs 的源文件夹;

android {sourceSets.main {jniLibs.srcDir "libs"}
}

Step2. 将 libs 文件夹加入仓库中;

repositories {flatDir {dirs 'libs'}
}

Step3. 增加 aar 所需依赖。

dependencies {implementation(name: 'QuSdk-RC', ext: 'aar')implementation 'com.android.support:appcompat-v7:24.2.1'implementation 'com.android.support:design:24.2.1'implementation 'com.google.code.findbugs:jsr305:3.0.0'implementation 'com.github.bumptech.glide:glide:3.7.0'implementation 'pub.devrel:easypermissions:0.2.1'implementation 'com.squareup.okhttp3:okhttp:3.2.0'implementation 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'implementation 'com.squareup.okio:okio:1.12.0'implementation 'com.google.code.gson:gson:2.8.0'}

如果此处遭遇 java.lang.NoSuchFieldError 错误,可以参考短视频安卓常见问题解决。

  1. 初始化 SDK
    请根据具体的项目情况选择合适的 SDK 初始化时机,Demo 工程在 Applicatioin 的 onCreate() 方法中初始化。
package me.bogerchan.alishortvideodemoimport android.app.Application
import com.aliyun.common.httpfinal.QupaiHttpFinal/*** Created by hb.chen on 2018/1/6.*/
class MyApplication : Application() {override fun onCreate() {super.onCreate()System.loadLibrary("QuCore-ThirdParty")System.loadLibrary("QuCore")QupaiHttpFinal.getInstance().initOkHttpFinal()}
}

3. 开始书写你的业务逻辑
经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。

package me.bogerchan.alishortvideodemoimport android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.aliyun.demo.recorder.AliyunVideoRecorder
import com.aliyun.struct.common.VideoQuality
import com.aliyun.struct.snap.AliyunSnapVideoParam
import me.bogerchan.alishortvideodemo.basic.Rclass MainActivity : AppCompatActivity() {companion object {val REQUEST_CODE_RECORD_VIDEO = 1val REQUEST_CODE_FOR_PERMISSION = 2}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)findViewById(R.id.btn_start_record).setOnClickListener {startRecordActivity()}ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO),REQUEST_CODE_FOR_PERMISSION)}private fun startRecordActivity() {val recordParam = AliyunSnapVideoParam.Builder().setResolutionMode(AliyunSnapVideoParam.RESOLUTION_720P).setRatioMode(AliyunSnapVideoParam.RATIO_MODE_9_16).setRecordMode(AliyunSnapVideoParam.RECORD_MODE_AUTO).setNeedClip(true).setMaxDuration(10000).setMinDuration(2000).setVideQuality(VideoQuality.HD).setSortMode(AliyunSnapVideoParam.SORT_MODE_MERGE).build()AliyunVideoRecorder.startRecordForResult(this, REQUEST_CODE_RECORD_VIDEO, recordParam)}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when (requestCode) {REQUEST_CODE_RECORD_VIDEO -> {if (resultCode == Activity.RESULT_OK && data != null) {val type = data.getIntExtra(AliyunVideoRecorder.RESULT_TYPE, 0)if (type == AliyunVideoRecorder.RESULT_TYPE_CROP) {Toast.makeText(this, "类型为裁剪", Toast.LENGTH_SHORT).show()} else if (type == AliyunVideoRecorder.RESULT_TYPE_RECORD) {Toast.makeText(this, "文件路径为 " + data.getStringExtra(AliyunVideoRecorder.OUTPUT_PATH), Toast.LENGTH_SHORT).show()}} else if (resultCode == Activity.RESULT_CANCELED) {Toast.makeText(this, "用户取消录制", Toast.LENGTH_SHORT).show()}}}}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {REQUEST_CODE_FOR_PERMISSION -> {grantResults.forEach {if (it == PackageManager.PERMISSION_DENIED) {Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show()finish()return@forEach}}}}}
}

标准版接入
1. 引入 aar 以及 so
标准版相较于基础版,在引入 so 文件时候多了几个文件,同时 aar 文件名有所变动。最终拷贝结果如下:
图片描述
build.gradle 文件修改与基础版接入一样,只是需要将接入 aar 文件名替换成标准版对应的名字。

2. 初始化 SDK
相较于基础版,需要加载的 so 增多了几个,其中部分 so 文件作为可选功能根据实际情况决定是否加载,具体可以参阅阿里云短视频 SDK 文档。接入后的 Application 文件参考:

package me.bogerchan.alishortvideodemoimport android.app.Application
import com.aliyun.common.httpfinal.QupaiHttpFinal/*** Created by hb.chen on 2018/1/6.*/
class MyApplication : Application() {override fun onCreate() {super.onCreate()System.loadLibrary("aliresample")System.loadLibrary("live-openh264")System.loadLibrary("QuCore-ThirdParty")System.loadLibrary("QuCore")QupaiHttpFinal.getInstance().initOkHttpFinal()}
}

3. 开始书写你的业务逻辑
经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。

package me.bogerchan.alishortvideodemoimport android.Manifest
import android.content.pm.PackageManager
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.aliyun.recorder.AliyunRecorderCreator
import com.aliyun.struct.recorder.CameraType
import com.aliyun.struct.recorder.MediaInfo
import me.bogerchan.alishortvideodemo.std.Rclass MainActivity : AppCompatActivity() {companion object {val REQUEST_CODE_FOR_PERMISSION = 1}private val mRecorder by lazy {AliyunRecorderCreator.getRecorderInstance(this)}private var mCameraType = CameraType.FRONToverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO),REQUEST_CODE_FOR_PERMISSION)initAliyunRecorder()findViewById(R.id.btn_start_record).setOnClickListener {Toast.makeText(this, "开始录制片段", Toast.LENGTH_SHORT).show()mRecorder.startRecording()}findViewById(R.id.btn_stop_record).setOnClickListener {Toast.makeText(this, "停止录制片段", Toast.LENGTH_SHORT).show()mRecorder.stopRecording()}findViewById(R.id.btn_finish_record).setOnClickListener {Toast.makeText(this, "结束录制", Toast.LENGTH_SHORT).show()mRecorder.finishRecording()}findViewById(R.id.btn_change_camera_type).setOnClickListener {Toast.makeText(this, "切换前后置", Toast.LENGTH_SHORT).show()mRecorder.switchCamera()}}override fun onStart() {super.onStart()mRecorder.startPreview()}override fun onPause() {super.onPause()mRecorder.stopPreview()}override fun onDestroy() {super.onDestroy()AliyunRecorderCreator.destroyRecorderInstance()}private fun initAliyunRecorder() {mRecorder.setDisplayView(findViewById(R.id.glsv_content) as GLSurfaceView)val mediaInfo = MediaInfo()mediaInfo.videoWidth = 800mediaInfo.videoHeight = 1200mediaInfo.isHWAutoSize = truemRecorder.setMediaInfo(mediaInfo)mRecorder.setCamera(mCameraType)mRecorder.setOutputPath(externalCacheDir.absolutePath + "/capture.mp4")}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {REQUEST_CODE_FOR_PERMISSION -> {grantResults.forEach {if (it == PackageManager.PERMISSION_DENIED) {Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show()finish()return@forEach}}}}}
}

专业版接入
1. 引入 aar 以及 so
专业版相较于基础版,在引入 so 文件时候多了几个文件,同时 aar 文件名有所变动。最终拷贝结果如下:
图片描述

build.gradle 文件修改与基础版接入一样,只是需要将接入 aar 文件名替换成专业版对应的名字。

2. 初始化 SDK
相较于基础版,需要加载的 so 增多了几个,其中部分 so 文件作为可选功能根据实际情况决定是否加载,具体可以参阅阿里云短视频 SDK 文档。接入后的 Application 文件参考:

package me.bogerchan.alishortvideodemoimport android.app.Application
import com.aliyun.common.httpfinal.QupaiHttpFinal/*** Created by hb.chen on 2018/1/6.*/
class MyApplication : Application() {override fun onCreate() {super.onCreate()System.loadLibrary("live-openh264")System.loadLibrary("QuCore-ThirdParty")System.loadLibrary("QuCore")System.loadLibrary("FaceAREngine")System.loadLibrary("AliFaceAREngine")QupaiHttpFinal.getInstance().initOkHttpFinal()}
}

3. 开始书写你的业务逻辑
经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。

package me.bogerchan.alishortvideodemoimport android.Manifest
import android.content.pm.PackageManager
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.aliyun.recorder.AliyunRecorderCreator
import com.aliyun.struct.recorder.CameraType
import com.aliyun.struct.recorder.MediaInfo
import me.bogerchan.alishortvideodemo.pro.Rclass MainActivity : AppCompatActivity() {companion object {val REQUEST_CODE_FOR_PERMISSION = 1}private val mRecorder by lazy {AliyunRecorderCreator.getRecorderInstance(this)}private var mCameraType = CameraType.FRONToverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO),REQUEST_CODE_FOR_PERMISSION)initAliyunRecorder()findViewById(R.id.btn_start_record).setOnClickListener {Toast.makeText(this, "开始录制片段", Toast.LENGTH_SHORT).show()mRecorder.startRecording()}findViewById(R.id.btn_stop_record).setOnClickListener {Toast.makeText(this, "停止录制片段", Toast.LENGTH_SHORT).show()mRecorder.stopRecording()}findViewById(R.id.btn_finish_record).setOnClickListener {Toast.makeText(this, "结束录制", Toast.LENGTH_SHORT).show()mRecorder.finishRecording()}findViewById(R.id.btn_change_camera_type).setOnClickListener {Toast.makeText(this, "切换前后置", Toast.LENGTH_SHORT).show()mRecorder.switchCamera()}}override fun onStart() {super.onStart()mRecorder.startPreview()}override fun onPause() {super.onPause()mRecorder.stopPreview()}override fun onDestroy() {super.onDestroy()AliyunRecorderCreator.destroyRecorderInstance()}private fun initAliyunRecorder() {mRecorder.setDisplayView(findViewById(R.id.glsv_content) as GLSurfaceView)val mediaInfo = MediaInfo()mediaInfo.videoWidth = 800mediaInfo.videoHeight = 1200mediaInfo.isHWAutoSize = truemRecorder.setMediaInfo(mediaInfo)mRecorder.setCamera(mCameraType)mRecorder.needFaceTrackInternal(true)mRecorder.setOutputPath(externalCacheDir.absolutePath + "/capture.mp4")}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {REQUEST_CODE_FOR_PERMISSION -> {grantResults.forEach {if (it == PackageManager.PERMISSION_DENIED) {Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show()finish()return@forEach}}}}}
}

结语

至此已经介绍完了阿里云短视频 SDK 的接入方法,示例代码展示的仅仅只是阿里云视频 SDK 强大功能的冰山一角,开发者们可以通过相关的 SDK 文档获取更多的接口信息。如果集成过程中遇到问题,在联系客服之前不妨先看下 常见问题解决,说不定你的问题就在里面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/522879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决Chrome插件安装时出现的“程序包无效”问题

https://blog.csdn.net/ysq5202121/article/details/50809494

【 CDN 最佳实践】CDN 命中率优化思路

摘要&#xff1a; CDN 在静态资源的加速场景中是将静态资源缓存在距离客户端较近的CDN 节点上&#xff0c;然后客户端访问该资源即可通过较短的链路直接从缓存中获取资源&#xff0c;而避免再通过较长的链路回源获取静态资源。因此 CDN的缓存命中率的高低直接影响客户体验&…

首帧秒开+智能鉴黄+直播答题,阿里云直播系统背后技术大起底

摘要&#xff1a; 想要快速实现直播能力&#xff0c;并对原有业务不产生任何影响&#xff0c;依托如阿里云一样的直播平台&#xff0c;来搭建移动直播系统&#xff0c;将技术难题交给阿里云&#xff0c;把更多的精力放在核心业务的本身&#xff0c;是最为稳妥和高效的选择。本文…

《云栖社区2017年度内容特辑》新鲜出炉!800+份大会PPT、20+技术专题、100+话题...快抱走!...

回首2017&#xff0c;云栖社区承载了太多的精彩内容&#xff0c;这一年大量的优秀团队入驻社区&#xff0c;600博主成为云栖专家&#xff0c;他们为读者奉献了无数精彩的内容——100W博文&#xff0c;300场直播&#xff0c;用户互动问答数超过6W&#xff1b;与此同时&#xff0…

K8S精华问答 | K8S 是什么?不是什么?

kubernetes&#xff0c;简称K8S&#xff0c;是用8代替8个字符“ubernete”而成的缩写。是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;Kubernetes的目标是让部署容器化的应用简单并且高效&#xff08;powerful&#xff09;,Kubernetes提供了应…

FaaS如何在云2.0时代发挥优势,又将走向何方?

摘要&#xff1a; 过去十年&#xff0c;云服务深刻地改变了社会获取和使用计算能力的方式&#xff0c;云服务自身也以极快的速度演进。在基础设施云化之后&#xff0c;容器、Serverless等技术迅猛发展&#xff0c;开始推动业务能力的云化&#xff0c;云计算进入2.0时代。 点此查…

解锁新姿势 | 如何用配置中心实现全局动态流控?

摘要&#xff1a; 当资源成为瓶颈时&#xff0c;服务框架需要对消费者做限流&#xff0c;启动流控保护机制。流量控制有多种策略&#xff0c;比较常用的有&#xff1a;针对访问速率的静态流控、针对资源占用的动态流控、针对消费者并发连接数的连接控制和针对并行访问数的并发控…

53K!拿下阿里Python岗,这些技术点全考了!

Python又上热搜了&#xff01;”&#xff0c;最近笔者在逛脉脉时&#xff0c;发现这样的一条信息&#xff1a;看完后&#xff0c;我相信大家和我一样&#xff0c;what&#xff0c;Python这么时候值钱了&#xff1f;本篇文章&#xff0c;我将帮大家搞定两大疑问&#xff1a;1. P…

用WEB技术栈开发NATIVE应用:WEEX SDK原理详解

摘要&#xff1a; WEEX依旧采取传统的web开发技术栈进行开发&#xff0c;同时app在终端的运行体验不输native app。其同时解决了开发效率、发版速度以及用户体验三个核心问题。那么WEEX是如何实现的&#xff1f;目前WEEX已经完全开源&#xff0c;并捐给Apache基金会&#xff0c…

什么是java枚举_什么是java枚举

什么是java枚举&#xff1f;java 枚举的定义与用法一、枚举的定义&#xff1a;枚举是一种特殊的数据类型&#xff0c;之所以特殊是因为它既是一种类(class)类型却又比类型多了些特殊的约束&#xff0c;但是这些约束的存在也造就了枚举类型的简洁&#xff0c;安全性以及便捷性。…

基于阿里云Serverless架构下函数计算的最新应用场景详解(一)

摘要&#xff1a; Serverless概念是近年来特别火的一个技术概念&#xff0c;基于这种架构能构建出很多应用场景&#xff0c;适合各行各业&#xff0c;只要对轻计算、高弹性、无状态等场景有诉求的用户都可以通过本文来普及一些基础概念&#xff0c;看看这些场景是否对用户有一些…

浪潮云完成6亿元B轮融资,正推进上市;VMware收购AI初创公司Bitfusion;小爱同学App在苹果应用商店下架……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 华为Mate30 Lite贴膜曝光&am…

基于阿里云Serverless架构下函数计算的最新应用场景详解(二)

摘要&#xff1a; Serverless概念是近年来特别火的一个技术概念&#xff0c;基于这种架构能构建出很多应用场景&#xff0c;适合各行各业&#xff0c;只要对轻计算、高弹性、无状态等场景有诉求的用户都可以通过本文来普及一些基础概念&#xff0c;看看这些场景是否对用户有一些…

增长黑客系列:今天比昨天增长多少?快使用环比函数来分析日志

摘要&#xff1a; 增长黑客系列&#xff1a;今天比昨天增长多少&#xff1f;快使用环比函数来分析日志 在我们平时分析业务时&#xff0c;一个最重要的指标就是&#xff0c;今天比昨天增长多少&#xff0c;本周比上周增长多少&#xff1b;或者同上一个周期相比增长最大的分类是…

云计算将会让数据中心消失?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 王洪鹏出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcould&#xff09;近年来企业应用云化明显&#xff0c;越来越多的企业开始将自己的公司业务转移到云平台之上&#xff0c;可能是迁到公有云&#xff0c;也可能是私有云…

巧用 Img / JavaScript 采集页面数据

摘要&#xff1a; 当我们有一个新内容时&#xff08;例如新功能、新活动、新游戏、新文章&#xff09;&#xff0c;作为运营人员总是迫不及待地希望能尽快传达到用户&#xff0c;因为这是获取用户的第一步、也是最重要的一步。 点此查看原文:http://click.aliyun.com/m/40929/…

时间序列数据的存储和计算 - 开源时序数据库解析

摘要&#xff1a; Prometheus 开源时序数据库解析的系列文章在之前已经完成了几篇&#xff0c;对比分析了Hbase系的OpenTSDB、Cassandra系的KairosDB、BlueFlood及Heroic&#xff0c;最后是tsdb ranking top 1的InfluxDB。 点此查看原文&#xff1a;http://click.aliyun.com/m/…

flowable modler为任务节点增加自定义属性

如何在modler设计器中为任务节点&#xff0c;添加自定义的属性。 文章目录1、modler设计器中所有元素的定义2、flowable如何处理stencilset_bpmn.json文件3、为UserTask任务节点添加一个扩展属性3.1. 添加属性的名称3.2. 为任务节点添加扩展属性3.3. 查看效果1、modler设计器中…

微软对OpenAI投资10亿美元欲开发AI技术;华晨宝马宣布建成全球首个5G汽车生产基地;传苹果将收购英特尔调制解调器芯片业务...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 索尼Xperia 1R信息曝光&…

java se 与j2se_javaSE和 j2SE的区别?

javaSE和 j2SE的区别?关注:71 答案:4 mip版解决时间 2021-01-28 18:29提问者耍硪ミ倪配么2021-01-27 20:19javaSE和 j2SE的区别?最佳答案二级知识专家自然卷的气质2021-01-27 21:53JavaEE 比 se多了许多包&#xff0c;用于开发大规模的&#xff0c;分布式的Java应用/服务器…