1、介绍
总览
音频编辑服务(Audio Editor Kit)是帮助开发者快速构建各类应用音频能力的服务。在本codelab中,您将学会创建一个Demo Project,了解如何使用音频编辑服务实现音源分离、合成分离的音频源的功能。
您将建立什么
在本codelab中,您将构建APP实现编辑并从音乐中删除音频。
您将学会什么
在本codelab中,你需要学习:
1、从视频中提取音源。
2、实现音源分离,提取乐器声音。
3、合成音频。
4、导出音频文件
2、您需要什么
硬件需求
-
安装了Android Studio并已连接到互联网的计算机。
-
华为或安卓手机(带USB线)。
-
手机用于运行和调试demo
软件需求
-
JDK版本:1.8.211或以上
-
Android(API版本21或以上)
-
HMS Core (APK) 6.0.0.300或以上
-
Android Studio版本:3.6.1或以上
-
华为手机:EMUI 5.0版本或以上;非华为手机:Android 5.0或以上。
3、集成前准备
如果您需要正式发布集成音频编辑服务的APP,请参考HUAWEI HMS Core集成准备章节,为集成做好准备。本代codelab提供的示例代码已完成为您准备的工作。如果使用示例代码,则可以跳过此步骤。
在准备集成HUAWEI HMS Core之前,您需要先注册开发者帐号并完成实名认证。详细信息,请参考注册认证。
4、开发Demo应用
在本节中,您将构建一个Demo,以了解如何将视频转换为音频文件,并使用音频编辑服务分离其音频源。
新建工程
1)创建一个Android项目,将FileUtils.kt和PermissionUtil.kt文件拷贝到“src\main\java\com\example\myapplication\util”目录下。
2)创建包和类,如下所示。
说明:将“FileUtils.kt”和“PermissionUtil.kt”复制到您的项目后,请检查文件中指定的包名是否与您的项目包名相同。如果不同,请将其更改为您的项目包名称。
3)将res目录下的所有资源文件复制到项目的“src\main\res”目录下。
说明:xml是一个新的空目录。
配置HMS Core SDK的Maven仓地址
Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle插件版本,选择对应的配置过程。
说明:Maven仓地址无法直接在浏览器中打开访问,只能在IDE中配置。如需添加多个Maven代码库,请将华为公司的Maven仓地址配置在最后。
1)7.0以下版本
a.打开Android Studio项目级“build.gradle”文件。
b.添加HUAWEI AGC插件以及Maven代码库。
①在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
②在“allprojects > repositories”中配置HMS Core SDK的Maven仓地址。
③如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加AGC插件配置。
buildscript {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
...
// Add the AppGallery Connect plugin configuration. Please refer to AppGallery Connect Plugin Dependency to select a proper plugin version.
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
allprojects {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
}
2)7.0版本
a.打开Android Studio项目级“build.gradle”文件。
b.添加HUAWEI AGC插件以及Maven代码库。
①在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
②如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加AGC插件和Android Gradle插件配置。
buildscript {
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
...
// Add the Android Gradle plugin configuration. You need to replace {version} with the actual Gradle plugin version, for example, 7.0.1.
classpath 'com.android.tools.build:gradle:{version}'
// Add the AppGallery Connect plugin configuration. Please refer to AppGallery Connect Plugin Dependency to select a proper plugin version.
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
c.打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。
dependencyResolutionManagement {
...
repositories {
google()
jcenter()
// Configure the Maven repository address for the HMS Core SDK.
maven {url 'https://developer.huawei.com/repo/'}
}
}
3)7.1及以上版本
a.打开Android Studio项目级“build.gradle”文件。
b.如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加AGC插件和Android Gradle插件配置。
buildscript {
dependencies {
...
// Add the Android Gradle plugin configuration. You need to replace {version} with the actual Gradle plugin version, for example, 7.1.1.
classpath 'com.android.tools.build:gradle:{version}'
// Add the AppGallery Connect plugin configuration. Please refer to AppGallery Connect Plugin Dependency to select a proper plugin version.
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
c.打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。
pluginManagement {
repositories {
gradlePluginPortal()
google() 添加编译依赖
mavenCentral()
// Configure the Maven repository address for the HMS Core SDK.
maven { url 'https://developer.huawei.com/repo/' }
}
}
dependencyResolutionManagement {
...
repositories {
google()
mavenCentral()
// Configure the Maven repository address for the HMS Core SDK.
maven { url 'https://developer.huawei.com/repo/' }
}
}
添加编译依赖
1)打开应用级的“build.gradle”文件。
2)添加Java版本配置。
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
3)在dependencies代码段中添加如下编译依赖。
dependencies {
implementation 'com.huawei.hms:audio-editor-sdk:1.5.0.301'
}
说明:如果需要添加其他依赖,请按照上述格式将其添加到依赖块中。
示例:
说明:
-
将{version}替换为实际的SDK版本号,例如:1.5.0.301。具体操作请参见版本变更记录。
-
minSdkVersion:21或以上
-
将“API Key”添加到“buildTypes”中。“API Key”可以在“appgallery_connect.json”文件中找到。
配置AndroidManifest.xml文件
Nearby Connection开发前,需要添加特定的权限到“AndroidManifest.xml”。
权限添加位置与标签“application”同级。示例代码如下:
<!-- Vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Microphone -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- Write into storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Read from storage -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Connect to Internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Obtain the network status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Obtain the changed network connectivity state -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-
ACCESS_FINE_LOCATION、WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE是危险的系统权限。您需要通过本项目提供的PermissionUtil类的launchMultiplePermission,在“HomeActivity”中动态申请这些权限。如果权限不足,音频编辑服务将会由于缺少必需权限无法开启广播或者扫描。
-
Android 10及以上版本的设备默认只允许应用访问外部存储的私有目录。如果您尝试访问外部存储的其他目录,将抛出异常FileNotFoundException。因此,您需要在“AndroidManifest.xml”文件中的“application”元素下面设置“requestLegacyExternalStorage="true"”。示例代码如下:
同步工程
点击“File > Sync Project with Gradle Files”同步工程。
如果显示“successful”,则表示同步成功,如下图所示。
音频提取-视频到音频
现在我们可以开始集成音频提取了。函数“extractAudio”可以从获取HAEAudioExpansion实例调用,如下所示。此函数采用5个参数:上下文(context)、视频源路径(videoPath)、输出路径(exportPath)、提取音频文件的名称(txtVideoName)和音频提取回调结果(AudioExtractCallBack),帮助您跟踪提取过程的进度与提取步骤。
binding.imgVideoEdit.setOnClickListener { val intent = Intent()
intent.type = "video/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(
Intent.createChooser(intent, "Select Video"),
REQUEST_TAKE_GALLERY_VIDEO
)
}
binding.btnExtraction.setOnClickListener {
exportPath = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
.toString() + File.separator + "SeparateAudioCodelab" + File.separator
)
if(!exportPath.exists()) exportPath.mkdir()
if(videoPath!=""){
HAEAudioExpansion.getInstance().extractAudio(
context,
videoPath,
exportPath.toString(),
binding.txtVideoName.text.toString(),
object : AudioExtractCallBack {
override fun onSuccess(audioPath: String) {
showDialog()
}
override fun onProgress(progress: Int) {
//Runs on progress
}
override fun onFail(errCode: Int) {
if(errCode==1006){
Toast.makeText(context,"File already exist",Toast.LENGTH_LONG).show()
}
}
override fun onCancel() {
//Runs on when process canceled
}
}) }
}
提取完成后,我们可以在分离页面上使用提取的音频文件分离其音频源。
音源分离
提取后,用户将被导航到分离页面。在此页面上,有一个可以与音频文件分离的源列表,我们将从“HAEAudioSeparationFile”实例中收集源列表。在这个过程中,所有源或其中的少数源都可以分离。“HAEAudioSeparationFile”采用一个源列表来设置分离哪些音频源,分离过程有4个参数:音频路径(filePath)、导出路径(folderPath)、创建的文件名(fileName)和分离结果回调(AudioSeparationCallBack)。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
haeAudioSeparationFile = HAEAudioSeparationFile()
private fun getInstruments() {
haeAudioSeparationFile.getInstruments(object :
SeparationCloudCallBack<List<SeparationBean?>?> {
override fun onFinish(response: List<SeparationBean>) {
for (separationBean in response) {
instruments.add(Instrument(separationBean.instrument, separationBean.desc,""))
}
rvAdapter.setItems(instruments)
}
override fun one rror(errorCode: Int) {
//Runs when when error occurred
}
})
}
private fun separateAudio() {
haeAudioSeparationFile.setInstruments(selectedInstruments.map { it.name })
binding.layoutSeparationFragment.visibility = View.VISIBLE
binding.layoutSeparationFragment.bringToFront()
val instrumentsToCompose = arrayListOf<Instrument>()
var doneTaskCount = 0
binding.txtSeparationProcess.text = "${doneTaskCount}/${selectedInstruments.size}"
haeAudioSeparationFile.startSeparationTasks(
filePath,
folderPath,
fileName,
object : AudioSeparationCallBack {
override fun onResult(separationBean: SeparationBean) {
activity?.runOnUiThread {
binding.txtSeparationProcess.text =
"${++doneTaskCount}/${selectedInstruments.size}"
}
separationBean.apply { instrumentsToCompose.add(Instrument(this.instrument,this.desc,this.outAudioPath)) }
}
override fun onFinish(separationBeans: List<SeparationBean>) {
activity?.runOnUiThread {
binding.layoutSeparationFragment.visibility = View.GONE
binding.btnSeparate.isClickable = true
val action = SeparationFragmentDirections.actionSeparationFragmentToComposeFragment(instrumentsToCompose.toList().toTypedArray(),folderPath)
findNavController().navigate(action)
}
}
override fun onFail(errorCode: Int) {
//Runs when process failed
}
override fun onCancel() {
//Runs when process canceled
}
})
}
分离过程可能需要几分钟。在这个过程之后,我们可以导航到第三个页面,即编辑页面。
合成音频文件
此页面设计类似于分离页面。但是包含音频源的列表只包含上一页上的分离源。用户可以选择这些源,并将它们合成到新的音频文件中。要合成这些音频文件,我们需要一个
“HuaweiAudioEditor”实例。我们将使用“appendAudioAsset”函数将所有要合成的路径添加到此实例中。要创建最终文件,我们需要使用音频编辑器服务的导出音频功能。
fileName = binding.txtComposeName.text.toString()
val mEditor = HuaweiAudioEditor.create(context)
mEditor.initEnvironment()
val mTimeLine = mEditor.timeLine
for(instrument in selectedInstruments){
mTimeLine.appendAudioLane().appendAudioAsset(instrument.filePath,mTimeLine.currentTime)
}
val path = exportPath+ File.separator+ fileName + ".mp3"
val exportAudioCallback: ExportAudioCallback = object : ExportAudioCallback {
override fun onCompileProgress(time: Long, duration: Long) {
//Runs on progress
}
override fun onCompileFinished() {
activity?.runOnUiThread{
binding.processCompose.visibility = View.INVISIBLE
binding.txtSelectInstruments.text = getString(R.string.select_instruments)
Toast.makeText(context,"DONE",Toast.LENGTH_LONG)
}
}
override fun onCompileFailed(errCode: Int, errorMsg: String) {
//Runs when process failed
}
}
HuaweiAudioEditor.getInstance().setExportAudioCallback(exportAudioCallback)
val audioProperty = HAEAudioProperty()
audioProperty.encodeFormat = Constants.AV_CODEC_ID_MP3
audioProperty.sampleRate = Constants.SAMPLE_RATE_44100
audioProperty.channels = 2 HuaweiAudioEditor.getInstance().exportAudio(audioProperty, path)
5、测试Demo
完成上述步骤后,编译演示。
演示构建完成后,会生成APK文件。安装在华为手机上,调试并运行。
a.初始屏幕
以上是在手机上运行的APP的截图。
APP提供以下两个按钮:
1)提取音频:打开文件选择器,选择要提取的视频。
2)分离音频:引导到页面,将音频源与文件分离。
b.音频提取
选择要提取的视频后
1)点击提取音频。
2)提取完成后,将出现分离页。
c.音源分离
1)选择要与音频文件分离的乐器。
2)点击分离音频,以启动音源分类离过程。
d.音频源合成
1)选择要作曲的乐器。
2)点击合成声音,以启动合成过程。
6、恭喜您
祝贺您,您已经成功完成本codelab并学到了:
-
构建Demo App,并将HMS Core Audio Editor SDK集成到APP中。
-
现在,使用HMS Core音频编辑服务来实现您的创意吧。
7、参考文件
更多信息,请点击以下链接:
下载示例代码,请点击以下链接:
标签:Core,音频,音源,HMS,Maven,fun,Android From: https://www.cnblogs.com/developer-huawei/p/17129068.html