实现科大讯飞版语音唤醒功能纯净版
首先需要获取唤醒信息:控制台-讯飞开放平台
通过开通唤醒功能,获取测试名额
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下载