当前位置: 首页 > 编程语言 > C#

ASP.NET MVC中的超快文本到语音(WAV – > MP3)分享

时间:2023-04-10 18:33:39 C#

C#学习教程:SuperFastTexttoSpeech(WAV->MP3)inASP.NETMVC用于服务器工作负载的API(SAPI),以及它是否可以可靠地用于w3wp中的语音合成。我们有一个异步控制器,它使用.NET4中的本机System.Speech程序集(不是作为MicrosoftSpeechPlatform-RuntimeVersion11的一部分提供的Microsoft.Speech)和lame.exe生成mp3,如下所示:[CacheFilter]publicvoidListenAsync(stringurl){stringfileName=string.Format(@"C:test{0}.wav",Guid.NewGuid());try{vart=newSystem.Threading.Thread(()=>{using(SpeechSynthesizerss=newSpeechSynthesizer()){ss.SetOutputToWaveFile(fileName,newSpeechAudioFormatInfo(22050,AudioBitsPerSample.Eight,AudioChannel.Mono));ss.Speak("这是一个测试语句...");ss.SetOutputToNull();ss.Dispose();}varprocess=newProcess(){EnableRaisingEvents=true};process.StartInfo.FileName=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"binlame.exe");process.StartInfo.Arguments=string.Format("-V2{0}{1}",fileName,fileName.Replace(".wav",".mp3"));process.StartInfo.UseShellExecute=false;process.StartInfo.RedirectStandardOutput=false;process.StartInfo.RedirectStandardError=假;process.Exited+=(sender,e)=>{System.IO.File.Delete(fileName);AsyncManager.OutstandingOperations.Decrement();};AsyncManager.OutstandingOperations.Increment();进程.开始();});t.开始();t.Join();}catch{}AsyncManager.Parameters["fileName"]=fileName;}publicFileResultListenCompleted(stringfileName){returnbase.File(fileName.Replace(".wav",".mp3"),"audio/mp3");问题是为什么SpeechSynthesizer需要在单独的线程上运行才能返回(这在SO和其他地方有报告)以及是否为此请求实现STAThreadRouteHandler比上述方法更有效/可扩展?其次,在ASP.NET(MVC或WebForms)上下文中运行SpeakAsync的选项是什么?我尝试过的选项似乎都不起作用(请参阅下面的更新)关于如何改进此模式的任何其他建议(即必须彼此串行执行但每个都具有异步支持的两个依赖项)是受欢迎的。我不认为这种方案在负载下是可持续的,特别是考虑到SpeechSynthesizer的已知内存泄漏。考虑在不同的堆栈上一起运行此服务。更新:Speak或SpeakAsnc选项在STAThreadRouteHandler下似乎都不起作用。前者产生:System.InvalidOperationException:在此上下文中不允许异步操作。启动异步操作的页面必须将Async属性设置为true,异步操作只能在PreRenderComplete事件之前的页面上启动。System.Web.LegacyAspOperationManager.CreateOperation(对象userSuppliedState)在System.ComponentModel.AsyncOperationManager.CreateOperation(对象userSuppliedState)在System.Speech.Internal.Synthesis.VoiceSynthesis..ctor(WeakReferencespeechSynthesizer)在System.Web.LegacyAspNetSynthesizer中)在系统.Speech.Synthesis.SpeechSynthesizer.SetOutputToWaveFile(Stringpath,SpeechAudioFormatInfoformatInfo)后者导致:System.InvalidOperationException:异步操作方法“Listen”无法同步执行。在System.Web.Mvc.Async.AsyncActionDescriptor.Execute(ControllerContextcontrollerContext,IDictionary`2parameters)看起来自定义STA线程池(使用COM对象的ThreadStatic实例)是更好的方法:http://marcinbudny.blogspot.ca/2012/04/dealing-with-sta-coms-in-web.html更新#2:System.Speech.SpeechSynthesizer似乎不需要STA处理,似乎在MTA线程上运行良好,只要您关注开始/加入模式。这是一个正确使用SpeakAsync的较新版本(问题是过早地处理它!)并将WAV生成和MP3生成分解为两个单独的请求:[CacheFilter][ActionName("listen-to-text")]publicvoidListenToTextAsync(string文本){AsyncManager.OutstandingOperations.Increment();vart=newThread(()=>{SpeechSynthesizerss=newSpeechSynthesizer();stringfileName=string.Format(@"C:test{0}.wav",Guid.NewGuid());ss.SetOutputToWaveFile(文件名,新的SpeechAudioFormatInfo(22050,AudioBitsPerSample.Eight,AudioChannel.Mono));ss.SpeakCompleted+=(sender,e)=>{ss.SetOutputToNull();ss.Dispose();AsyncManager.Parameters["fileName"]=fileName;AsyncManager.OutstandingOperations.Decrement();};CustomPromptBuilderpb=newCustomPromptBuilder(settings.DefaultVoiceName);pb.AppendParagraphText(text););});t.开始();t.Join();}[CacheFilter]publicActionResultListenToTextCompleted(stringfileName){returnRedirectToAction("mp3",new{fileName=fileName});}[CacheFilter][ActionName("mp3")]ppublicvoidMp3Async(stringfileName){varprocess=newProcess(){EnableRaisingEvents=true,StartInfo=newProcessStartInfo(){FileName=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"binlame.exe"),Arguments=string.Format("-V2{0}{1}",fileName,fileName.Replace(".wav",".mp3")),UseShellExecute=false,RedirectStandardOutput=false,RedirectStandardError=false}};process.Exited+=(sender,e)=>{System.IO.File.Delete(fileName);AsyncManager.Parameters["文件名"]=文件名;AsyncManager.OutstandingOperations.Decrement();};AsyncManager.OutstandingOperations.Increment();处理.Start();}[CacheFilter]publicActionResultMp3Completed(stringfileName){returnbase.File(fileName.Replace(".wav",".mp3"),"audio/mp3");服务器上的I/O在服务器上非常昂贵你认为你可以在服务器硬盘驱动器上使用多少wav写入流?为什么不在内存中做所有事情,只在完全处理后才写入mp3?mp3的数量要小得多,I/O也需要很少的时间。您甚至可以更改代码以将流直接返回给用户,而不是保存为mp3(如果需要)。我如何使用LAME将wav编码为mp3c#这个问题现在有点老了,但这就是我正在做的,到目前为止它工作得很好:publicTaskSpeak(stringtext){returnTask.Factory.StartNew(()=>{使用(varsynthesizer=newSpeechSynthesizer()){varms=newMemoryStream();synthesizer.SetOutputToWaveStream(ms);synthesizer.Speak(text);ms.Position=0;returnnewFileStreamResult(ms,"音频/wav");}});}可能对其他人有帮助...以上就是《C#学习教程:超快文本转语音(WAV->MP3)inASP.NETMVC》的全部内容,如果对大家有帮助的话有用,需要了解有关C#学习教程的更多信息。希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: