4

我尝试使用System.Speech该类在 ASP.NET mvc 应用程序中生成语音。

[HttpPost]
public  ActionResult TTS(string text)
{
   SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer();
   speechSynthesizer.Speak(text);
   return View();
}

但它给出了以下错误。

 System.InvalidOperationException: 'An asynchronous operation cannot be 
 Started at this time. Asynchronous operations may only be started within an 
 asynchronous handler or module or during certain events in the Page lifecycle. 
 If this exception occurred while executing a Page, ensure that the Page is
 marked <%@ Page Async="true" %>. 
 This exception may also indicate an attempt to call an "async void" method, 
 which is generally unsupported within ASP.NET request processing. Instead, 
the asynchronous method should return a Task, and the caller should await it.

我在 wpf 应用程序中使用了 System.Speech 类和异步方法。

  1. System.Speech 类可以在 ASP.NET mvc 应用程序中使用吗?

  2. 怎么做?

  3. 应该<%@ Page Async="true" %>放在哪里?
4

1 回答 1

9

答案是:的,你可以System.Speech在 MVC 中使用类。

我认为您可以尝试使用async控制器操作方法并使用这样SpeechSynthesizer.SpeakTask.Run方法:

[HttpPost]
public async Task<ActionResult> TTS(string text)
{
    Task<ViewResult> task = Task.Run(() =>
    {
        using (SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer())
        {
            speechSynthesizer.Speak(text);
            return View();
        }
    });
    return await task;
}

但是,如上面的示例所示,生成的声音会在服务器上播放,因为上面的代码是在服务器端而不是客户端运行的。要在客户端启用播放,您可以使用SetOutputToWaveFile方法和audio标签在返回如下示例所示的视图页面时播放音频内容(假设您在 CSHTML 视图中使用 HTML 5):

控制器

[HttpPost]
public async Task<ActionResult> TTS(string text)
{
    // you can set output file name as method argument or generated from text
    string fileName = "fileName";
    Task<ViewResult> task = Task.Run(() =>
    {
        using (SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer())
        {
            speechSynthesizer.SetOutputToWaveFile(Server.MapPath("~/path/to/file/") + fileName + ".wav");
            speechSynthesizer.Speak(text);

            ViewBag.FileName = fileName + ".wav";
            return View();
        }
    });
    return await task;
}

看法

<audio autoplay="autoplay" src="@Url.Content("~/path/to/file/" + ViewBag.FileName)">
</audio>

或者您可以将操作类型更改为FileContentResult并使用MemoryStreamwithSetOutputToWaveStream让用户自己播放音频文件:

Task<FileContentResult> task = Task.Run(() =>
{
    using (SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer())
    {
        using (MemoryStream stream = new MemoryStream())
        {
            speechSynthesizer.SetOutputToWaveStream(stream);
            speechSynthesizer.Speak(text);
            var bytes = stream.GetBuffer();
            return File(bytes, "audio/x-wav");
        }
    }
});

参考:

在 ASP.NET MVC 中使用异步方法

类似问题:

如何在mvc中使用语音

System.Speech.Synthesis 在 2012 R2 上以高 CPU 挂起

于 2017-11-15T06:42:39.233 回答