Azure语音转文字服务启动后立即停止,需实现结果返回至MainViewModel
Azure语音转文字服务启动后立即停止,已修复运行但需返回文本至ViewModel
我尝试将WAV文件转写为文本,但Azure语音转文字服务启动后立即停止。设置了按钮点击调用ConvertToTextAsync方法,本应返回WAV文件的文本内容,但从Debug.WriteLine输出能看到服务启动后立刻打印停止信息。目前已让服务正常运行,但需要将识别出的文本返回至MainViewModel。
初始代码
public List<char> Letters { get; set; } public StringBuilder Builder { get; set; } public AzureTranscriptionService() { Letters = new List<char>(); Builder = new StringBuilder(); } public async Task<string> ConvertToTextAsync( string FilePath, string Language, string WordDocName) { //Configure speech service var config = SpeechConfig.FromSubscription (ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION); config.EnableDictation(); config.SpeechRecognitionLanguage = Language; //Configure speech recognition var stopRecognition = new TaskCompletionSource<string>(); using var audioConfig = AudioConfig.FromWavFileInput (FilePath); { using var speechRecognizer = new SpeechRecognizer(config, audioConfig); speechRecognizer.Recognized += (sender, e) => { if (e.Result.Reason == ResultReason.RecognizedSpeech) { foreach (var c in e.Result.Text) { Letters.Add(c); } } }; speechRecognizer.SessionStarted += (sender, e) => { Debug.WriteLine("------> Started"); }; speechRecognizer.SessionStopped += (sender, e) => { Debug.WriteLine("Stop"); foreach (var item in Letters) { Builder.Append(item); } }; speechRecognizer.Recognizing += (sender, e) => { Debug.WriteLine(e.Result.Text); stopRecognition.TrySetResult(0); }; await speechRecognizer.StartContinuousRecognitionAsync(); // Waits for completion. Use Task.WaitAny to keep the task rooted. await Task.WhenAny(new[] { stopRecognition.Task }); return Builder.ToString(); } }
第一次修改后的代码
private TaskCompletionSource<string>? SpeechRecognitionCompletionSource { get; set; } private StringBuilder? RecognizedSpeechTextBuilder { get; set; } = new StringBuilder(); private SpeechRecognizer? SpeechRecognizer { get; set; } public async Task<string> ConvertToTextAsync(string filePath, string language, string wordDocName) { // Configure speech service var config = SpeechConfig.FromSubscription(ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION); config.EnableDictation(); config.SpeechRecognitionLanguage = language; // Configure speech recognition this.SpeechRecognitionCompletionSource = new TaskCompletionSource<string>(); using var audioConfig = AudioConfig.FromWavFileInput(filePath); using (SpeechRecognizer = new SpeechRecognizer(config, audioConfig)) { SpeechRecognizer.SessionStarted += OnSessionStarted!; SpeechRecognizer.SessionStopped += OnSessionStopped!; SpeechRecognizer.Recognizing += OnRecognizing!; SpeechRecognizer.Recognized += OnRecognized!; await this.SpeechRecognizer.StartContinuousRecognitionAsync(); // Wait for the 'SpeechRecognizer.StopContinuousRecognitionAsync' call // before returning the result string. // In this case, 'SpeechRecognizer.StopContinuousRecognitionAsync' // is called from a Button.Click event handler. return await SpeechRecognitionCompletionSource.Task; } } // Stop speech recognition when the user clicks a button private async void OnStopButtonClicked(object sender, RoutedEventArgs e) { await SpeechRecognizer!.StopContinuousRecognitionAsync(); } private void OnSessionStarted(object sender, SessionEventArgs e) { Debug.WriteLine("------> Started"); } private void OnSessionStopped(object sender, SessionEventArgs e) { Debug.WriteLine("Stop"); SpeechRecognitionCompletionSource!.TrySetResult(RecognizedSpeechTextBuilder!.ToString()); } private void OnRecognizing(object sender, SpeechRecognitionEventArgs e) { Debug.WriteLine(e.Result.Text); } private void OnRecognized(object sender, SpeechRecognitionEventArgs e) { if (e.Result.Reason != ResultReason.RecognizedSpeech) { return; } foreach (var speechText in e.Result.Text) { this.RecognizedSpeechTextBuilder!.Append(speechText); } }
调用ConvertToTextAsync的代码
private async void StartAction(object obj) { IsBusy = true; CanShow = Visibility.Visible; var FileWithoutExtension = Path.GetFileNameWithoutExtension (FilePath); var AudioPath = FolderHelper.CreateFolder(ConstantsHelpers.AUDIO); var DocumentPath = FolderHelper.CreateFolder(); var AudioFileNamePath = Path.Combine(AudioPath, $"{FileWithoutExtension}{ConstantsHelpers.WAV}"); var ConvertedAudioPath = AudioHelper.Converter(FilePath!, AudioFileNamePath); var DocumentName = Path.Combine(DocumentPath, $"{FileWithoutExtension}{ConstantsHelpers.DOCX}"); var res = await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath, SelectedItem, DocumentName); IsBusy = false; StartCommand.RaiseCanExecuteChanged(); CanShow = Visibility.Hidden; }
当前可正常运行但需返回文本的代码
public async Task ConvertToTextAsync(string FilePath, string FileName) { List<char> Characers = new(); StringBuilder builder = new(); //Configure speech service var config = SpeechConfig.FromSubscription (ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION); config.EnableDictation(); //Configure speech recognition var taskCompleteionSource = new TaskCompletionSource<int>(); using var audioConfig = AudioConfig.FromWavFileInput(FilePath); if (!string.IsNullOrEmpty(FileName)) { using var speechRecognizer = new SpeechRecognizer(config, audioConfig); speechRecognizer.Recognized += (sender, e) => { if (e.Result.Reason == ResultReason.RecognizedSpeech) { foreach (var item in e.Result.Text) { Characers.Add(item); } } }; speechRecognizer.SessionStarted += (sender, e) => { Debug.WriteLine("--------> started"); }; speechRecognizer.SessionStopped += (sender, e) => { Debug.WriteLine("-----------> stooped"); foreach (var item in Characers) { builder.Append(item); } Debug.WriteLine(builder.ToString()); }; await speechRecognizer.StartContinuousRecognitionAsync() .ConfigureAwait(false); Task.WaitAny(new[] { taskCompleteionSource.Task }); await speechRecognizer.StopContinuousRecognitionAsync() .ConfigureAwait(false); } return builder.ToString(); }
问题修复与文本返回优化
- 初始代码核心问题:
Recognizing事件中调用stopRecognition.TrySetResult(0)会立刻终止识别流程,导致服务启动后马上停止。 - 当前代码优化点:
- 修正
TaskCompletionSource的使用逻辑:在SessionStopped事件中设置结果,确保识别完成后再返回文本。 - 调整方法返回类型:将
Task改为Task<string>,符合返回文本的需求。 - 替换阻塞调用:用
await Task.WhenAny替代Task.WaitAny,避免线程阻塞问题。
- 修正
优化后的最终代码:
public async Task<string> ConvertToTextAsync(string FilePath, string FileName) { StringBuilder builder = new(); var config = SpeechConfig.FromSubscription(ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION); config.EnableDictation(); var taskCompletionSource = new TaskCompletionSource<string>(); using var audioConfig = AudioConfig.FromWavFileInput(FilePath); if (!string.IsNullOrEmpty(FileName)) { using var speechRecognizer = new SpeechRecognizer(config, audioConfig); speechRecognizer.Recognized += (sender, e) => { if (e.Result.Reason == ResultReason.RecognizedSpeech) { builder.Append(e.Result.Text); } }; speechRecognizer.SessionStarted += (sender, e) => { Debug.WriteLine("--------> started"); }; speechRecognizer.SessionStopped += (sender, e) => { Debug.WriteLine("-----------> stopped"); taskCompletionSource.TrySetResult(builder.ToString()); }; speechRecognizer.Canceled += (sender, e) => { Debug.WriteLine($"识别取消:{e.Reason}"); taskCompletionSource.TrySetResult(builder.ToString()); }; await speechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false); var result = await taskCompletionSource.Task.ConfigureAwait(false); await speechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false); return result; } return string.Empty; }
在MainViewModel的调用处,直接接收返回值即可用于后续处理:
var res = await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath, DocumentName); // 可将res绑定到ViewModel的属性,用于UI展示或写入文档
内容的提问来源于stack exchange,提问作者edu
相关产品推荐
相关产品推荐

