啟用連續語音輸入

學習如何在 Windows 應用程式 SDK 應用程式中捕捉並辨識長格式、持續的語音輸入。

Important

語音辨識需要 MSIX 套件的識別碼。 Windows.Media.SpeechRecognition這些 API 只有在你的應用程式以套件身份(打包或以外部位置打包)執行時才可用。 未封裝的應用程式無法使用這些 API。

主要 API

概觀

語音辨識中,你會學習如何捕捉並辨識短語音輸入,方法是使用 RecognizeAsyncRecognizeWithUIAsync。 對於較長時間、連續的語音辨識工作階段(例如聽寫或電子郵件),請使用 SpeechRecognizerContinuousRecognitionSession 屬性,以取得 SpeechContinuousRecognitionSession 物件。

備註

語音輸入語言的支援取決於你應用程式執行的裝置。 對於個人電腦和筆記型電腦,只有 en-US 能辨識語音輸入,而 Xbox 則能辨識所有語音辨識支援的語言。 欲了解更多資訊,請參閱 「指定語音識別語言」。

設定

你的應用程式需要以下物件來管理持續的語音輸入工作階段:

  • 一個物件的 SpeechRecognizer 實例。
  • 參考 UI dispatcher,在語音輸入時更新 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 來更新使用者介面:

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 處理常式中驗證這些欄位的值。