我在使用具有文字转语音功能的Windows Phone 7应用程序上工作。我正在使用Text-To-Speech with Microsoft Translator Service和以下C#代码......
// Text-To-Speech with Microsoft Translator Service (http://translatorservice.codeplex.com/)
private void TextToSpeech_Play(object sender, EventArgs e)
{
SpeechSynthesizer speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
//string content = "This is a beautiful day!";
string language = "en";
//speech.SpeakAsync(content, language);
foreach (UIElement element in todayschapter.Children)
{
if (element is TextBlock)
{
string content = (element as TextBlock).Text;
speech.SpeakAsync(content, language);
}
}
}
在这个例子中,todayschapter是一个StackPanel,它的Children是TextBlocks。我想连续播放每个TextBlock的音频。问题是它同时播放每个TextBlock的音频。
我怀疑这个问题是SpeakAsync()
,但我不确定。 documentation显示Speak()
,但在Visual Studio方法帮助程序下拉列表中不可用(可能是不同的版本)(在您键入时显示的小东西 - 不确定它的名称)。
有没有办法让它在下一场比赛之前等待每场比赛结束? foreach
不是正确的选择吗?
与往常一样,如果我的代码看起来很愚蠢,请推荐更好的方法。我是一名初学程序员。
答案 0 :(得分:2)
只需使用Speak
而不是异步调用,因为无论如何都希望一个接一个地使用它。
答案 1 :(得分:0)
SpeakAsync
电话确实是问题所在。很遗憾,由于SpeakAsync
未返回Task
,因此您无法将其转换为await SpeakAsync()
(这将是最直接的转换)。
而且,查看源代码,它不会触发事件来判断它何时完成。所以让我们添加一个(在SpeechSynthesizer.cs中):
public event EventHandler<SpeechEventArgs> SpeakCompleted;
public void SpeakAsync(string text, string language)
{
this.GetSpeakStreamAsyncHelper(text, language, result =>
{
if (result.Error == null)
{
SoundEffect effect = SoundEffect.FromStream(result.Stream);
FrameworkDispatcher.Update();
effect.Play();
this.OnSpeakCompleted(new SpeechEventArgs(result.Error)); // added to call completion handler
}
else
{
this.OnSpeakFailed(new SpeechEventArgs(result.Error));
}
});
}
// new function
private void OnSpeakCompleted(SpeechEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (SpeakCompleted != null)
SpeakCompleted(this, e);
});
}
现在,您需要处理SpeakCompleted
事件并开始说下一个字符串。
这样的东西(我甚至没有编译过这个,所以要警告):
private Queue<string> utterances;
private SpeechSynthesizer speech;
private void TextToSpeech_Play(object sender, EventArgs e)
{
speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
speech.SpeechCompleted += new EventHandler<SpeechEventArgs>(TextToSpeech_Completed);
foreach (UIElement element in todayschapter.Children)
{
if (element is TextBlock)
{
string content = (element as TextBlock).Text;
utterances.Enqueue(content);
}
}
TextToSpeech_Completed(null, null); // start speaking the first one
}
private void TextToSpeech_Completed(object sender, SpeechEventArgs e)
{
if (utterances.Any())
{
string contents = utterances.Dequeue();
speech.SpeakAsync(contents);
}
}