體驗 Microsoft Azure 語音服務(C#)
一、 什麼是語音辨識:
語音辨識 (speech recognition) 技術,也被稱為自動語音辨識、
電腦語音識別或是語音轉文字識別,
其目標是以電腦自動將人類的語音內容轉換為相應的文字。
二、 Microsoft Azure 語音服務:
語音服務會將語音轉文字、文字轉語音及語音翻譯,
整合至單一 Azure 訂用帳戶。
藉由語音 SDK、語音裝置 SDK 或 REST API,
可輕易地透過語音來啟用您的應用程式、工具和裝置。
三、 使用語音服務前準備(.Net Core):
1. .NET Core SDK
2. Visual Studio 2017 或更新版本
3. 語音服務的 Azure 訂用帳戶金鑰
四、 使用語音服務(.Net Core 主控台應用程式):
1. 取得 Azure 訂用帳戶金鑰
參考 免費試用語音服務 取得帳戶金鑰
2. 啟動 Visual Studio 並建立 主控台應用程式 專案,並修改名稱為
SpeechRecognitionSample
3. 在方案 SpeechRecognitionSample 點選滑鼠右鍵,
點選 [加入] -> 新增專案
建立類別庫專案(.NET Core),名稱叫做 Interfaces ,點選確定
在專案Interfaces點選滑鼠右鍵,點選滑鼠右鍵,點選 [加入] -> 新增資料夾
修改 資料夾名稱為 BusinessModels,
建立 RecognizeBM類別,設定屬性
using System;
using System.Collections.Generic;
using System.Text;
namespace Interfaces
{
/// <summary>
/// 語音辨識基本設定用 BM
/// </summary>
public class RecognizeBM
{
/// <summary>
/// 訂用帳戶金鑰
/// </summary>
public string Subkey { get; set; }
/// <summary>
/// 訂用帳戶服務的所在區域
/// </summary>
public string Region { get; set; }
/// <summary>
/// 要辨識的語言
/// </summary>
public string Language { get; set; }
/// <summary>
/// 輸入的文字
/// </summary>
public string Text { get; set; }
}
}
修改預設的class.cs檔案為介面檔,名稱為ISpeechService,並建立方法
using Interfaces;
using System;
using System.Threading.Tasks;
namespace Interfaces
{
/// <summary>
/// 語音辨識用介面
/// </summary>
public interface ISpeechService
{
/// <summary>
/// 辨識輸入語音為文字
/// </summary>
/// <param name="configBM">語音辨識基本設定用</param>
/// <returns>辨識後的文字</returns>
Task<string> SpeakToText(RecognizeBM configBM);
/// <summary>
/// 辨識輸入文字為語音
/// </summary>
/// <param name="textToSpeakBM">輸入文字為語音用</param>
/// <returns></returns>
Task TextToSpeak(RecognizeBM recognizeBM);
}
}
4.在方案 SpeechRecognitionSample點選滑鼠右鍵,點選 [加入] -> 新增專案
建立類別庫專案(.NET Core),名稱叫做 Services,點選確定
在專案Services點選滑鼠右鍵,點選 [管理NuGet套件]
接著點選瀏灠,輸入組件名稱[Microsoft.CognitiveServices.Speech],
再點按組件[Microsoft.CognitiveServices.Speech]
右方的下箭頭鈕(安裝Microsoft.CognitiveServices.Speech v1.7.0版)。
修改預設的class.cs檔案名稱為SpeechService,
繼承 ISpeechService,並實作方法
using Interfaces;
using Microsoft.CognitiveServices.Speech;
using System;
using System.Threading.Tasks;
namespace Services
{
// 語音服務的語言,語音名稱設定等可參考
// https://github.com/MicrosoftDocs/azure-docs.zh-tw/blob/master/articles/cognitive-services/Speech-Service/language-support.md#text-to-speech
/// <summary>
/// 語音辨識
/// </summary>
public class SpeechService : ISpeechService
{
private string recognizeText = string.Empty;
/// <summary>
/// 辨識輸入語音為文字
/// </summary>
/// <param name="recognizeBM">語音辨識基本設定用</param>
/// <returns>辨識後的文字</returns>
public async Task<string> SpeakToText(RecognizeBM recognizeBM)
{
// 設定語音服務設定
var config = this.GetSpeechConfig(recognizeBM);
// 建立語音辨識器類別
using (var recognizer = new SpeechRecognizer(config))
{
// RecognizeOnceAsync 此方法 僅適用於單個語音識別,如命令或查詢,輸入時間小於 15 秒
// 如果需要長時間運行的多話語識別,請改用 StartContinuousRecognitionAsync(),
// 輸入時間大於 15 秒
var result = await recognizer.RecognizeOnceAsync();
// 判斷回傳執行結果狀態
this.CheckReason(result);
return recognizeText;
}
}
/// <summary>
/// 辨識輸入文字為語音
/// </summary>
/// <param name="textToSpeakBM">輸入文字為語音用</param>
/// <returns></returns>
public async Task TextToSpeak(RecognizeBM recognizeBM)
{
// 設定語音服務設定
var config = this.GetSpeechConfig(recognizeBM);
// 建立語音合成器類別
using (var synthesizer = new SpeechSynthesizer(config))
{
Console.WriteLine("處理中...");
// 判斷輸入是否為空白
if (string.IsNullOrEmpty(recognizeBM.Text.Trim()))
recognizeBM.Text = "無法辨識輸入,請重新輸入\n";
// 將文字合成為語音
using (var result = await synthesizer.SpeakTextAsync(recognizeBM.Text))
{
// 判斷回傳執行結果狀態
this.CheckReason(result);
Console.WriteLine($"系統辨識為: {recognizeBM.Text}\n");
}
}
}
/// <summary>
/// 設定語音服務設定
/// </summary>
/// <param name="recognizeBM"></param>
/// <returns></returns>
private SpeechConfig GetSpeechConfig(RecognizeBM recognizeBM)
{
// 設定 訂用帳戶金鑰 與 訂用帳戶服務的所在區域
// 免費試用的服務所在區域都是 westus
var speechConfig =
SpeechConfig.FromSubscription(recognizeBM.Subkey, recognizeBM.Region);
// 要辨識的語言
speechConfig.SpeechRecognitionLanguage = recognizeBM.Language;
// 設定語音名稱
speechConfig = this.SetVoiceName(recognizeBM.Language, speechConfig);
return speechConfig;
}
/// <summary>
/// 設定語音名稱
/// </summary>
/// <param name="language">要辨識的語言</param>
/// <param name="speechConfig">語音服務設定</param>
/// <returns></returns>
private SpeechConfig SetVoiceName(string language, SpeechConfig speechConfig)
{
// 根據要辨識的語言設定對應的語音名稱
// 中文 zh-TW-Yating-Apollo、zh-TW-HanHanRUS、zh-TW-Zhiwei-Apollo
if (language == "zh-TW")
speechConfig.SpeechSynthesisVoiceName = "zh-TW-Yating-Apollo";
return speechConfig;
}
/// <summary>
/// 判斷回傳執行結果狀態
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
private bool CheckReason(dynamic result)
{
// 發生錯誤
if (result.Reason == ResultReason.Canceled)
{
var typeName = result.GetType().Name;
// 發生錯誤,提示訊息
if (typeName == "RecognitionResult")
this.DisPlayMessage(CancellationDetails.FromResult(result));
if (typeName == "SpeechSynthesisResult")
this.DisPlayMessage(SpeechSynthesisCancellationDetails.FromResult(result));
}
// 如果 執行結果為 語音轉文字類型
// 設定 辨識後的文字
if (result as RecognitionResult != null)
recognizeText = result.Text;
// 無法辨識輸入結果
if (result.Reason == ResultReason.NoMatch)
{
recognizeText = $"無法辨識輸入語音,請重新輸入\n";
}
return true;
}
/// <summary>
/// 發生錯誤,提示訊息
/// </summary>
/// <param name="cancellation"></param>
private void DisPlayMessage(dynamic cancellation)
{
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
Console.WriteLine($"CANCELED: Did you update the subscription info?");
}
throw new Exception("發生系統錯誤,請重新執行");
}
}
}
5. 修改 Program.cs 內容
1.修改專案的 SpeechRecognitionSample.csproj 檔
以文字檔開啟後 修改 <PropertyGroup></PropertyGroup> 內容
加入 <LangVersion>7.1</LangVersion> 設定使用語言版本
2.修改 static void Main(string[] args) 方法 為
static async Task Main(string[] args),
程式碼如下:
using Interfaces;
using Services;
using System;
using System.Threading.Tasks;
namespace SpeechRecognitionSample
{
class Program
{
static ISpeechService speechService;
static async Task Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("模式切換方式如下:");
Console.WriteLine("語音輸入模式下,說出 手動輸入 或 切換,即切換為手動輸入模式");
Console.WriteLine("手動輸入模式下,輸入 語音輸入 或 切換,即切換為語音輸入模式");
Console.WriteLine("任一模式下,輸入 關閉 或 結束,即結束應用程式");
Console.ForegroundColor = ConsoleColor.White;
// 實體化 語音辨識 服務
speechService = new SpeechService();
// 實體化 語音辨識基本設定用 BM
var recognizeBM = new RecognizeBM();
// 要辨識的語言
recognizeBM.Language = "zh-TW";
Console.WriteLine("輸入帳戶金鑰:");
// 取得金鑰
recognizeBM.Subkey = Console.ReadLine();
// 取得服務端點位置,免費試用帳戶都為 westus
recognizeBM.Region = "westus";
// 預設程式啟動提示訊息
recognizeBM.Text = "語音服務啟動";
try
{
// 執行文字轉語音
await speechService.TextToSpeak(recognizeBM);
// 用來切換模式的 flag
var isTextMode = false;
while (true)
{
if (isTextMode)
{
Console.WriteLine("手動輸入:");
// 取得輸入文字
recognizeBM.Text = Console.ReadLine();
// 執行文字轉語音
isTextMode = await StartTextToSpeak(recognizeBM, "語音輸入", isTextMode);
}
else
{
Console.WriteLine("語音輸入:");
// 取得輸入文字
recognizeBM.Text = await speechService.SpeakToText(recognizeBM);
// 執行文字轉語音
isTextMode = await StartTextToSpeak(recognizeBM, "手動輸入", isTextMode);
}
}
}
catch
{
Console.WriteLine("應用程式執行失敗,請重新執行");
Console.ReadLine();
}
}
/// <summary>
/// 執行文字轉語音
/// </summary>
/// <param name="recognizeBM">語音辨識設定</param>
/// <param name="keyWord">切換 手動/語音模式 關鍵字</param>
/// <param name="modeStatus">模式狀態</param>
/// <returns></returns>
private async static Task<bool> StartTextToSpeak(
RecognizeBM recognizeBM, string keyWord, bool modeStatus)
{
// 輸入關閉或結束,結束應用程式
if (recognizeBM.Text.Contains("關閉") || recognizeBM.Text.Contains("結束"))
{
Console.WriteLine("應用程式結束,請輸入任意鍵繼續...");
Console.ReadLine();
Environment.Exit(0);
}
// 執行文字轉語音
await speechService.TextToSpeak(recognizeBM);
if (recognizeBM.Text.Contains(keyWord) || recognizeBM.Text == "切換")
return !modeStatus;
return modeStatus;
}
}
}
6.按 F5 啟動專案進行測試,執行結果如下,
可以發現成功的將 文字轉換成語音輸出,及輸入的語音轉換成文字
五、結語:
這篇介紹了如何簡單的運用 Microsoft Azure 語音服務
來實現語音操作應用程式的方法,
Microsoft Azure 還有提供許多的認知服務,
有興趣的人可以再自行研究學習。
六、參考資料: