实施文本转语音
当你想要实现文本到语音转换(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;
}
结果是当应用程序运行并单击按钮时,将说出提供的文本。
所有这一切都无需像编译器提示等那样做。你现在可以通过独立于平台的代码来统一访问平台特定功能。