Xamarin可以製作跨平台的App應用程式,當然也可以使用各平台底層的服務
在這篇文章中,會說明如何使用Android底層的Google語音辨識服務,將說出的語句辨識成為文字
由於用到的是Xamarin.Forms的開發方式,所以要採用DependencyService的方式來針對不同平台作出語音辨識的功能
iOS的語音辨識較為麻煩,需要採用第三方套件才能達成語音辨識的功能
所以在本篇文章中只會先說明Android該如何作出語音辨識,iOS的部份留待後續再來說明
1.先在Xamarin.Forms的可攜式專案中,建立一個SpeechToTextResult.cs的檔案檔案內容請加上下面的程式碼
public class SpeechToTextResult
{
public string Text { get; set; }
}
這個類別庫主要是用來定義接收語音辨識完的結果,並放入至一個結果物件中
2.一樣在可攜式專案中,建立一個ISpeechToText.cs的類別檔
並在ISpeechToText.cs檔案中加上下面程式碼
public interface ISpeechToText
{
Task<SpeechToTextResult> SpeechToTextAsync();
}
這邊主要是建立一個介面,以便讓不同平台去實作這樣的功能,所以在這裡定義了一個SpeechToTextAsync的副程式,並將結果回傳SpeechToTextResult的物件
3.建立一個View,並在畫面上加上一個Label與Button,當Button按下的時候,啟動語音辨識的功能xaml程式碼如下:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AzureAD.Views.SpeechToTextView">
<StackLayout>
<Label Text="" VerticalOptions="Center" HorizontalOptions="Center" x:Name="lblText" />
<Button Text="開始辨識" VerticalOptions="Center" HorizontalOptions="Center" x:Name="btnSpeech" Clicked="btnSpeech_Clicked" />
</StackLayout>
</ContentPage>
C#程式碼如下:
ISpeechToText speech = DependencyService.Get<ISpeechToText>();
public SpeechToTextView()
{
InitializeComponent();
}
/// <summary>
/// 點選開始辨識的動作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected async void btnSpeech_Clicked(object sender, EventArgs e)
{
var SpeechResult = await speech.SpeechToTextAsync();
if (SpeechResult != null)
lblText.Text = SpeechResult.Text;
}
這個步驟主要是當按下Button時,去呼叫ISpeechToText這個介面,並將辨識的結果回傳至畫面上的Label中
4.接著就是Android平台中的重頭戲了,先在Android平台中,建立一個SpeechToTextService.cs的類別庫類別庫程式碼如下:
[assembly: Xamarin.Forms.Dependency(typeof(SpeechToTextService))]
namespace AzureAD.Droid.Services
{
public class SpeechToTextService :ISpeechToText
{
private static TaskCompletionSource<SpeechToTextResult> objResult;
public Task<SpeechToTextResult> SpeechToTextAsync()
{
string rec = PackageManager.FeatureMicrophone;
if (rec == "android.hardware.microphone")
{
var voiceIntent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
voiceIntent.PutExtra(RecognizerIntent.ExtraPrompt, "請說出指令");
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputPossiblyCompleteSilenceLengthMillis, 1500);
voiceIntent.PutExtra(RecognizerIntent.ExtraSpeechInputMinimumLengthMillis, 15000);
voiceIntent.PutExtra(RecognizerIntent.ExtraMaxResults, 1);
voiceIntent.PutExtra(RecognizerIntent.ExtraLanguage, Java.Util.Locale.Default);
var activity = (Activity)Forms.Context;
activity.StartActivityForResult(voiceIntent, (int)Enums.ActiveResultCode.SpeechToText);
}
objResult = new TaskCompletionSource<SpeechToTextResult>();
return objResult.Task;
}
/// <summary>
/// 取得辨識結果的動作
/// </summary>
/// <param name="resultCode"></param>
/// <param name="strSpeechText"></param>
public static void OnResult(Result resultCode, Intent data)
{
if (resultCode == Result.Canceled)
{
objResult.TrySetResult(null);
return;
}
if (resultCode != Result.Ok)
{
objResult.TrySetException(new Exception("Unexpected error"));
return;
}
var matches = data.GetStringArrayListExtra(RecognizerIntent.ExtraResults);
string strSpeechText = "No Speech";
if (matches.Count != 0)
strSpeechText = matches[0];
SpeechToTextResult res = new SpeechToTextResult();
res.Text = strSpeechText;
objResult.TrySetResult(res);
}
}
}
這段程式碼分成兩個部份,上半段是實際執行語音辨識的動作,並定義一個新的SpeechToTextResult物件,下半段則是當語音辨識有結果時,將辨識的結果放至SpeechToTextResult物件中
5.最後在MainActivity.cs中,加上下面這段程式碼
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
// 如果回傳的requestCode是Enums.ActiveResultCode.SpeechToText, 就將結果回傳至SpeechToText的OnResult
AzureAD.Droid.Services.SpeechToTextService.OnResult(resultCode, data);
base.OnActivityResult(requestCode, resultCode, data);
}
MainActivity.cs的程式碼主要是在執行,當辨識的過程得到結果後,會將事件傳至SpeechToTextService.OnResult的副程式中,這樣才能順利得到辨識的結果
下圖是執行的結果畫面
當按下開始辨識的按鈕之後,Android作業系統會開啟Google的語音辨識功能
最後得到辨識的結果,並放在最上方的Label中
語音變識的功能,以前並沒有太多的應用,但是隨著進近幾年機器人與AI智慧的發展,口語以及語音辨識的應用也會越來越多,並大量的應用在生活周遭上
參考資料:
Android Speech
Accessing Native Features with DependencyService
範例程式已放上GitHub,請參考下面網址內容:
https://github.com/madukapai/maduka-Xamarin