-
Notifications
You must be signed in to change notification settings - Fork 493
Expand file tree
/
Copy pathOfflineSpeechToTextViewModel.cs
More file actions
108 lines (86 loc) · 3.19 KB
/
OfflineSpeechToTextViewModel.cs
File metadata and controls
108 lines (86 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System.Globalization;
using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Maui.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace CommunityToolkit.Maui.Sample.ViewModels.Essentials;
public partial class OfflineSpeechToTextViewModel : BaseViewModel
{
readonly ISpeechToText speechToText;
public OfflineSpeechToTextViewModel()
{
// For demo purposes. You can resolve dependency from the DI container,
speechToText = OfflineSpeechToText.Default;
speechToText.StateChanged += HandleSpeechToTextStateChanged;
speechToText.RecognitionResultUpdated += HandleRecognitionResultUpdated;
speechToText.RecognitionResultCompleted += HandleRecognitionResultCompleted;
}
public SpeechToTextState? State => speechToText.CurrentState;
[ObservableProperty]
public partial string? RecognitionText { get; set; } = "Welcome to .NET MAUI Community Toolkit!";
[ObservableProperty, NotifyCanExecuteChangedFor(nameof(StartListenCommand))]
public partial bool CanStartListenExecute { get; set; } = true;
[ObservableProperty, NotifyCanExecuteChangedFor(nameof(StopListenCommand))]
public partial bool CanStopListenExecute { get; set; } = false;
static async Task<bool> ArePermissionsGranted(ISpeechToText speechToText)
{
var microphonePermissionStatus = await Permissions.RequestAsync<Permissions.Microphone>();
var isSpeechToTextRequestPermissionsGranted = await speechToText.RequestPermissions(CancellationToken.None);
return microphonePermissionStatus is PermissionStatus.Granted
&& isSpeechToTextRequestPermissionsGranted;
}
[RelayCommand(CanExecute = nameof(CanStartListenExecute))]
async Task StartListen(CancellationToken token)
{
CanStartListenExecute = false;
CanStopListenExecute = true;
var isGranted = await ArePermissionsGranted(speechToText);
if (!isGranted)
{
await Toast.Make("Permission not granted").Show(token);
CanStartListenExecute = true;
CanStopListenExecute = false;
return;
}
const string beginSpeakingPrompt = "Begin speaking...";
RecognitionText = beginSpeakingPrompt;
try
{
await speechToText.StartListenAsync(new SpeechToTextOptions
{
AutoStopSilenceTimeout = TimeSpan.FromSeconds(5),
Culture = CultureInfo.CurrentCulture,
ShouldReportPartialResults = true
}, token);
if (RecognitionText is beginSpeakingPrompt)
{
RecognitionText = string.Empty;
}
}
catch
{
CanStartListenExecute = true;
CanStopListenExecute = false;
throw;
}
}
[RelayCommand(CanExecute = nameof(CanStopListenExecute))]
Task StopListen(CancellationToken token)
{
CanStartListenExecute = true;
CanStopListenExecute = false;
return speechToText.StopListenAsync(token);
}
void HandleRecognitionResultUpdated(object? sender, SpeechToTextRecognitionResultUpdatedEventArgs e)
{
RecognitionText += e.RecognitionResult;
}
void HandleRecognitionResultCompleted(object? sender, SpeechToTextRecognitionResultCompletedEventArgs e)
{
RecognitionText = e.RecognitionResult.IsSuccessful ? e.RecognitionResult.Text : e.RecognitionResult.Exception.Message;
}
void HandleSpeechToTextStateChanged(object? sender, SpeechToTextStateChangedEventArgs e)
{
OnPropertyChanged(nameof(State));
}
}