阿里雲短視頻 SDK For Android 快速接入
摘要: 近期的一些創意短視頻 App 風靡年輕群體,比較典型的例如抖音、MUSE 等,阿里雲也適時地推出了簡單易用的短視頻 SDK,幫助開發者們以較低的成本快速引入功能完備的創意短視頻功能。本文主要介紹如何快速接入阿里雲短視頻 SDK 的三個版本(基礎版、標準版和專業版)。
前言
近期的一些創意短視頻 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
錯誤,可以參考短視頻安卓常見問題解決。
2. 初始化 SDK
請根據具體的項目情況選擇合適的 SDK 初始化時機,Demo 工程在 Applicatioin 的 onCreate()方法中初始化。
package me.bogerchan.alishortvideodemoimport android.app.Applicationimport 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.Manifestimport android.app.Activityimport android.content.Intentimport android.content.pm.PackageManagerimport android.os.Bundleimport android.support.v4.app.ActivityCompatimport android.support.v7.app.AppCompatActivityimport android.widget.Toastimport com.aliyun.demo.recorder.AliyunVideoRecorderimport com.aliyun.struct.common.VideoQualityimport com.aliyun.struct.snap.AliyunSnapVideoParamimport me.bogerchan.alishortvideodemo.basic.Rclass MainActivity : AppCompatActivity() {
companion object {
val REQUEST_CODE_RECORD_VIDEO = 1
val 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.Applicationimport 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.Manifestimport android.content.pm.PackageManagerimport android.opengl.GLSurfaceViewimport android.os.Bundleimport android.support.v4.app.ActivityCompatimport android.support.v7.app.AppCompatActivityimport android.widget.Toastimport com.aliyun.recorder.AliyunRecorderCreatorimport com.aliyun.struct.recorder.CameraTypeimport com.aliyun.struct.recorder.MediaInfoimport 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.FRONT
override 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 = 800
mediaInfo.videoHeight = 1200
mediaInfo.isHWAutoSize = true
mRecorder.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.Applicationimport 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.Manifestimport android.content.pm.PackageManagerimport android.opengl.GLSurfaceViewimport android.os.Bundleimport android.support.v4.app.ActivityCompatimport android.support.v7.app.AppCompatActivityimport android.widget.Toastimport com.aliyun.recorder.AliyunRecorderCreatorimport com.aliyun.struct.recorder.CameraTypeimport com.aliyun.struct.recorder.MediaInfoimport 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.FRONT
override 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 = 800
mediaInfo.videoHeight = 1200
mediaInfo.isHWAutoSize = true
mRecorder.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 文檔獲取更多的介面信息。如果集成過程中遇到問題,在聯繫客服之前不妨先看下 常見問題解決,說不定你的問題就在裡面。
TAG:雲棲社區 |