启用连续听写

了解如何在 Windows 应用 SDK 应用中捕获和识别长格式连续听写语音输入。

Important

语音识别需要 MSIX 包标识。 仅当应用在使用包标识的情况下运行时(已打包,或采用外部位置打包),Windows.Media.SpeechRecognition API 才可用。 未打包的应用不能使用这些 API。

关键 API

概述

语音识别中,了解如何使用 RecognizeAsyncRecognizeWithUIAsync识别短语音输入。 对于较长时间的连续语音识别会话(例如听写或电子邮件),请使用 SpeechRecognizerContinuousRecognitionSession 属性来获取 SpeechContinuousRecognitionSession 对象。

注释

听写语言支持取决于应用正在运行的设备。 对于电脑和笔记本电脑,只有 en-US 可以识别听写,而Xbox可以识别语音识别支持的所有语言。 有关详细信息,请参阅 指定语音识别器语言

设置

你的应用需要以下对象来管理连续听写会话:

  • SpeechRecognizer 对象的一个实例。
  • 对 UI 调度程序的引用,用于在听写期间更新 UI。
  • 跟踪用户说出的累积字词的方法。

在页面类中声明一个 SpeechRecognizer 实例和一个 StringBuilder,作为用于累积识别结果的字段:

private SpeechRecognizer speechRecognizer;
private StringBuilder dictatedTextBuilder;

在 WinUI 3 中,可以使用 DispatcherQueue 从后台线程调度 UI 更新(而不是 CoreDispatcher):

// Get the DispatcherQueue for the current thread (UI thread).
private Microsoft.UI.Dispatching.DispatcherQueue dispatcherQueue =
    Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();

初始化

在初始化期间,可以:

  1. 初始化语音识别器。
  2. 编译内置听写语法(或添加自定义约束)。
  3. 为识别事件设置事件侦听器。
// Initialize the speech recognizer.
speechRecognizer = new SpeechRecognizer();

// Compile the default dictation grammar.
SpeechRecognitionCompilationResult result =
    await speechRecognizer.CompileConstraintsAsync();

// Subscribe to continuous recognition events.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
    ContinuousRecognitionSession_ResultGenerated;
speechRecognizer.ContinuousRecognitionSession.Completed +=
    ContinuousRecognitionSession_Completed;
speechRecognizer.HypothesisGenerated +=
    SpeechRecognizer_HypothesisGenerated;

dictatedTextBuilder = new StringBuilder();

处理识别事件

结果已生成

当用户说话时,事件 ResultGenerated 会触发。 识别器会定期传递一部分语音输入。 检查属性 Confidence 以确定是否接受结果。

由于此事件在后台线程上触发,因此请使用 DispatcherQueue.TryEnqueue 更新 UI:

private void ContinuousRecognitionSession_ResultGenerated(
    SpeechContinuousRecognitionSession sender,
    SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
    if (args.Result.Confidence == SpeechRecognitionConfidence.Medium ||
        args.Result.Confidence == SpeechRecognitionConfidence.High)
    {
        dictatedTextBuilder.Append(args.Result.Text + " ");

        dispatcherQueue.TryEnqueue(() =>
        {
            dictationTextBox.Text = dictatedTextBuilder.ToString();
            btnClearText.IsEnabled = true;
        });
    }
}

已完成

Completed 事件指示连续识别会话已结束。 会话在调用 StopAsyncCancelAsync发生错误时或用户停止说话时结束。

private void ContinuousRecognitionSession_Completed(
    SpeechContinuousRecognitionSession sender,
    SpeechContinuousRecognitionCompletedEventArgs args)
{
    if (args.Status != SpeechRecognitionResultStatus.Success)
    {
        dispatcherQueue.TryEnqueue(() =>
        {
            if (args.Status == SpeechRecognitionResultStatus.TimeoutExceeded)
            {
                dictationTextBox.Text = dictatedTextBuilder.ToString();
            }
        });
    }
}

已生成假设

处理事件 HypothesisGenerated 以在识别器仍在处理时显示临时结果。 这通过在最终结果可用之前向用户提供反馈来提高响应能力:

private void SpeechRecognizer_HypothesisGenerated(
    SpeechRecognizer sender,
    SpeechRecognitionHypothesisGeneratedEventArgs args)
{
    string hypothesis = args.Hypothesis.Text;
    string textboxContent = dictatedTextBuilder.ToString() + " " + hypothesis + " ...";

    dispatcherQueue.TryEnqueue(() =>
    {
        dictationTextBox.Text = textboxContent;
        btnClearText.IsEnabled = true;
    });
}

启动和停止识别

在启动或停止会话之前检查识别器状态:

// Start continuous recognition.
if (speechRecognizer.State == SpeechRecognizerState.Idle)
{
    await speechRecognizer.ContinuousRecognitionSession.StartAsync();
}

// Stop continuous recognition (lets pending events complete).
if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
    await speechRecognizer.ContinuousRecognitionSession.StopAsync();
}

若要立即取消并丢弃待处理结果,请调用 CancelAsync,而不要调用 StopAsync

注释

由于多线程,调用 CancelAsync 后,ResultGenerated 事件仍可能会被触发。 如果在取消识别会话时设置专用字段,请始终在 ResultGenerated 处理程序中验证其值。