csdcorp / speech_to_text

A Flutter plugin that exposes device specific text to speech recognition capability.
BSD 3-Clause "New" or "Revised" License
351 stars 218 forks source link

Question: Correct way to restart listener for continuous listening #253

Open itanium21 opened 2 years ago

itanium21 commented 2 years ago

Hi, Could anyone help me with a workaround solution for "continuous" listening? I know that continuous listening as such is not supported with this library, but it seems that it should be possible just to restart the listener after each result/error, e.g. error_no_match, which is raised when no match is found within x seconds.

Here's my code:

void startListening() async {
    print('startListening()');
    speech = stt.SpeechToText();

    bool _available = await speech!.initialize(
      onStatus: (val) => print('onStatus: $val'),
      //onError: (val) => print('onError: $val'),
      onError: (val) => onError(val),
    );
    if (_available) {
      print('startListening() -> _available = true');
      listen();
    } else {
      print('startListening() -> _available = false');
    }
}

void listen() async {
    print('listen()');
    if (speech!.isListening) {
      print('listen() -> isListening = true');
      //await speech!.stop();
      await speech!.cancel(); // Tried with .stop() - no difference
      speech.
      print('speech!.stopPED');
    } else {
      print('listen() -> isListening = false');
    }
    print('speech!.listen()');
    speech!.listen(
        onResult: (val) => onResult(val),
        listenFor: Duration(seconds: 60),
        pauseFor: Duration(seconds: 60)); // Doesn't do anything
}

void onError(SpeechRecognitionError val) async {
    print('onError(): ${val.errorMsg}');
    startListening();
}

void onResult(SpeechRecognitionResult val) async {
    print('onResult()');
    print('val.alternates ${val.alternates}');
    startListening();
}

Seems that restarting of listener works just fine in onResult(), but it doesn't - in onError(), which I'm using to restart listener when "error_no_match" is raised (x seconds of silence).

Console: I/flutter (22431): startListening() I/flutter (22431): startListening() -> _available = true I/flutter (22431): listen() I/flutter (22431): listen() -> isListening = true I/flutter (22431): onStatus: notListening I/flutter (22431): speech!.stopPED I/flutter (22431): speech!.listen() I/flutter (22431): onStatus: listening I/flutter (22431): onError: error_busy I/flutter (22431): startListening() I/flutter (22431): startListening() -> _available = true I/flutter (22431): listen() I/flutter (22431): listen() -> isListening = true I/flutter (22431): onStatus: notListening I/flutter (22431): speech!.stopPED I/flutter (22431): speech!.listen() I/flutter (22431): onStatus: listening I/flutter (22431): onError: error_busy...and so on

sowens-csd commented 2 years ago

The restart should probably happen in response to the new done event in the onStatus listener. After that event all of the OS level resources in use should have been released.

itanium21 commented 2 years ago

done event? From the debugging results attached above it seems that event done is never raised, just:

I/flutter (22431): onStatus: notListening
I/flutter (22431): onStatus: listening
sowens-csd commented 2 years ago

Do you have the 5.0.0 version of the plugin? It's a new state. If you do, and you're not seeing that event, then there's an issue with it.

itanium21 commented 2 years ago

Yes, as it turns out, I was using outdated version 4.2.2. Updated speech_to_text to latest 5.0.0 version and moved restarting to status done.

  void onStatus(String val) {
    print('onStatus: $val');
    if (val == 'done') {
      startListening();
    }
  }

But it works quite odd: After error_no_match speech!.listen() is called, but no actual listening happens.

/flutter (23739): startListening()
I/flutter (23739): startListening() -> _available = true
I/flutter (23739): listen()
I/flutter (23739): listen() -> isListening = false
I/flutter (23739): speech!.listen()
I/flutter (23739): onStatus: listening
I/flutter (23739): onError: error_no_match
I/flutter (23739): onStatus: done
I/flutter (23739): startListening()
I/flutter (23739): startListening() -> _available = true
I/flutter (23739): listen()
I/flutter (23739): listen() -> isListening = false
I/flutter (23739): speech!.listen()

