android studio开发科大讯飞最新版
实现科大讯飞版语音唤醒功能纯净版
首先需要获取唤醒信息:控制台-讯飞开放平台
通过开通唤醒功能,获取测试名额
1、通过控制台创建新应用: 控制台-讯飞开放平台
2、点击应用,选择语音唤醒(新版)
3、申请装机量(免费10个), 获取对应的APPID, APISecret, APIKey信息
剩下的就是代码开发了,对于一个纯小白,我最大的难点在于SDK工作路径的理解。
我以为这是个固定名称,实际为app的sdk存储路径, 不明白他们为什么不在代码内部直接实现
这里的实际内容是将resource文件夹中的资源 拷贝直 app的sdk文件夹中,已方便使用。
将资源复制到assets下, 然后再将资源拷贝到app的sdk下,封装了一个工具类,对科大讯飞的所有sdk均可用
package com.example.xiaobei;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class AssetCopyUtils {
private static final String TAG = "AssetFolderCopyUtils";
public static void copyAssetFolder(Context context, String assetFolderPath, String destinationFolderPath) {
AssetManager assetManager = context.getAssets();
try {
String[] files = assetManager.list(assetFolderPath);
if (files!= null) {
File destinationFolder = new File(destinationFolderPath);
if (!destinationFolder.exists()) {
if (!destinationFolder.mkdirs()) {
Log.e(TAG, "Failed to create destination folder: " + destinationFolderPath);
return;
}
}
for (String file : files) {
String fullAssetPath = assetFolderPath + File.separator + file;
String fullDestinationPath = destinationFolderPath + File.separator + file;
if (isAssetDirectory(assetManager, fullAssetPath)) {
copyAssetFolder(context, fullAssetPath, fullDestinationPath);
} else {
copyAssetFile(context, fullAssetPath, fullDestinationPath);
}
}
}
} catch (IOException e) {
Log.e(TAG, "Error copying asset folder: " + e.getMessage());
}
}
private static boolean isAssetDirectory(AssetManager assetManager, String assetPath) {
try {
String[] subFiles = assetManager.list(assetPath);
return subFiles!= null && subFiles.length > 0;
} catch (IOException e) {
Log.e(TAG, "Error checking asset directory: " + e.getMessage());
return false;
}
}
private static void copyAssetFile(Context context, String assetPath, String destinationPath) {
AssetManager assetManager = context.getAssets();
try (InputStream in = assetManager.open(assetPath);
OutputStream out = new FileOutputStream(destinationPath)) {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer))!= -1) {
out.write(buffer, 0, read);
}
Log.d(TAG, "Copied asset file: " + assetPath);
} catch (IOException e) {
Log.e(TAG, "Error copying asset file: " + assetPath + " - " + e.getMessage());
}
}
}
剩下的就是对资源的初始化,以及设置回调处理。
我这里没有使用他们demo里的方式,而是获取音频后直接进行唤醒操作,
int read = audioRecord.read(buffer, 0, BUFFER_SIZE);
if (read > 0) {
// 发送 PCM 数据
if (AIKIT_STATUS){
write(buffer, status);
if (status == AiStatus.BEGIN) {
status = AiStatus.CONTINUE;
}
}
else {
// 语音做ASR识别
//sendDataToRecognize(buffer);
Log.d(TAG, "audioRecording......");
}
唤醒词是通过resource中的keyword.txt决定的,如果需要变更,修改即可使用。
通过回调函数,获取唤醒词,并使用阈值进行筛选,以获取自己的唤醒词。
demo下载