56 lines
1.6 KiB
Dart
56 lines
1.6 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:speech_to_text/speech_to_text.dart';
|
|
import 'package:mymuseum_visitapp/Services/Glasses/engines/stt_engine.dart';
|
|
|
|
/// STT via speech_to_text — Google on-device (Android) / Apple (iOS).
|
|
/// Gratuit, supporte FR/NL/EN/DE.
|
|
class SpeechToTextSttEngine implements SttEngine {
|
|
final SpeechToText _speech = SpeechToText();
|
|
bool _initialized = false;
|
|
|
|
Future<void> _ensureInitialized() async {
|
|
if (_initialized) return;
|
|
_initialized = await _speech.initialize();
|
|
debugPrint('[SpeechToTextSttEngine] initialized: $_initialized');
|
|
}
|
|
|
|
@override
|
|
Future<String> transcribeOnce({
|
|
required String languageCode,
|
|
Duration timeout = const Duration(seconds: 6),
|
|
}) async {
|
|
await _ensureInitialized();
|
|
if (!_initialized) return '';
|
|
|
|
final completer = Completer<String>();
|
|
String lastResult = '';
|
|
|
|
// Petit délai pour laisser le micro se réinitialiser après le wake word
|
|
await Future.delayed(const Duration(milliseconds: 200));
|
|
|
|
final timer = Timer(timeout, () {
|
|
if (!completer.isCompleted) completer.complete(lastResult);
|
|
});
|
|
|
|
await _speech.listen(
|
|
localeId: languageCode,
|
|
onResult: (result) {
|
|
lastResult = result.recognizedWords;
|
|
if (result.finalResult) {
|
|
timer.cancel();
|
|
if (!completer.isCompleted) completer.complete(lastResult);
|
|
}
|
|
},
|
|
listenOptions: SpeechListenOptions(partialResults: true),
|
|
);
|
|
|
|
return completer.future;
|
|
}
|
|
|
|
@override
|
|
Future<void> cancel() async {
|
|
await _speech.cancel();
|
|
}
|
|
}
|