使用 SpeechSynthesis 将文本转换为语音时,.NET 4.5 中的 WebAPI 中的 HTTP Get 请求没有响应

2024-04-23

我正在尝试使用 WebAPI 设置一个简单的 Web 服务。这是我的代码:

public class SpeakController : ApiController
    {
        //
        // api/speak

        public HttpResponseMessage Get(String textToConvert, String outputFile, string gender, string age = "Adult")
        {
            VoiceGender voiceGender = (VoiceGender)Enum.Parse(typeof(VoiceGender), gender);
            VoiceAge voiceAge = (VoiceAge)Enum.Parse(typeof(VoiceAge), age);

            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                synthesizer.SelectVoiceByHints(voiceGender, voiceAge);
                synthesizer.SetOutputToWaveFile(outputFile, new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
                synthesizer.Speak(textToConvert);
            }

            return Request.CreateResponse(HttpStatusCode.OK, new Response { HttpStatusCode = (int)HttpStatusCode.OK, Message = "Payload Accepted." });
        }
    }

代码相当简单,而且还没有准备好投入生产。但在我的测试中,我注意到对控制器的任何请求都会发生以下情况:

  • WAV文件已成功生成
  • 在调试期间,我可以看到控件点击返回并退出该方法
  • 但是,我的浏览器一直在旋转,我从未收到服务器的响应

我对 Postman(Chrome 的 REST 客户端)进行了同样的尝试,并得到了相同的结果。虽然我确实希望这是一个阻塞调用,但为了尝试我修改的其他内容synthesizer.Speak to synthesizer.SpeakAsync并遇到了同样的问题。

但是,当我如下所示单独测试片段时,代码按预期工作。

使用注释掉的语音部分测试 Web API 调用:

public class SpeakController : ApiController
{
    //
    // api/speak

    public HttpResponseMessage Get(String textToConvert, String outputFile, string gender, string age = "Adult")
    {
        VoiceGender voiceGender = (VoiceGender)Enum.Parse(typeof(VoiceGender), gender);
        VoiceAge voiceAge = (VoiceAge)Enum.Parse(typeof(VoiceAge), age);

        //using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
        //{
        //  synthesizer.SelectVoiceByHints(voiceGender, voiceAge);
        //  synthesizer.SetOutputToWaveFile(outputFile, new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
        //  synthesizer.Speak(textToConvert);
        //}

        return Request.CreateResponse(HttpStatusCode.OK, new Response { HttpStatusCode = (int)HttpStatusCode.OK, Message = "Payload Accepted." });
    }
}

在控制台应用程序中单独测试语音:

static string usageInfo = "Invalid or no input arguments!"
    + "\n\nUsage: initiatives \"text to speak\" c:\\path\\to\\generate.wav gender"
    + "\nGender:\n\tMale or \n\tFemale"
    + "\n";

static void Main(string[] args)
{
    if (args.Length != 3)
    {
        Console.WriteLine(usageInfo);
    }
    else
    {
        ConvertStringToSpeechWav(args[0], args[1], (VoiceGender)Enum.Parse(typeof(VoiceGender), args[2]));
    }

    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

static void ConvertStringToSpeechWav(String textToConvert, String pathToCreateWavFile, VoiceGender gender, VoiceAge age = VoiceAge.Adult)
{
    using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
    {
        synthesizer.SelectVoiceByHints(gender, age);
        synthesizer.SetOutputToWaveFile(pathToCreateWavFile, new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
        synthesizer.Speak(textToConvert);
    }
}

WebAPI 和 SpeechSynthesis 似乎不能很好地协同工作。任何帮助解决这个问题的帮助将不胜感激。

Thanks!


我不知道为什么会发生这种情况,但在单独的线程中运行 SpeechSynthesizer 似乎可以解决问题(不兼容的线程模型?)。这是我过去的做法。

基于:ASP.NET MVC 中的超快速文本转语音 (WAV -> MP3) https://stackoverflow.com/questions/12343249/ultra-fast-text-to-speech-wav-mp3-in-asp-net-mvc

public dynamic Post(dynamic req)
{
    try 
    {
        string phrase = req["phrase"].Value;

        var stream = new MemoryStream();
        var t = new System.Threading.Thread(() =>
            {
                using (var synth = new SpeechSynthesizer())
                {
                    synth.SetOutputToWaveStream(stream);
                    synth.Speak(phrase);
                    synth.SetOutputToNull();
                }
            });

        t.Start();
        t.Join();

        stream.Position = 0;

        var resp = new HttpResponseMessage(HttpStatusCode.OK);
        resp.Content = new StreamContent(stream);

        resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        resp.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
        resp.Content.Headers.ContentDisposition.FileName = "phrase.wav";

        return resp;
    }
    catch
    {
        return new HttpResponseMessage(HttpStatusCode.InternalServerError);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SpeechSynthesis 将文本转换为语音时,.NET 4.5 中的 WebAPI 中的 HTTP Get 请求没有响应 的相关文章

随机推荐