You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}

问题修复与文本返回优化

  1. 初始代码核心问题:Recognizing事件中调用stopRecognition.TrySetResult(0)会立刻终止识别流程,导致服务启动后马上停止。
  2. 当前代码优化点:
    • 修正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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:41:39