基于SpeechToText与flutter_tts的语音助手自监听循环问题排查
Flutter语音助手自录音循环问题解决
需求与问题
需求:
- 应用启动后持续监听用户语音
- 实时识别语音并同步展示文本
- Demo阶段固定回复:
You said: $input. This is a dummy response.
问题:用户说话识别正常,但助手回复时会录制自身输出的语音,触发无限循环识别。
期望效果:回复期间暂停监听,语音播放完成后自动恢复监听,确保对话流程正常。
解决方案
核心问题是语音回复时未停止监听,导致TTS输出被重新识别。通过以下调整解决:
- 处理用户输入前先停止当前语音监听
- 监听TTS播放完成事件,确保播放结束后再重启监听
- 同步更新监听状态,避免UI显示异常
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; import 'package:flutter_tts/flutter_tts.dart'; void main() => runApp(VoiceAssistantApp()); class VoiceAssistantApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: VoiceAssistantScreen(), ); } } class VoiceAssistantScreen extends StatefulWidget { @override _VoiceAssistantScreenState createState() => _VoiceAssistantScreenState(); } class _VoiceAssistantScreenState extends State<VoiceAssistantScreen> { stt.SpeechToText _speech = stt.SpeechToText(); FlutterTts _flutterTts = FlutterTts(); bool _isListening = false; String _lastWords = ''; String _response = ''; @override void initState() { super.initState(); // 初始化TTS完成回调 _initTtsHandler(); startListening(); } void _initTtsHandler() { // 设置TTS播放完成回调,播放结束后重启监听 _flutterTts.setCompletionHandler(() { startListening(); }); } void startListening() async { bool available = await _speech.initialize(); if (available) { setState(() => _isListening = true); _speech.listen( onResult: (result) { if (result.finalResult) { setState(() { _lastWords = result.recognizedWords; }); processUserInput(_lastWords); } }, listenFor: Duration(minutes: 5), pauseFor: Duration(seconds: 5), listenOptions: stt.SpeechListenOptions( cancelOnError: false, partialResults: true, onDevice: false, listenMode: stt.ListenMode.confirmation, sampleRate: 0, autoPunctuation: true, enableHapticFeedback: false)); } } void _stopListening() { if (_isListening) { _speech.stop(); setState(() => _isListening = false); } } void processUserInput(String input) { // 先停止监听,避免录制回复语音 _stopListening(); String response = "You said: $input. This is a dummy response."; setState(() { _response = response; }); // 触发语音回复,播放完成后会自动重启监听 speak(response); } Future<void> speak(String text) async { await _flutterTts.speak(text); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Voice Assistant')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( _isListening ? 'Listening...' : 'Not Listening', style: TextStyle(fontSize: 20), ), SizedBox(height: 20), Text( 'You said:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), Text( _lastWords, style: TextStyle(fontSize: 16, color: Colors.blue), ), SizedBox(height: 20), Text( 'Response:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), Text( _response, style: TextStyle(fontSize: 16, color: Colors.green), ), ], ), ), ); } }
关键修改说明
- 添加
_stopListening方法:在处理用户输入前主动停止语音识别,防止录制TTS输出的语音。 - TTS完成回调:通过
_flutterTts.setCompletionHandler监听播放结束事件,自动重启监听,确保回复后回到等待用户输入的状态。 - 状态同步:停止监听时更新
_isListening状态,UI会同步显示"Not Listening",回复完成后切换回"Listening...",状态更准确。
内容的提问来源于stack exchange,提问作者Gaurav Gehlot
相关产品推荐
相关产品推荐

