如何在Windows窗体中使用谷歌文本到语音API?

İlk*_*kut 1 c# desktop-application winforms

我想在我的Windows窗体应用程序中使用谷歌文本语音,它会读取标签.我添加了System.Speech参考.如何通过按钮点击事件读取标签? http://translate.google.com/translate_tts?q=testing+google+speech这是谷歌文本到语音API,或者我如何使用微软的本机文本语音?

M.B*_*ock 6

更新 Google的TTS API不再公开发布.关于微软TTS底部的注释仍然相关,并提供相同的功能.


您可以使用来自WinForm应用程序的Google的TTS API,通过使用此问题答案的变体播放响应(我花了一段时间,但我有一个真正的解决方案):

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.FormClosing += (sender, e) =>
            {
                if (waiting)
                    stop.Set();
            };
    }

    private void ButtonClick(object sender, EventArgs e)
    {
        var clicked = sender as Button;
        var relatedLabel = this.Controls.Find(clicked.Tag.ToString(), true).FirstOrDefault() as Label;

        if (relatedLabel == null)
            return;

        var playThread = new Thread(() => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(relatedLabel.Text)));
        playThread.IsBackground = true;
        playThread.Start();
    }

    bool waiting = false;
    AutoResetEvent stop = new AutoResetEvent(false);
    public void PlayMp3FromUrl(string url)
    {
        using (Stream ms = new MemoryStream())
        {
            using (Stream stream = WebRequest.Create(url)
                .GetResponse().GetResponseStream())
            {
                byte[] buffer = new byte[32768];
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
            }

            ms.Position = 0;
            using (WaveStream blockAlignedStream =
                new BlockAlignReductionStream(
                    WaveFormatConversionStream.CreatePcmStream(
                        new Mp3FileReader(ms))))
            {
                using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
                {
                    waveOut.Init(blockAlignedStream);
                    waveOut.PlaybackStopped += (sender, e) =>
                    {
                        waveOut.Stop();
                    };

                    waveOut.Play();
                    waiting = true;
                    stop.WaitOne(10000);
                    waiting = false;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注:上面的代码需要n音讯工作(自由/开源)和usingfor语句System.Web,System.ThreadingNAudio.Wave.

Form1有2个控件:

  1. 标签名为 label1
  2. 一个名为button1a Tag的按钮label1(用于将按钮绑定到其标签)

如果您使用(未经测试)之类的内容为每个按钮/标签组合设置不同的事件,则可以略微简化上述代码:

    private void ButtonClick(object sender, EventArgs e)
    {
        var clicked = sender as Button;

        var playThread = new Thread(() => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(label1.Text)));
        playThread.IsBackground = true;
        playThread.Start();
    }
Run Code Online (Sandbox Code Playgroud)

但是这个解决方案存在问题(这个列表可能不完整;我确信评论和现实世界的用法会找到其他的):

  1. 请注意stop.WaitOne(10000);第一个代码段中的内容.10000表示最多播放10秒的音频,因此如果您的标签需要的时间长于读取的标签,则需要进行调整.这是必要的,因为当前版本的NAudio(v1.5.4.0)似乎在确定流何时完成播放时存在问题.它可以在更高版本中修复,或者可能有一个我没有花时间找到的解决方法.一个临时解决方法是使用一个ParameterizedThreadStart将超时作为线程的参数.这将允许可变超时,但在技术上不会解决问题.
  2. 更重要的是,Google TTS API是非官方的(意味着不被非Google应用程序使用),它可能随时更改,恕不另行通知.如果您需要能够在商业环境中使用的东西,我建议使用MS TTS解决方案(如您的问题所示)或许多商业替代方案之一.尽管如此,这些都不是那么简单.

要回答问题的另一面:

这个System.Speech.Synthesis.SpeechSynthesizer容易使用,你可以指望它可靠地可用(在谷歌API的情况下,明天可能会消失).

它实际上就像包含对引用的System.Speech引用一样简单,并且:

public void SaySomething(string somethingToSay)
{
    var synth = new System.Speech.Synthesis.SpeechSynthesizer();

    synth.SpeakAsync(somethingToSay);
}
Run Code Online (Sandbox Code Playgroud)

只是有效的.

尝试使用Google TTS API是一个有趣的实验,但我很难建议它用于生产用途,如果你不想支付商业替代品,微软的解决方案就像它获得的一样好.