實施文字轉語音
當你想要實現文字到語音轉換(tts)時,請求特定於平臺的程式碼的功能的一個很好的示例。此示例假定你正在使用 PCL 庫中的共享程式碼。
我們的解決方案的示意圖將看起來像下面的影象。
在我們的共享程式碼中,我們定義了一個在 DependencyService
中註冊的介面。這是我們呼叫的地方。定義類似於下面的介面。
public interface ITextToSpeech
{
void Speak (string text);
}
現在,在每個特定平臺中,我們需要建立此介面的實現。讓我們從 iOS 實現開始。
iOS 實施
using AVFoundation;
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var speechSynthesizer = new AVSpeechSynthesizer ();
var speechUtterance = new AVSpeechUtterance (text) {
Rate = AVSpeechUtterance.MaximumSpeechRate/4,
Voice = AVSpeechSynthesisVoice.FromLanguage ("en-US"),
Volume = 0.5f,
PitchMultiplier = 1.0f
};
speechSynthesizer.SpeakUtterance (speechUtterance);
}
}
在上面的程式碼示例中,你注意到 iOS 有特定的程式碼。像 AVSpeechSynthesizer
這樣的型別。這些在共享程式碼中不起作用。
要使用 Xamarin DependencyService
註冊此實現,請在名稱空間宣告上方新增此屬性。
using AVFoundation;
using DependencyServiceSample.iOS;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.iOS {
public class TextToSpeechImplementation : ITextToSpeech
//... Rest of code
現在,當你在共享程式碼中執行此類呼叫時,將注入正在執行應用程式的平臺的正確實現。
DependencyService.Get<ITextToSpeech>()
。稍後會詳細介紹。
Android 實施
這段程式碼的 Android 實現看起來就像在下面。
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
{
TextToSpeech speaker;
string toSpeak;
public TextToSpeechImplementation () {}
public void Speak (string text)
{
var ctx = Forms.Context; // useful for many Android SDK features
toSpeak = text;
if (speaker == null) {
speaker = new TextToSpeech (ctx, this);
} else {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#region IOnInitListener implementation
public void OnInit (OperationResult status)
{
if (status.Equals (OperationResult.Success)) {
var p = new Dictionary<string,string> ();
speaker.Speak (toSpeak, QueueMode.Flush, p);
}
}
#endregion
}
再次不要忘記將其註冊到 DependencyService
。
using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.Droid{
//... Rest of code
Windows Phone 實現
最後,對於 Windows Phone,可以使用此程式碼。
public class TextToSpeechImplementation : ITextToSpeech
{
public TextToSpeechImplementation() {}
public async void Speak(string text)
{
MediaElement mediaElement = new MediaElement();
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
await synth.SynthesizeTextToStreamAsync(text);
}
}
再一次不要忘記註冊它。
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;
using DependencyServiceSample.WinPhone;//enables registration outside of namespace
[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.WinPhone{
//... Rest of code
在共享程式碼中實現
現在一切都準備好了! 最後,在共享程式碼中,你現在可以使用該介面呼叫此函式。在執行時,將注入與其執行的當前平臺相對應的實現。
在此程式碼中,你將看到可能位於 Xamarin Forms 專案中的頁面。它建立了一個按鈕,通過使用 DependencyService
呼叫 Speak()
方法。
public MainPage ()
{
var speak = new Button {
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
speak.Clicked += (sender, e) => {
DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
};
Content = speak;
}
結果是當應用程式執行並單擊按鈕時,將說出提供的文字。
所有這一切都無需像編譯器提示等那樣做。你現在可以通過獨立於平臺的程式碼來統一訪問平臺特定功能。