0

我正在开发一个项目,它将说出浏览网页的内容。浏览器是我使用 WebControl 制作的。我正在将 SAPI 用于语音引擎。我想在通过 SpVoice.speak 阅读时突出显示网页中的行。但问题是,如果我以异步方式使用这种 speak 方法,那么只有网页的最后一行会突出显示,因为循环不会等待语音完成。因此它发生得如此之快,以至于只有最后一行显示为突出显示。Highlight 方法使用参考 Microsoft mshtml。代码:

SpeechLib.SpVoice sound_object = new SpeechLib.SpVoice();
bool highlight(string senten)
    {
        if (senten != null)
        {
            IHTMLDocument2 doc = (IHTMLDocument2)GetCurrentBrowser().Document.DomDocument;
            IHTMLSelectionObject sel = (IHTMLSelectionObject)doc.selection;
            IHTMLTxtRange rng = (IHTMLTxtRange)sel.createRange();
            rng.collapse(false);
            if (rng.findText(senten, 1000000, 0))
            {
                rng.select();
                return true;
            }
            else
            {
                return false;
            }

        }
        else
        { return false; }

    }

private void Read_ButtonSpkBAR_Click(object sender, EventArgs e) { //调用获取源代码 gettingSourceCode();

        if (highlightToolStripMenuItem.Checked == true)
        {

            if (PAUSE)
            {
                sound_object.Resume();
                PAUSE = false;
            }
            else
            {
                sound_object.Rate = tempoRate;
                sound_object.Volume = volume;


                string[] splitSentences = Regex.Split(SourceCode, @"(?<=['""A-Za-z0-9][\.\!\?\u2424])\s+(?=[A-Z])");



                for (int i = 0; i < splitSentences.Length; i++)
                {


                    highlight(splitSentences[i]);
                    //MessageBox.Show(splitSentences[i]);

                    sound_object.Speak(splitSentences[i],SpeechLib.SpeechVoiceSpeakFlags.SVSFlagsAsync);




                }
            }
        }

现在,如果我以同步方式调用 sound_object.speak(),即 sound_object.Speak(splitSentences[i]); 然后循环等待声音完成,但我不知道为什么它没有显示突出显示的行。软件在说话的时候挂掉了。这意味着WebBrowser在说话的时候没有做任何事情,但是当时说话的程序运行正常。

为了检查突出显示,我在循环中放置了一个消息框,如果循环等待消息框的“确定”按钮被按下,则这些行会被突出显示。但是按下“确定”根本不是一个好主意每一行的按钮。那么任何人都可以帮我解决问题是什么以及如何以有效的方式使用 SAPI 或任何其他语音引擎,这样我就可以在不让浏览器挂起的情况下完全阅读和突出显示......

4

2 回答 2

2

You need to do the next line after the previous line finishes, using the TTS's completion event.

于 2011-03-07T15:41:35.183 回答
0

把所有的句子放在一个字符串中,然后只调用一次 speak。用下面的替换你的 for 循环:

string str1 = "";
for (int i = 0; i < splitSentences.Length; i++) 
{ 
     str1 += highlight(splitSentences[i]); 
}
sound_object.Speak(str1, SpeechLib.SpeechVoiceSpeakFlags.SVSFlagsAsync);

希望这可以帮助!

于 2011-10-07T17:42:41.113 回答