我正在使用 Gerald Versluis 方法在 Android 上使用 MAUI 启用语音识别和语音转文本 - https://github.com/jfversluis/MauiSpeechToTextSample
我试图通过将识别文本移动到另一个标签来使其永久化,这样它就不会被新传入的语音覆盖,但我似乎无法访问保存最终处理语音的值。
在RecordButton方法中,包含最终识别语音的值是RecognitionText。来自 MainPage.xaml.cs
private async void RecordButton()
{
var isAuthorized = await speechToText.RequestPermissions();
if (isAuthorized)
{
try
{
RecognitionText = await speechToText.Listen(
System.Globalization.CultureInfo.GetCultureInfo("en-us"),
new Progress<string>(partialText =>
{
RecognitionText = partialText;
OnPropertyChanged(nameof(RecognitionText));
}),
tokenSource.Token);
// When ExtraSpeechInputCompleteSilenceLengthMillis is used, this code is never reached
// When ExtraSpeechInputCompleteSilenceLengthMillis is commented out, this code is reached and everything works great
HistoryText += RecognitionText + Environment.NewLine + Environment.NewLine;
OnPropertyChanged(nameof(HistoryText));
}
catch (Exception ex)
{
await DisplayAlert("Error", ex.ToString(), "OK");
}
}
else
{
await DisplayAlert("Permission Error", "No microphone access", "OK");
}
}
这是 MainPage.xaml 中的 XAML 部分
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border>
<ScrollView Margin="10">
<Label
Grid.Row="0"
x:Name="HistoryLabel"
Text="{Binding HistoryText}"
FontSize="{OnIdiom Phone=Medium, Tablet=Large}" />
</ScrollView>
</Border>
<Label
Grid.Row="1"
x:Name="RecognitionLabel"
Text="{Binding RecognitionText}"
FontSize="{OnIdiom Phone=Medium, Tablet=Large}"
Margin="5"
Padding="5" />
<Button
Grid.Row="2"
CornerRadius="60"
WidthRequest="120"
HeightRequest="120"
Text="Record"
FontSize="24"
FontAttributes="Bold"
Command="{Binding RecordButtonCommand}" />
</Grid>
这是 SpeechToTextImplementation.cs 中的 Listen 方法定义
public async Task<string> Listen(CultureInfo culture, IProgress<string> recognitionResult, CancellationToken cancellationToken)
{
var taskResult = new TaskCompletionSource<string>();
listener = new SpeechRecognitionListener
{
Error = ex => taskResult.TrySetException(new Exception("Failure in speech engine - " + ex)),
PartialResults = sentence =>
{
recognitionResult?.Report(sentence);
},
Results = sentence => taskResult.TrySetResult(sentence)
};
speechRecognizer = SpeechRecognizer.CreateSpeechRecognizer(Android.App.Application.Context);
if (speechRecognizer is null)
throw new ArgumentException("Speech recognizer is not available.");
speechRecognizer.SetRecognitionListener(listener);
speechRecognizer.StartListening(CreateSpeechIntent(culture));
await using (cancellationToken.Register(() =>
{
StopRecording();
taskResult.TrySetCanceled();
}))
{
return await taskResult.Task;
}
}
最后是具有问题意图的 CreateSpeechIntent 方法
private static Intent CreateSpeechIntent(CultureInfo culture)
{
var intent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
intent.PutExtra(RecognizerIntent.ExtraLanguagePreference, Java.Util.Locale.Default);
var javaLocale = Java.Util.Locale.ForLanguageTag(culture.Name);
intent.PutExtra(RecognizerIntent.ExtraLanguage, javaLocale);
intent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
intent.PutExtra(RecognizerIntent.ExtraCallingPackage, Android.App.Application.Context.PackageName);
//-->Problem//intent.PutExtra(RecognizerIntent.ExtraSpeechInputCompleteSilenceLengthMillis, 10000);
//intent.PutExtra(RecognizerIntent.ExtraBiasingStrings, ...) // SCA Use ATC strings!!
//intent.PutExtra(RecognizerIntent.ExtraMaxResults, 1);
//intent.PutExtra(RecognizerIntent.ExtraSpeechInputPossiblyCompleteSilenceLengthMillis, 1500);
//intent.PutExtra(RecognizerIntent.ExtraSpeechInputMinimumLengthMillis, 15000); // SCA Are you done talking? Yes or no. Set right ere.
intent.PutExtra(RecognizerIntent.ExtraPartialResults, true);
return intent;
}
只需使用 MAUI 社区工具包即可轻松解决此问题。 MCT 拥有处理语音处理所需的所有方法。不再需要手动执行此操作。只需使用工具包事件处理程序 SpeechToTextRecognitionResultUpdatedEventArgs。