You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
6.7 KiB
Dart
202 lines
6.7 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:speech_to_text/speech_recognition_error.dart';
|
|
import 'package:speech_to_text/speech_recognition_event.dart';
|
|
import 'package:speech_to_text/speech_recognition_result.dart';
|
|
import 'package:speech_to_text/speech_to_text.dart';
|
|
|
|
/// Simplifies interaction with [SpeechToText] by handling all the callbacks and notifying
|
|
/// listeners as events happen.
|
|
///
|
|
/// Here's an example of using the [SpeechToTextProvider]
|
|
/// ```
|
|
/// var speechProvider = SpeechToTextProvider( SpeechToText());
|
|
/// var available = await speechProvider.initialize();
|
|
/// StreamSubscription<SpeechRecognitionEvent> _subscription;
|
|
/// _subscription = speechProvider.recognitionController.stream.listen((recognitionEvent) {
|
|
/// if (recognitionEvent.eventType == SpeechRecognitionEventType.finalRecognitionEvent ) {
|
|
/// print("I heard: ${recognitionEvent.recognitionResult.recognizedWords}");
|
|
/// }
|
|
/// });
|
|
/// speechProvider.addListener(() {
|
|
/// var words = speechProvider.lastWords;
|
|
/// });
|
|
class SpeechToTextProvider extends ChangeNotifier {
|
|
final StreamController<SpeechRecognitionEvent> _recognitionController =
|
|
StreamController.broadcast();
|
|
final SpeechToText _speechToText;
|
|
SpeechRecognitionResult _lastResult;
|
|
double _lastLevel = 0;
|
|
List<LocaleName> _locales = [];
|
|
LocaleName _systemLocale;
|
|
|
|
/// Only construct one instance in an application.
|
|
///
|
|
/// Do not call `initialize` on the [SpeechToText] that is passed as a parameter, instead
|
|
/// call the [initialize] method on this class.
|
|
SpeechToTextProvider(this._speechToText);
|
|
|
|
Stream<SpeechRecognitionEvent> get stream => _recognitionController.stream;
|
|
|
|
/// Returns the last result received, may be null.
|
|
SpeechRecognitionResult get lastResult => _lastResult;
|
|
|
|
/// Returns the last error received, may be null.
|
|
SpeechRecognitionError get lastError => _speechToText.lastError;
|
|
|
|
/// Returns the last sound level received.
|
|
///
|
|
/// Note this is only available when the `soundLevel` is set to true on
|
|
/// a call to [listen], will be 0 at all other times.
|
|
double get lastLevel => _lastLevel;
|
|
|
|
/// Initializes the provider and the contained [SpeechToText] instance.
|
|
///
|
|
/// Returns true if [SpeechToText] was initialized successful and can now
|
|
/// be used, false otherwse.
|
|
Future<bool> initialize() async {
|
|
if (isAvailable) {
|
|
return isAvailable;
|
|
}
|
|
bool availableBefore = _speechToText.isAvailable;
|
|
bool available =
|
|
await _speechToText.initialize(onStatus: _onStatus, onError: _onError);
|
|
if (available) {
|
|
_locales = [];
|
|
_locales.addAll(await _speechToText.locales());
|
|
_systemLocale = await _speechToText.systemLocale();
|
|
}
|
|
if (availableBefore != available) {
|
|
notifyListeners();
|
|
}
|
|
return available;
|
|
}
|
|
|
|
/// Returns true if the provider has been initialized and can be used to recognize speech.
|
|
bool get isAvailable => _speechToText.isAvailable;
|
|
|
|
/// Returns true if the provider cannot be used to recognize speech, either because it has not
|
|
/// yet been initialized or because initialization failed.
|
|
bool get isNotAvailable => !_speechToText.isAvailable;
|
|
|
|
/// Returns true if [SpeechToText] is listening for new speech.
|
|
bool get isListening => _speechToText.isListening;
|
|
|
|
/// Returns true if [SpeechToText] is not listening for new speech.
|
|
bool get isNotListening => _speechToText.isNotListening;
|
|
|
|
/// Returns true if [SpeechToText] has a previous error.
|
|
bool get hasError => _speechToText.hasError;
|
|
|
|
/// Returns true if [lastResult] has a last result.
|
|
bool get hasResults => null != _lastResult;
|
|
|
|
/// Returns the list of locales that are available on the device for speech recognition.
|
|
List<LocaleName> get locales => _locales;
|
|
|
|
/// Returns the locale that is currently set as active on the device.
|
|
LocaleName get systemLocale => _systemLocale;
|
|
|
|
/// Start listening for new events, set [partialResults] to true to receive interim
|
|
/// recognition results.
|
|
///
|
|
/// [soundLevel] set to true to be notified on changes to the input sound level
|
|
/// on the microphone.
|
|
///
|
|
/// [listenFor] sets the maximum duration that it will listen for, after
|
|
/// that it automatically stops the listen for you.
|
|
///
|
|
/// [pauseFor] sets the maximum duration of a pause in speech with no words
|
|
/// detected, after that it automatically stops the listen for you.
|
|
///
|
|
/// Call this only after a successful [initialize] call
|
|
void listen(
|
|
{bool partialResults = false,
|
|
bool soundLevel = false,
|
|
Duration listenFor,
|
|
Duration pauseFor}) {
|
|
_lastLevel = 0;
|
|
_lastResult = null;
|
|
if (soundLevel) {
|
|
_speechToText.listen(
|
|
partialResults: partialResults,
|
|
listenFor: listenFor,
|
|
pauseFor: pauseFor,
|
|
cancelOnError: true,
|
|
onResult: _onListenResult,
|
|
// onSoundLevelChange: _onSoundLevelChange);
|
|
);
|
|
} else {
|
|
_speechToText.listen(
|
|
partialResults: partialResults,
|
|
listenFor: listenFor,
|
|
pauseFor: pauseFor,
|
|
cancelOnError: true,
|
|
onResult: _onListenResult);
|
|
}
|
|
}
|
|
|
|
/// Stops a current active listening session.
|
|
///
|
|
/// Call this after calling [listen] to stop the recognizer from listening further
|
|
/// and return the current result as final.
|
|
void stop() {
|
|
_speechToText.stop();
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Cancel a current active listening session.
|
|
///
|
|
/// Call this after calling [listen] to stop the recognizer from listening further
|
|
/// and ignore any results recognized so far.
|
|
void cancel() {
|
|
_speechToText.cancel();
|
|
notifyListeners();
|
|
}
|
|
|
|
void _onError(SpeechRecognitionError errorNotification) {
|
|
_recognitionController.add(SpeechRecognitionEvent(
|
|
SpeechRecognitionEventType.errorEvent,
|
|
null,
|
|
errorNotification,
|
|
isListening,
|
|
null));
|
|
notifyListeners();
|
|
}
|
|
|
|
void _onStatus(String status) {
|
|
_recognitionController.add(SpeechRecognitionEvent(
|
|
SpeechRecognitionEventType.statusChangeEvent,
|
|
null,
|
|
null,
|
|
isListening,
|
|
null));
|
|
notifyListeners();
|
|
}
|
|
|
|
void _onListenResult(SpeechRecognitionResult result) {
|
|
_lastResult = result;
|
|
_recognitionController.add(SpeechRecognitionEvent(
|
|
result.finalResult
|
|
? SpeechRecognitionEventType.finalRecognitionEvent
|
|
: SpeechRecognitionEventType.partialRecognitionEvent,
|
|
result,
|
|
null,
|
|
isListening,
|
|
null));
|
|
notifyListeners();
|
|
}
|
|
|
|
// void _onSoundLevelChange(double level) {
|
|
// _lastLevel = level;
|
|
// _recognitionController.add(SpeechRecognitionEvent(
|
|
// SpeechRecognitionEventType.soundLevelChangeEvent,
|
|
// null,
|
|
// null,
|
|
// null,
|
|
// level));
|
|
// notifyListeners();
|
|
// }
|
|
}
|