There is silence for some ~60 seconds, during which listening is not active. After this silence listening actually starts (results are processed).

I/flutter (23739): listen() -> isListening = false
I/flutter (23739): speech!.listen()
I/flutter (23739): onResult

P.S. This seems to happen only after error_speech_timeout, because if there is some result, then it works quite flawlessly.

Update: seems that the length of this silence during which speech is not processed is related with pauseFor value, which makes no sense?

[pauseFor] sets the maximum duration of a pause in speech with no words detected, after that it automatically stops the listen for you.

What's more, I'm still getting: I/flutter (27988): onError: error_busy and also something new: I/flutter (27988): onError: error_client From which description I can't tell that much.

sowens-csd commented 2 years ago

Thanks for the detailed findings. This is helpful, and your result is very, very weird. Just to confirm all of this is from Android, correct? What do you have pauseFor set to? Have you tried the same test on iOS?

itanium21 commented 2 years ago

Yes, all these findings were found by using real Android device (Xiaomi Mi9 with latest MIUI 12.5.1). Unfortunately I don't have access to any iOS device, so I can't check anything on it :/ I tried with multiple pauseFor values:

Tried also to reduce it to 0, but it just went in "fail loop": beeped all the time

sowens-csd commented 2 years ago

I've got what I think is a reproduce on this behaviour. There's definitely something odd going on when a timeout happens but I'm not sure what it is yet. Here's the full code of the loop I'm testing:

