You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SpeechToText与flutter_tts的语音助手自监听循环问题排查

Flutter语音助手自录音循环问题解决

需求与问题

需求:

  • 应用启动后持续监听用户语音
  • 实时识别语音并同步展示文本
  • Demo阶段固定回复:You said: $input. This is a dummy response.

问题:用户说话识别正常,但助手回复时会录制自身输出的语音,触发无限循环识别。

期望效果:回复期间暂停监听,语音播放完成后自动恢复监听,确保对话流程正常。


解决方案

核心问题是语音回复时未停止监听,导致TTS输出被重新识别。通过以下调整解决:

  1. 处理用户输入前先停止当前语音监听
  2. 监听TTS播放完成事件,确保播放结束后再重启监听
  3. 同步更新监听状态,避免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),
            ),
          ],
        ),
      ),
    );
  }
}

关键修改说明

  1. 添加_stopListening方法:在处理用户输入前主动停止语音识别,防止录制TTS输出的语音。
  2. TTS完成回调:通过_flutterTts.setCompletionHandler监听播放结束事件,自动重启监听,确保回复后回到等待用户输入的状态。
  3. 状态同步:停止监听时更新_isListening状态,UI会同步显示"Not Listening",回复完成后切换回"Listening...",状态更准确。

内容的提问来源于stack exchange,提问作者Gaurav Gehlot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:47:03