这是与微软语音api相关的问题:
当SpeechSynthesizer触发SpeakStarted事件时,我想知道SpeechSynthesizer在这个事件中会说些什么。所以我可以同步语音和GUI显示。
代码:
SpeechSynthesizer _reader = new SpeechSynthesizer();
_reader.SpeakStarted += new EventHandler<SpeakStartedEventArgs>(_reader_SpeakStarted);
void _reader_SpeakStarted(object sender, SpeakStartedEventArgs e)
{
// now _speak started!
Console.WriteLine("_reader_SpeakStarted\t" + e.ToString());
// string textContent=????
// updateGUI(textContent);
}
_reader.SpeakAsync("Hello world A B C"); //asynchronize method!!!
_reader.SpeakAsync("Hello world B C D");
_reader.SpeakAsync("Hello world C D E");
问题:
在SpeakStarted事件中,人们无法说出要说出的文字内容。
奇怪的是,“Hello world x x x”确实出现在参数中,如果你在那里放置一个断点,但是没有办法访问它。
如果有人可以帮助我,我会非常感激。
.Net 4,Windows 7 64位,VS2010
答案 0 :(得分:1)
提示对象并不总是包含文本,这就是它不作为公共属性公开的原因。也可以使用标记或音频文件构造相同的对象。执行此操作的最佳方法是将传递给SpeakAsync方法的值存储为全局参数,当您想要显示它们时可以将其传递到UI。
private static string _spokenWords;
static void Main(string[] args)
{
SpeechSynthesizer _reader = new SpeechSynthesizer();
_reader.SpeakStarted += ReaderSpeakStarted;
_spokenWords = "Hello world A B C";
_reader.SpeakAsync(_spokenWords); //asynchronize method!!!
}
static void ReaderSpeakStarted(object sender, SpeakStartedEventArgs e)
{
// now _speak started!
Console.WriteLine("_reader_SpeakStarted\t" + _spokenWords);
// string textContent=????
// updateGUI(textContent);
您还可以查看使用反射来突破提示对象中的私有文本字段以访问该值。虽然这将更加耗费资源,但不一定稳定:
static void Main(string [] args) {
SpeechSynthesizer _reader = new SpeechSynthesizer();
_reader.SpeakStarted += ReaderSpeakStarted;
_reader.SpeakAsync("Hello world A B C"); //asynchronize method!!!
_reader.SpeakAsync("Hello world B C D");
_reader.SpeakAsync("Hello world C D E");
}
static void ReaderSpeakStarted(object sender, SpeakStartedEventArgs e)
{
// now _speak started!
var spokenWord = GetTextFieldValue(e.Prompt);
Console.WriteLine("_reader_SpeakStarted\t" + spokenWord);
// string textContent=????
// updateGUI(textContent);
}
private static string GetTextFieldValue(Prompt p)
{
var text = typeof(Prompt).GetField("_text", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(p);
return (string)(text.GetType() == typeof(String) ? text : string.Empty);
}