From f29d33d7e781bc18a6015d6466aa0fa3daa0df25 Mon Sep 17 00:00:00 2001 From: Sultan khan <> Date: Tue, 20 Jun 2023 12:43:44 +0300 Subject: [PATCH] Changes for voice command search --- .../others/floating_button_search.dart | 163 ++++++++++-------- pubspec.yaml | 41 +++-- .../lib/speech_recognition_error.dart | 1 + 3 files changed, 116 insertions(+), 89 deletions(-) diff --git a/lib/widgets/others/floating_button_search.dart b/lib/widgets/others/floating_button_search.dart index 5a571df8..8e5c16b5 100644 --- a/lib/widgets/others/floating_button_search.dart +++ b/lib/widgets/others/floating_button_search.dart @@ -66,8 +66,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_tts/flutter_tts.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -// import 'package:speech_to_text/speech_recognition_error.dart'; -// import 'package:speech_to_text/speech_to_text.dart' as stt; +import 'package:speech_to_text/speech_recognition_error.dart'; +import 'package:speech_to_text/speech_to_text.dart' as stt; +import 'package:speech_to_text/speech_to_text.dart'; import 'package:url_launcher/url_launcher.dart'; class FloatingSearchButton extends StatefulWidget { @@ -83,7 +84,8 @@ class _FloatingSearchButton extends State with TickerProvi RobotProvider eventProvider = RobotProvider(); bool isLoading = false; bool isError = false; - // stt.SpeechToText speech = stt.SpeechToText(); + stt.SpeechToText speech = stt.SpeechToText(); + FlutterTts tts = FlutterTts(); String error = ''; String _currentLocaleId = ""; String lastError; @@ -92,7 +94,6 @@ class _FloatingSearchButton extends State with TickerProvi double minSoundLevel = 50000; double maxSoundLevel = -50000; String reconizedWord = ''; - FlutterTts flutterTts = FlutterTts(); var selectedLang; bool isSearching = false; Map results = {}; @@ -113,7 +114,7 @@ class _FloatingSearchButton extends State with TickerProvi void initState() { controller = AnimationController(vsync: this, duration: Duration(seconds: 1)); offset = Tween(begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0)).animate(controller); - + startIosTts(); if (IS_VOICE_COMMAND_CLOSED == true) { controller.reverse(from: -1); } else { @@ -192,20 +193,20 @@ class _FloatingSearchButton extends State with TickerProvi : Image.asset('assets/images/gif/robot-idle.gif'), ), onTap: () async { - // if (Platform.isAndroid) { - // if (await PermissionService.isMicrophonePermissionEnabled()) { - // new RoboSearch(context: context).showAlertDialog(context); - // initSpeechState().then((value) => {startVoiceSearch()}); - // } else { - // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).recordAudioPermission, () { - // new RoboSearch(context: context).showAlertDialog(context); - // initSpeechState().then((value) => {startVoiceSearch()}); - // }); - // } - // } else { - // new RoboSearch(context: context).showAlertDialog(context); - // initSpeechState().then((value) => {startVoiceSearch()}); - // } + if (Platform.isAndroid) { + if (await PermissionService.isMicrophonePermissionEnabled()) { + new RoboSearch(context: context).showAlertDialog(context); + initSpeechState().then((value) => {startVoiceSearch()}); + } else { + Utils.showPermissionConsentDialog(context, TranslationBase.of(context).recordAudioPermission, () { + new RoboSearch(context: context).showAlertDialog(context); + initSpeechState().then((value) => {startVoiceSearch()}); + }); + } + } else { + new RoboSearch(context: context).showAlertDialog(context); + initSpeechState().then((value) => {startVoiceSearch()}); + } }, ), Positioned( @@ -234,44 +235,60 @@ class _FloatingSearchButton extends State with TickerProvi ])); } - // startVoiceSearch() async { - // bool available = await speech.initialize(onStatus: statusListener, onError: errorListener); - // _currentLocaleId = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); - // - // if (available) { - // speech.listen( - // onResult: resultListener, - // //listenMode: ListenMode.confirmation, - // localeId: _currentLocaleId == 'en' ? 'en_US' : 'ar_SA', - // ); - // } else { - // print("The user has denied the use of speech recognition."); - // } - // // some time later... - // //speech.stop(); - // // speech.listen( - // // onResult: resultListener, - // // listenFor: Duration(seconds: 10), - // // localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', - // // onSoundLevelChange: soundLevelListener, - // // cancelOnError: true, - // // partialResults: true, - // // onDevice: true, - // // listenMode: ListenMode.deviceDefault); - // } + + startIosTts() async{ + await tts.setSharedInstance(true); + await tts.setLanguage("en-US"); + tts.setIosAudioCategory( + IosTextToSpeechAudioCategory.playback, + [IosTextToSpeechAudioCategoryOptions.mixWithOthers], + IosTextToSpeechAudioMode.voicePrompt); + } + startVoiceSearch() async { + bool available = await speech.initialize(); + _currentLocaleId = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + // + // if (available) { + // speech.listen( + // onResult: resultListener, + // //listenMode: ListenMode.confirmation, + // localeId: _currentLocaleId == 'en' ? 'en_US' : 'ar_SA', + // ); + // } else { + // print("The user has denied the use of speech recognition."); + // } + // some time later... + if(available) { + speech.stop(); + speech.listen( + onResult: resultListener, + listenFor: Duration(seconds: 10), + localeId: _currentLocaleId == 'en' ? 'en-US' : 'ar-SA', + onSoundLevelChange: soundLevelListener, + cancelOnError: true, + partialResults: true, + onDevice: true, + listenMode: ListenMode.deviceDefault); + } + } void resultListener(result) { + _stopListening(); reconizedWord = result.recognizedWords; event.setValue({"searchText": reconizedWord}); if (result.finalResult == true) { Future.delayed(const Duration(seconds: 1), () { + _speak(reconizedWord); - RoboSearch.closeAlertDialog(context); + RoboSearch.closeAlertDialog(context); //Navigator.of(context).pop(); }); } } - + void _stopListening() async { + await speech.stop(); + // setState(() {}); + } Future _speak(reconizedWord) async { getPages(reconizedWord); } @@ -315,10 +332,10 @@ class _FloatingSearchButton extends State with TickerProvi // }); } - // void errorListener(SpeechRecognitionError error) { - // event.setValue({"searchText": 'null'}); - // RoboSearch.closeAlertDialog(context); - // } + void errorListener(SpeechRecognitionError error) { + event.setValue({"searchText": 'null'}); + RoboSearch.closeAlertDialog(context); + } void statusListener(String status) { //setState(() { @@ -807,7 +824,7 @@ class _FloatingSearchButton extends State with TickerProvi ); } - speak({isInit}) async { + speak({isInit =false}) async { //if (mounted) { setState(() { this.networkImage = results['AnimationURL']; @@ -817,12 +834,18 @@ class _FloatingSearchButton extends State with TickerProvi if (isInit == true) { event.setValue({"animationEnable": 'true'}); } + + // var voice = await tts.getVoice(); + // print(voice); if (isArabic == false && results['ReturnMessage'] != null && isInit == false) { - await flutterTts.setVoice({"name": "en-au-x-aub-network", "locale": "en-AU"}); - await flutterTts.speak(results['ReturnMessage']); + // await tts.synthesizeToFile("Hello World", Platform.isAndroid ? "tts.wav" : "tts.caf"); + + await tts.setVoice({"name": "Karen", "locale": "en-AU"}); + // await tts.setVoice({"name" : voice[35]["name"],"locale": voice[35]["locale"]}); + await tts.speak(results['ReturnMessage']); } else if (results['ReturnMessage_Ar'] != null && isInit == false) { - await flutterTts.setVoice({"name": "ar-xa-x-ard-network", "locale": "ar"}); - await flutterTts.speak(results['ReturnMessage_Ar']); + //await tts.setVoice({"name" : voice[0]["name"],"locale": voice[0]["locale"]}); + await tts.speak(results['ReturnMessage_Ar']); } stopAnimation(isInit: isInit); @@ -850,7 +873,7 @@ class _FloatingSearchButton extends State with TickerProvi } initialSpeak() async { - await flutterTts.awaitSpeakCompletion(true); + // await flutterTts.awaitSpeakCompletion(true); results = { 'ReturnMessage_Ar': "هذه الخدمة تم تصميمها لتتمكن من ربط الملفات الطبية للعائلة بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي.", 'ReturnMessage': "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file." @@ -875,21 +898,21 @@ class _FloatingSearchButton extends State with TickerProvi }); }); } else { - flutterTts.setCompletionHandler(() async { - event.setValue({"animationEnable": 'false'}); - setState(() { - this.networkImage = null; - this.isAnimationEnable = false; - }); - }); + // tts.setCompletionHandler(() async { + // event.setValue({"animationEnable": 'false'}); + // setState(() { + // this.networkImage = null; + // this.isAnimationEnable = false; + // }); + // }); } - flutterTts.setCompletionHandler(() async { - event.setValue({"animationEnable": 'false'}); - setState(() { - this.networkImage = null; - this.isAnimationEnable = false; - }); - }); + // flutterTts.setCompletionHandler(() async { + // event.setValue({"animationEnable": 'false'}); + // setState(() { + // this.networkImage = null; + // this.isAnimationEnable = false; + // }); + // }); } signOut() async { diff --git a/pubspec.yaml b/pubspec.yaml index a7222ce6..970ebdcc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: diplomaticquarterapp description: A new Flutter application. -version: 4.5.61+1 +version: 4.5.64+1 environment: sdk: ">=2.7.0 <3.0.0" @@ -15,7 +15,7 @@ dependencies: sdk: flutter intl: ^0.17.0 # web view -# webview_flutter: ^2.3.1 + # webview_flutter: ^2.3.1 # http client http: ^0.13.4 @@ -23,7 +23,7 @@ dependencies: async: ^2.8.1 audio_wave: ^0.1.4 -# audio_session: ^0.1.13 + # audio_session: ^0.1.13 # State Management provider: ^6.0.1 @@ -34,7 +34,7 @@ dependencies: health: ^3.0.3 #chart - fl_chart: ^0.40.2 + fl_chart: ^0.45.0 #Camera Preview camera: ^0.10.1 @@ -54,7 +54,7 @@ dependencies: maps_launcher: ^2.0.1 url_launcher: ^6.0.15 shared_preferences: ^2.0.0 -# flutter_flexible_toast: ^0.1.4 + # flutter_flexible_toast: ^0.1.4 fluttertoast: ^8.0.8 firebase_messaging: ^14.1.0 firebase_analytics: ^10.0.5 @@ -98,7 +98,7 @@ dependencies: flutter_polyline_points: ^1.0.0 location: ^4.3.0 # Qr code Scanner -# barcode_scan_fix: ^1.0.2 + # barcode_scan_fix: ^1.0.2 barcode_scan2: ^4.2.2 # Rating Stars @@ -108,7 +108,7 @@ dependencies: syncfusion_flutter_calendar: ^19.3.55 # SVG Images -# flutter_svg: ^0.23.0+1 + # flutter_svg: ^0.23.0+1 #Calendar Events manage_calendar_events: ^2.0.1 @@ -152,7 +152,7 @@ dependencies: #google maps places google_maps_place_picker_mb: ^3.0.0 -# google_maps_place_picker: ^2.1.0-nullsafety.3 + # google_maps_place_picker: ^2.1.0-nullsafety.3 map_launcher: ^1.1.3 #countdown timer for Upcoming List flutter_countdown_timer: ^4.1.0 @@ -161,23 +161,25 @@ dependencies: native_device_orientation: ^1.0.0 wakelock: ^0.5.6 after_layout: ^1.1.0 -# twilio_programmable_video: ^0.11.0+1 + # twilio_programmable_video: ^0.11.0+1 cached_network_image: ^3.1.0+1 -# flutter_tts: -# path: flutter_tts-voice_enhancement - flutter_tts: ^3.6.1 + # flutter_tts: + # path: flutter_tts-voice_enhancement + flutter_tts: ^3.7.0 wifi: ^0.1.5 vibration: ^1.7.3 flutter_nfc_kit: ^3.3.1 -# speech_to_text: ^6.1.1 -# path: speech_to_text + geofencing: ^0.1.0 - in_app_update: ^3.0.0 + speech_to_text: ^6.1.1 + # path: speech_to_text - in_app_review: ^2.0.3 + in_app_update: ^4.0.1 + + in_app_review: ^2.0.6 badges: ^2.0.1 flutter_app_icon_badge: ^2.0.0 @@ -191,7 +193,7 @@ dependencies: carousel_slider: ^4.0.0 flutter_material_pickers: ^3.1.2 flutter_staggered_grid_view: ^0.4.1 -# flutter_hms_gms_availability: ^2.0.0 + # flutter_hms_gms_availability: ^2.0.0 huawei_hmsavailability: ^6.6.0+300 huawei_location: 6.0.0+302 @@ -201,15 +203,16 @@ dependencies: equatable: ^2.0.3 signalr_core: ^1.1.1 wave: ^0.2.0 -# sms_retriever: ^1.0.0 + # sms_retriever: ^1.0.0 sms_otp_auto_verify: ^2.1.0 flutter_ios_voip_kit: ^0.0.5 google_api_availability: ^3.0.1 +# flutter_callkit_incoming: ^1.0.3+3 # firebase_core: 1.12.0 dependency_overrides: provider : ^5.0.0 -# permission_handler : ^10.2.0 + # permission_handler : ^10.2.0 flutter_svg: ^1.0.0 # firebase_messaging_platform_interface: any # flutter_inappwebview: 5.7.2+3 diff --git a/speech_to_text/lib/speech_recognition_error.dart b/speech_to_text/lib/speech_recognition_error.dart index 2ab6cd4d..1b47b0c9 100644 --- a/speech_to_text/lib/speech_recognition_error.dart +++ b/speech_to_text/lib/speech_recognition_error.dart @@ -1,5 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; + part 'speech_recognition_error.g.dart'; /// A single error returned from the underlying speech services.