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 chineseVoice = "zhitian_emo";
|
||||||
private static final String englishVoice = "abby";
|
private static final String englishVoice = "abby";
|
||||||
private final NativeNui streamInputTtsInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
|
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
|
// asr 是否初始化
|
||||||
///
|
private boolean isAsrInitialized = false;
|
||||||
/// 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 property
|
||||||
private MethodChannel channel;
|
private MethodChannel channel;
|
||||||
|
// asr instance
|
||||||
|
private final NativeNui asrInstance = new NativeNui();
|
||||||
private Handler asrHandler;
|
private Handler asrHandler;
|
||||||
private AsrCallBack asrCallBack;
|
private AsrCallBack asrCallBack;
|
||||||
private Handler handler = new Handler(Looper.getMainLooper());
|
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
|
@Override
|
||||||
public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
|
public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
|
||||||
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL);
|
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL);
|
||||||
@@ -69,9 +85,10 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
|||||||
HandlerThread asrHandlerThread = new HandlerThread("process_thread");
|
HandlerThread asrHandlerThread = new HandlerThread("process_thread");
|
||||||
asrHandlerThread.start();
|
asrHandlerThread.start();
|
||||||
asrHandler = new Handler(asrHandlerThread.getLooper());
|
asrHandler = new Handler(asrHandlerThread.getLooper());
|
||||||
asrCallBack = new AsrCallBack(channel);
|
// 不能在这里初始化 asr, 初始化之后会占用麦克风
|
||||||
asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
// asrCallBack = new AsrCallBack(channel);
|
||||||
Constants.LogLevel.LOG_LEVEL_NONE, false);
|
// asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
||||||
|
// Constants.LogLevel.LOG_LEVEL_NONE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,6 +98,16 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
|||||||
ttsAudioTrack.releaseAudioTrack();
|
ttsAudioTrack.releaseAudioTrack();
|
||||||
streamInputTtsInstance.stopStreamInputTts();
|
streamInputTtsInstance.stopStreamInputTts();
|
||||||
streamInputTtsInstance.release();
|
streamInputTtsInstance.release();
|
||||||
|
|
||||||
|
if (isAsrInitialized) {
|
||||||
|
asrInstance.release();
|
||||||
|
if (asrCallBack != null) {
|
||||||
|
asrCallBack.release();
|
||||||
|
asrCallBack = null;
|
||||||
|
}
|
||||||
|
isAsrInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
// asrInstance.release();
|
// asrInstance.release();
|
||||||
// if (asrCallBack != null) {
|
// if (asrCallBack != null) {
|
||||||
// asrCallBack.release();
|
// asrCallBack.release();
|
||||||
@@ -93,6 +120,7 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
|||||||
Map<String, Object> args = call.arguments();
|
Map<String, Object> args = call.arguments();
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "startTts":
|
case "startTts":
|
||||||
|
assert args != null;
|
||||||
Object isChinese = args.get("isChinese");
|
Object isChinese = args.get("isChinese");
|
||||||
if (isChinese == null || isChinese.toString().isBlank()) {
|
if (isChinese == null || isChinese.toString().isBlank()) {
|
||||||
return;
|
return;
|
||||||
@@ -101,6 +129,7 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
|||||||
result.success(isSuccess);
|
result.success(isSuccess);
|
||||||
break;
|
break;
|
||||||
case "sendTts":
|
case "sendTts":
|
||||||
|
assert args != null;
|
||||||
Object textArg = args.get("text");
|
Object textArg = args.get("text");
|
||||||
if (textArg == null || textArg.toString().isBlank()) {
|
if (textArg == null || textArg.toString().isBlank()) {
|
||||||
return;
|
return;
|
||||||
@@ -140,6 +169,9 @@ public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
|||||||
|
|
||||||
private void startAsr() {
|
private void startAsr() {
|
||||||
asrHandler.post(() -> {
|
asrHandler.post(() -> {
|
||||||
|
// 初始化
|
||||||
|
initAsrInstance();
|
||||||
|
// 启动
|
||||||
String setParamsString = genAsrParams();
|
String setParamsString = genAsrParams();
|
||||||
Log.i(TAG, "nui set params " + setParamsString);
|
Log.i(TAG, "nui set params " + setParamsString);
|
||||||
asrInstance.setParams(setParamsString);
|
asrInstance.setParams(setParamsString);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import io.flutter.plugin.common.MethodChannel;
|
|||||||
|
|
||||||
public class AsrCallBack implements INativeNuiCallback {
|
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_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 final static int ASR_WAVE_FRAM_SIZE = 20 * 2 * 1 * ASR_SAMPLE_RATE / 1000; //20ms audio for 16k/16bit/mono
|
||||||
private AudioRecord asrAudioRecorder = null;
|
private AudioRecord asrAudioRecorder = null;
|
||||||
@@ -38,7 +38,7 @@ public class AsrCallBack implements INativeNuiCallback {
|
|||||||
if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_STARTED) {
|
if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_STARTED) {
|
||||||
asrText = "";
|
asrText = "";
|
||||||
} else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
|
} else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
|
||||||
|
// complete
|
||||||
} else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
|
} else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
|
||||||
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
||||||
JSONObject payload = jsonObject.getJSONObject("payload");
|
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());
|
runApp(const MyApp());
|
||||||
|
|
||||||
// AIChatAssistantManager.instance.setWakeWordDetection(true);
|
// AIChatAssistantManager.instance.setWakeWordDetection(true);
|
||||||
AIChatAssistantManager.instance.startVoskWakeword();
|
// AIChatAssistantManager.instance.startVoskWakeword();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,10 +60,15 @@ class MessageService extends ChangeNotifier {
|
|||||||
Future<dynamic> _handleMethodCall(MethodCall call) async {
|
Future<dynamic> _handleMethodCall(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "onAsrResult":
|
case "onAsrResult":
|
||||||
|
{
|
||||||
|
debugPrint("ASR 结果: ${call.arguments}");
|
||||||
replaceMessage(
|
replaceMessage(
|
||||||
id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
|
id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "onAsrStop":
|
case "onAsrStop":
|
||||||
|
{
|
||||||
|
debugPrint("ASR 停止: ${call.arguments}");
|
||||||
int index = findMessageIndexById(_latestUserMessageId!);
|
int index = findMessageIndexById(_latestUserMessageId!);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return;
|
return;
|
||||||
@@ -79,6 +84,7 @@ class MessageService extends ChangeNotifier {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// final ChatSseService _chatSseService = ChatSseService(PlatformTtsService(aliSdkChannelName));
|
// final ChatSseService _chatSseService = ChatSseService(PlatformTtsService(aliSdkChannelName));
|
||||||
final Service.ChatSseService _chatSseService = Service.ChatSseService();
|
final Service.ChatSseService _chatSseService = Service.ChatSseService();
|
||||||
|
|||||||
Reference in New Issue
Block a user