fix: 修复asr 启动就初始化的问题
asrInstance.initialize 这个方法的作用是初始化阿里云 NUI SDK 的 ASR 实例。根据阿里云 SDK 的设计,这个初始化过程不仅仅是加载配置,它还会立即建立与云端的长连接(WebSocket),并进入一个“待命”状态。SDK 会请求打开音频设备。 延迟初始化,只在第一次需要时才进行初始化
This commit is contained in:
@@ -35,13 +35,14 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
private static final String chineseVoice = "zhitian_emo";
|
||||
private static final String englishVoice = "abby";
|
||||
private final NativeNui streamInputTtsInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
|
||||
private final NativeNui asrInstance = new NativeNui();
|
||||
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
///
|
||||
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||
/// when the Flutter Engine is detached from the Activity
|
||||
// asr 是否初始化
|
||||
private boolean isAsrInitialized = false;
|
||||
|
||||
// asr property
|
||||
private MethodChannel channel;
|
||||
// asr instance
|
||||
private final NativeNui asrInstance = new NativeNui();
|
||||
private Handler asrHandler;
|
||||
private AsrCallBack asrCallBack;
|
||||
private Handler handler = new Handler(Looper.getMainLooper());
|
||||
@@ -62,6 +63,21 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
}
|
||||
});
|
||||
|
||||
void initAsrInstance() {
|
||||
if (!isAsrInitialized) {
|
||||
Log.i(TAG, "Initializing ASR for the first time...");
|
||||
asrCallBack = new AsrCallBack(channel);
|
||||
int initResult = asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
||||
Constants.LogLevel.LOG_LEVEL_NONE, false);
|
||||
Log.i(TAG, "ASR initialization result: " + initResult);
|
||||
if (initResult != Constants.NuiResultCode.SUCCESS) {
|
||||
Log.i(TAG, "ASR initialization failed with error code: " + initResult);
|
||||
return;
|
||||
}
|
||||
isAsrInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
|
||||
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL);
|
||||
@@ -69,9 +85,10 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
HandlerThread asrHandlerThread = new HandlerThread("process_thread");
|
||||
asrHandlerThread.start();
|
||||
asrHandler = new Handler(asrHandlerThread.getLooper());
|
||||
asrCallBack = new AsrCallBack(channel);
|
||||
asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
||||
Constants.LogLevel.LOG_LEVEL_NONE, false);
|
||||
// 不能在这里初始化 asr, 初始化之后会占用麦克风
|
||||
// asrCallBack = new AsrCallBack(channel);
|
||||
// asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
||||
// Constants.LogLevel.LOG_LEVEL_NONE, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,6 +98,16 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
ttsAudioTrack.releaseAudioTrack();
|
||||
streamInputTtsInstance.stopStreamInputTts();
|
||||
streamInputTtsInstance.release();
|
||||
|
||||
if (isAsrInitialized) {
|
||||
asrInstance.release();
|
||||
if (asrCallBack != null) {
|
||||
asrCallBack.release();
|
||||
asrCallBack = null;
|
||||
}
|
||||
isAsrInitialized = false;
|
||||
}
|
||||
|
||||
// asrInstance.release();
|
||||
// if (asrCallBack != null) {
|
||||
// asrCallBack.release();
|
||||
@@ -93,6 +120,7 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
Map<String, Object> args = call.arguments();
|
||||
switch (call.method) {
|
||||
case "startTts":
|
||||
assert args != null;
|
||||
Object isChinese = args.get("isChinese");
|
||||
if (isChinese == null || isChinese.toString().isBlank()) {
|
||||
return;
|
||||
@@ -101,6 +129,7 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
result.success(isSuccess);
|
||||
break;
|
||||
case "sendTts":
|
||||
assert args != null;
|
||||
Object textArg = args.get("text");
|
||||
if (textArg == null || textArg.toString().isBlank()) {
|
||||
return;
|
||||
@@ -140,6 +169,9 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||
|
||||
private void startAsr() {
|
||||
asrHandler.post(() -> {
|
||||
// 初始化
|
||||
initAsrInstance();
|
||||
// 启动
|
||||
String setParamsString = genAsrParams();
|
||||
Log.i(TAG, "nui set params " + setParamsString);
|
||||
asrInstance.setParams(setParamsString);
|
||||
|
||||
@@ -18,7 +18,7 @@ import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class AsrCallBack implements INativeNuiCallback {
|
||||
|
||||
private static final String TAG = "AliAsr";
|
||||
private static final String TAG = "AliAsr-Callbask";
|
||||
private final static int ASR_SAMPLE_RATE = 16000;
|
||||
private final static int ASR_WAVE_FRAM_SIZE = 20 * 2 * 1 * ASR_SAMPLE_RATE / 1000; //20ms audio for 16k/16bit/mono
|
||||
private AudioRecord asrAudioRecorder = null;
|
||||
@@ -38,7 +38,7 @@ public class AsrCallBack implements INativeNuiCallback {
|
||||
if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_STARTED) {
|
||||
asrText = "";
|
||||
} else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
|
||||
|
||||
// complete
|
||||
} else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
|
||||
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
||||
JSONObject payload = jsonObject.getJSONObject("payload");
|
||||
|
||||
663
example/android/build/reports/problems/problems-report.html
Normal file
663
example/android/build/reports/problems/problems-report.html
Normal file
File diff suppressed because one or more lines are too long
@@ -67,7 +67,7 @@ void main() async {
|
||||
runApp(const MyApp());
|
||||
|
||||
// AIChatAssistantManager.instance.setWakeWordDetection(true);
|
||||
AIChatAssistantManager.instance.startVoskWakeword();
|
||||
// AIChatAssistantManager.instance.startVoskWakeword();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -60,23 +60,29 @@ class MessageService extends ChangeNotifier {
|
||||
Future<dynamic> _handleMethodCall(MethodCall call) async {
|
||||
switch (call.method) {
|
||||
case "onAsrResult":
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
|
||||
break;
|
||||
{
|
||||
debugPrint("ASR 结果: ${call.arguments}");
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
|
||||
break;
|
||||
}
|
||||
case "onAsrStop":
|
||||
int index = findMessageIndexById(_latestUserMessageId!);
|
||||
if (index == -1) {
|
||||
return;
|
||||
{
|
||||
debugPrint("ASR 停止: ${call.arguments}");
|
||||
int index = findMessageIndexById(_latestUserMessageId!);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
final message = _messages[index];
|
||||
if (message.text.isEmpty) {
|
||||
removeMessageById(_latestUserMessageId!);
|
||||
return;
|
||||
}
|
||||
if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
|
||||
_asrCompleter!.complete(messages.last.text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
final message = _messages[index];
|
||||
if (message.text.isEmpty) {
|
||||
removeMessageById(_latestUserMessageId!);
|
||||
return;
|
||||
}
|
||||
if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
|
||||
_asrCompleter!.complete(messages.last.text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user