import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Speech To Text Continuous'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  SpeechToText? speech;
  bool _listenLoop = false;
  String lastHeard = '';
  StringBuffer totalHeard = StringBuffer();

  @override
  void initState() {
    super.initState();
  }

  void startListening({bool forced = false}) async {
    if (forced) {
      setState(() {
        _listenLoop = !_listenLoop;
      });
    }
    if (!_listenLoop) return;
    print('startListening()');
    speech = SpeechToText();

    bool _available = await speech!.initialize(
      onStatus: _onStatus,
      //onError: (val) => print('onError: $val'),
      onError: (val) => onError(val),
    );
    if (_available) {
      print('startListening() -> _available = true');
      await listen();
    } else {
      print('startListening() -> _available = false');
    }
  }

  Future listen() async {
    print('speech!.listen()');
    speech!.listen(
      onResult: (val) => onResult(val),
    ); // Doesn't do anything
  }

  void onError(SpeechRecognitionError val) async {
    print('onError(): ${val.errorMsg}');
    startListening();
  }

  void onResult(SpeechRecognitionResult val) async {
    print('onResult()');
    print('val.alternates ${val.alternates}');
    if (val.finalResult) {
      setState(() {
        lastHeard = val.recognizedWords;
        totalHeard.write(lastHeard);
        totalHeard.write(" ");
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(_listenLoop ? Icons.mic : Icons.mic_external_off),
            Text(
              'You said:',
            ),
            Text(lastHeard),
            Text(
              'Heard so far:',
            ),
            Text(totalHeard.toString()),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => startListening(forced: true),
        tooltip: 'Start listening',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  void _onStatus(String status) {
    if ('done' == status) {
      startListening();
    }
  }
}
sowens-csd commented 2 years ago

I've committed an experimental change to improve this behaviour. If you have a chance and could try it on your device that would be helpful. Here's the code I was testing it with:

import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Speech To Text Continuous'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  SpeechToText? speech;
  bool _listenLoop = false;
  String lastHeard = '';
  StringBuffer totalHeard = StringBuffer();

  void _onStatus(String status) {
    if ('done' == status) {
      print('onStatus(): $status ');
      startListening();
    }
  }

  void startListening({bool forced = false}) async {
    if (forced) {
      setState(() {
        _listenLoop = !_listenLoop;
      });
    }
    if (!_listenLoop) return;
    print('startListening()');
    speech = SpeechToText();

    bool _available = await speech!.initialize(
      onStatus: _onStatus,
      //onError: (val) => print('onError: $val'),
      onError: (val) => onError(val),
      debugLogging: true,
    );
    if (_available) {
      print('startListening() -> _available = true');
      await listen();
    } else {
      print('startListening() -> _available = false');
    }
  }

  Future listen() async {
    print('speech!.listen()');
    speech!.listen(
      onResult: (val) => onResult(val),
    ); // Doesn't do anything
  }

  void onError(SpeechRecognitionError val) async {
    print('onError(): ${val.errorMsg}');
  }

  void onResult(SpeechRecognitionResult val) async {
    print('onResult()');
    print('val.alternates ${val.alternates}');
    if (val.finalResult) {
      setState(() {
        lastHeard = val.recognizedWords;
        totalHeard.write(lastHeard);
        totalHeard.write(" ");
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(_listenLoop ? Icons.mic : Icons.mic_external_off),
            Text(
              'You said:',
            ),
            Text(lastHeard),
            Text(
              'Heard so far:',
            ),
            Text(totalHeard.toString()),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => startListening(forced: true),
        tooltip: 'Start listening',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
juliopuebla commented 2 years ago

Thanks. With your experimental change works great in android and Web (using flutter 2.0.6 for web).

I only added this condition "'notListening' == status"

void _onStatus(String status) { if ('done' == status || 'notListening' == status) { print('onStatus(): $status '); startListening(); } }

itanium21 commented 2 years ago

@sowens-csd, my sincere apologies for such late reply - I somehow missed your comment. I tried the code you added above with the speech_to_text version 5.0.0 (didn't find a way how to use experimental version that contains your latest changes made in SpeechToTextPlugin.kt and speech_to_text.dart). Though, flutter pub upgrade says that there is nothing newer than what I'm using.

With the version I have your code works quite OK if something is recognized: it restarts the listener straight away and next words are listened. That's great.

Though, if nothing is recognized, e.g. I say nothing, then it just stops working:

D/SpeechToTextPlugin(25853): Error 7 after start at 5270 -2.0 / 10.0
I/flutter (25853): onError(): error_no_match
I/flutter (25853): onStatus(): done
I/flutter (25853): startListening()
I/flutter (25853): startListening() -> _available = true
I/flutter (25853): speech!.listen()
sowens-csd commented 2 years ago

Thanks for the response. To try the experimental version you can change the Pubspec reference to refer to GitHub instead of using the version. The syntax looks like:

  speech_to_text:
    git: https://github.com/csdcorp/speech_to_text.git
    ref: main
    path: speech_to_text/
sowens-csd commented 2 years ago

These changes are now live as 5.1.0. Let me know if you have a chance to try it.

itanium21 commented 2 years ago

With speech_to_text: ^5.1.1 and 'if ('done' == status || 'notListening' == status)' ('done' status was not called for some random noise, 'notListening' was, so I added it)

Any chance that sound signal could be turned off for such restarts when nothing is recognized?

sowens-csd commented 2 years ago

Three thumbs up! I'll take it, best review I've had yet. I will have a look as to why done isn't being sent in that case, my goal is that it should always be sent if speech recognition ends.

By sound signal I think you mean the system sounds that play when recognition starts/ends? If so, then no. I haven't found any system supported way to turn those off.

sowens-csd commented 2 years ago

Odd, on my device I am getting done for random noise. What device / OS are you using? Are you getting any error notifications?

itanium21 commented 2 years ago

By sound signal I think you mean the system sounds that play when recognition starts/ends? If so, then no. I haven't found any system supported way to turn those off.

Sad to hear that. Would make a lot of sense for such use-case where listener is repeatedly restarted as long as some supported command is recognized.

About that done status: Xiaomi Mi 9, Android 11 (MIUI 12.5.1.0) From Debug Console (I just did long "shhhh" :D ):

I/flutter (16326): startListening() D/SpeechToTextPlugin(16326): Start initialize D/SpeechToTextPlugin(16326): Checked permission D/SpeechToTextPlugin(16326): has permission, completing D/SpeechToTextPlugin(16326): completeInitialize D/SpeechToTextPlugin(16326): Testing recognition availability D/SpeechToTextPlugin(16326): sending result D/SpeechToTextPlugin(16326): leaving complete D/SpeechToTextPlugin(16326): leaving initializeIfPermitted I/flutter (16326): startListening() -> _available = true I/flutter (16326): speech!.listen() D/SpeechToTextPlugin(16326): Start listening D/SpeechToTextPlugin(16326): setupRecognizerIntent D/SpeechToTextPlugin(16326): Notify status:listening D/SpeechToTextPlugin(16326): Start listening done I/flutter (16326): onStatus(): listening D/SpeechToTextPlugin(16326): rmsDB -2.0 / -2.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / -0.68000007 I/chatty (16326): uid=10009(com.example.quiz_game_new) identical 1 line D/SpeechToTextPlugin(16326): rmsDB -2.0 / -0.68000007 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 2.6799998 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 I/chatty (16326): uid=10009(com.example.quiz_game_new) identical 72 lines D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 I/chatty (16326): uid=10009(com.example.quiz_game_new) identical 2 lines D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 I/chatty (16326): uid=10009(com.example.quiz_game_new) identical 54 lines D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(16326): Error 7 after start at 5115 -2.0 / 10.0 D/SpeechToTextPlugin(16326): Notify status:notListening D/SpeechToTextPlugin(16326): Notify status:doneNoResult I/flutter (16326): onStatus(): notListening I/flutter (16326): onStatus(): notListening -> startListening()

sowens-csd commented 2 years ago

Could you try that same test on that device with the updated example and with the 'Log events' checkbox checked and then post that log? The log you provided above looks exactly like the log I get from an older Android device but I do get the done status update.

itanium21 commented 2 years ago

'Log events' checkbox checked

Sorry, but I didn't understand this part. Searched in Visual Studio Code, searched in Google, but didn't find anything related with flutter.

sowens-csd commented 2 years ago

Sorry! The example app that ships with the plugin speech_to_text/speech_to_text/example/lib/main.dart has a 'Log events' checkbox on it. When checked the app logs every state change, error and result that is receives.

itanium21 commented 2 years ago

Thanks for the clarification! Weird, with example app status 'done' appears all the time, but with code provided by you earlier time to time status 'done' doesn't appear. Will try to understand what's the difference.

itanium21 commented 2 years ago

Took code from example app as a basis and still occasionally it fails - ends with status 'notListening'

Code: ` Future initSpeech({bool forced = false}) async { if (forced) { setState(() { _listenLoop = !_listenLoop; }); } if (!_listenLoop) return; printWithTimestamp('Initialize'); var hasSpeech = await speech.initialize( onError: errorListener, onStatus: statusListener, debugLogging: true, finalTimeout: Duration(milliseconds: 0)); if (hasSpeech) { // Get the list of languages installed on the supporting platform so they // can be displayed in the UI for selection by the user. localeNames = await speech.locales();

  var systemLocale = await speech.systemLocale();
  currentLocaleId = systemLocale?.localeId ?? '';

  startListening();
}

}

void startListening() { printWithTimestamp('start listening'); speech.listen( onResult: resultListener, listenFor: Duration(seconds: 30), pauseFor: Duration(seconds: 5), partialResults: true, localeId: 'en_US', //currentLocaleId, cancelOnError: true, listenMode: ListenMode.confirmation); setState(() {}); }

void errorListener(SpeechRecognitionError error) { printWithTimestamp( 'Received error status: $error, listening: ${speech.isListening}'); }

void statusListener(String status) { printWithTimestamp( 'Received listener status: $status, listening: ${speech.isListening}'); if ('done' == status) { printWithTimestamp('onStatus(): $status -> startListening()'); Timer(Duration(milliseconds: 100), () { initSpeech(); }); } }

void resultListener(SpeechRecognitionResult result) { print( 'Result listener final: ${result.finalResult}, words: ${result.recognizedWords}'); if (result.finalResult) { setState(() { lastHeard = result.recognizedWords; totalHeard.write(lastHeard); totalHeard.write(" "); }); } }`

Log:

I/flutter (11881): 20:44:45.121 - Initialize D/SpeechToTextPlugin(11881): Received extra language broadcast D/SpeechToTextPlugin(11881): Extra supported languages I/flutter (11881): 20:44:45.135 - start listening D/SpeechToTextPlugin(11881): Start listening D/SpeechToTextPlugin(11881): setupRecognizerIntent D/SpeechToTextPlugin(11881): Notify status:listening D/SpeechToTextPlugin(11881): Start listening done I/flutter (11881): 20:44:45.137 - Received listener status: listening, listening: true D/SpeechToTextPlugin(11881): rmsDB -2.0 / -2.0 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 1 line D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 13 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 2 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 13 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Error 8 after start at 1362 -2.0 / 10.0 D/SpeechToTextPlugin(11881): Notify status:notListening D/SpeechToTextPlugin(11881): Notify status:doneNoResult I/flutter (11881): 20:44:46.501 - Received listener status: notListening, listening: false I/flutter (11881): 20:44:46.503 - Received listener status: done, listening: false I/flutter (11881): 20:44:46.504 - onStatus(): done -> startListening() I/flutter (11881): 20:44:46.508 - Received error status: SpeechRecognitionError msg: error_busy, permanent: true, listening: false D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 3 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/flutter (11881): 20:44:46.608 - Initialize D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Received extra language broadcast D/SpeechToTextPlugin(11881): Extra supported languages D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Calling results callback D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/flutter (11881): 20:44:46.654 - start listening D/SpeechToTextPlugin(11881): Start listening D/SpeechToTextPlugin(11881): setupRecognizerIntent D/SpeechToTextPlugin(11881): Notify status:listening D/SpeechToTextPlugin(11881): Start listening done I/flutter (11881): 20:44:46.658 - Result listener final: false, words: I/flutter (11881): 20:44:46.662 - Received listener status: listening, listening: true D/SpeechToTextPlugin(11881): rmsDB 2.3200002 / 2.3200002 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 2.3200002 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 7.12 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 7.6000004 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 7.84 D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 2 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 1 line D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 15 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 15 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Calling results callback I/flutter (11881): 20:44:48.304 - Result listener final: false, words: D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 I/chatty (11881): uid=10009(com.example.quiz_game_new) identical 27 lines D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Stop listening D/SpeechToTextPlugin(11881): Notify status:notListening D/SpeechToTextPlugin(11881): Notify status:done D/SpeechToTextPlugin(11881): Stop listening done I/flutter (11881): 20:44:48.865 - Received listener status: notListening, listening: false D/SpeechToTextPlugin(11881): rmsDB -2.0 / 10.0 D/SpeechToTextPlugin(11881): Calling results callback I/flutter (11881): 20:44:48.901 - Result listener final: false, words: check D/SpeechToTextPlugin(11881): Error 7 after start at 2845 -2.0 / 10.0 I/flutter (11881): 20:44:49.506 - Received error status: SpeechRecognitionError msg: error_no_match, permanent: true, listening: false D/SpeechToTextPlugin(11881): Error 7 after start at 5845 -2.0 / 10.0 I/flutter (11881): 20:44:52.507 - Received error status: SpeechRecognitionError msg: error_no_match, permanent: true, listening: false

searleser97 commented 1 year ago

I posted this solution in StackOverflow which worked perfectly on my Google Pixel 6 Pro device https://stackoverflow.com/a/73597058/13079132

AndreVicencio commented 2 months ago

Hello, Is the continuous listening issue exclusive to flutter? Will continous listening not be an issue if simply using native android?

sowens-csd commented 2 months ago

No, it's not Flutter specific. The plugin is designed around the way the native Android speech recognition library works. You would have more control over how you interact with the speech subsystem if you were developing a native app but the fundamental restrictions would be the same. Android speech is not designed to be used for continuous recognition.