How to use windows speech synthesizer in ASP.NET MVC

这一生的挚爱 提交于 2019-12-10 10:41:36

问题


I tried to use the System.Speech class to generate speech in ASP.NET mvc application.

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

But it gives the following error.

 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.

I used the System.Speech class and async methods in wpf applications.

  1. Can the System.Speech class be used in a ASP.NET mvc application?

  2. How to do it?

  3. Where should be the <%@ Page Async="true" %> be placed?

回答1:


The answer is: yes, you can use System.Speech class in MVC.

I think you can try using async controller action method and use SpeechSynthesizer.Speak with Task.Run method like this:

[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;
}

However, as in example above the generated sound plays on server, because the code above runs server-side instead of client-side. To enable playing on client-side, you can use SetOutputToWaveFile method and use audio tag to play audio content when returning view page shown in example below (assumed you're using HTML 5 in CSHTML view):

Controller

[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;
}

View

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

Or you can change action type to FileContentResult and use MemoryStream with SetOutputToWaveStream to let user play audio file himself:

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");
        }
    }
});

Reference:

Using Asynchronous Methods in ASP.NET MVC

Similar issues:

How to use speech in mvc

System.Speech.Synthesis hangs with high CPU on 2012 R2



来源:https://stackoverflow.com/questions/47300251/how-to-use-windows-speech-synthesizer-in-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!