C# 在NAudio的内存流中将格式从wav更改为mp3

C# 在NAudio的内存流中将格式从wav更改为mp3,c#,asp.net,audio,naudio,C#,Asp.net,Audio,Naudio,您好,我正在尝试将内存中的文本转换为语音(wav),将其转换为mp3,然后在用户页面上播放。那么需要我帮助吗 这是我的asmx代码: [WebMethod] public byte[] StartSpeak(string Word) { MemoryStream ms = new MemoryStream(); using (System.Speech.Synthesis.SpeechSynthesizer synhesizer = new System.Speech.Synth

您好,我正在尝试将内存中的文本转换为语音(wav),将其转换为mp3,然后在用户页面上播放。那么需要我帮助吗

这是我的asmx代码:

[WebMethod]
public byte[] StartSpeak(string Word)
{
    MemoryStream ms = new MemoryStream();
    using (System.Speech.Synthesis.SpeechSynthesizer synhesizer = new System.Speech.Synthesis.SpeechSynthesizer())
    {
        synhesizer.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.NotSet, System.Speech.Synthesis.VoiceAge.NotSet, 0, new System.Globalization.CultureInfo("en-US"));
        synhesizer.SetOutputToWaveStream(ms);
        synhesizer.Speak(Word);
    }
    return ms.ToArray();

    }

谢谢。

假设您正在尝试将输出转换为MP3,您需要能够处理音频转码的东西。有很多工具可用,但我个人的偏好是。它是一个命令行工具,所以您需要考虑到这一点,但除此之外,它非常易于使用


网上有很多信息,但你可以先看看他们的文档。

你需要一个MP3压缩程序库。我使用Lame通过雪人Lame包装。您可以找到代码和示例项目

使其工作的步骤:

  • 将以下文件从
    MP3Compressor
    复制到项目中:

    public static Byte[] WavToMP3(byte[] wavFile)
    {
         using (MemoryStream source = new MemoryStream(wavFile))
         using (NAudio.Wave.WaveFileReader rdr = new NAudio.Wave.WaveFileReader(source))
         {
             WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(rdr.WaveFormat.SampleRate, rdr.WaveFormat.BitsPerSample, rdr.WaveFormat.Channels);
    
             // convert to MP3 at 96kbit/sec...
             Yeti.Lame.BE_CONFIG conf = new Yeti.Lame.BE_CONFIG(fmt, 96);
    
             // Allocate a 1-second buffer
             int blen = rdr.WaveFormat.AverageBytesPerSecond;
             byte[] buffer = new byte[blen];
    
             // Do conversion
             using (MemoryStream output = new MemoryStream())
             { 
                 Yeti.MMedia.Mp3.Mp3Writer mp3 = new Yeti.MMedia.Mp3.Mp3Writer(output, fmt, conf);
    
                 int readCount;
                 while ((readCount = rdr.Read(buffer, 0, blen)) > 0)
                     mp3.Write(buffer, 0, readCount);
                 mp3.Close();
    
                 return output.ToArray();
             }
         }
     }
    
    • AudioWriters.cs
    • Lame.cs
    • Lame_enc.dll
    • Mp3Writer.cs
    • Mp3WriterConfig.cs
    • WaveNative.cs
    • WriterConfig.cs

  • Lame_enc.dll的项目属性中
    Copy to Output
    属性设置为
    Copy if newer
    Copy always

  • 编辑Lame.cs并替换以下内容的所有实例:

    [DllImport("Lame_enc.dll")]
    
    与:

  • 将以下代码添加到项目中:

    public static Byte[] WavToMP3(byte[] wavFile)
    {
         using (MemoryStream source = new MemoryStream(wavFile))
         using (NAudio.Wave.WaveFileReader rdr = new NAudio.Wave.WaveFileReader(source))
         {
             WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(rdr.WaveFormat.SampleRate, rdr.WaveFormat.BitsPerSample, rdr.WaveFormat.Channels);
    
             // convert to MP3 at 96kbit/sec...
             Yeti.Lame.BE_CONFIG conf = new Yeti.Lame.BE_CONFIG(fmt, 96);
    
             // Allocate a 1-second buffer
             int blen = rdr.WaveFormat.AverageBytesPerSecond;
             byte[] buffer = new byte[blen];
    
             // Do conversion
             using (MemoryStream output = new MemoryStream())
             { 
                 Yeti.MMedia.Mp3.Mp3Writer mp3 = new Yeti.MMedia.Mp3.Mp3Writer(output, fmt, conf);
    
                 int readCount;
                 while ((readCount = rdr.Read(buffer, 0, blen)) > 0)
                     mp3.Write(buffer, 0, readCount);
                 mp3.Close();
    
                 return output.ToArray();
             }
         }
     }
    
  • 将对
    System.Windows.Forms
    的引用添加到项目中(如果尚未添加),或者编辑
    AudioWriter.cs
    WriterConfig.cs
    以删除引用。它们都有一个
    使用System.Windows.Forms,并且
    WriterConfig.cs
    具有需要删除/注释掉的
    ConfigControl
    声明


  • 一旦所有这些都完成了,您应该有一个功能性的内存中的WAV文件到MP3转换器,您可以使用它将从
    语音合成器
    获取的WAV文件转换为MP3。

    这现在有点旧了,但因为您还没有接受我之前提供的答案

    我最近为NAudio构建了一个扩展,它封装了LAME库,以提供简化的MP3编码


    使用NuGet包管理器查找
    NAudio.Lame
    。使用它的基本示例可用。

    我在.net4.0中有一个类似的要求,即转换8bit 8Khz单声道wav,并使用以下代码

    public void WavToMp3(string wavPath, string fileId)
        {
            var tempMp3Path = TempPath + "tempFiles\\" + fileId + ".mp3";
            var mp3strm = new FileStream(tempMp3Path, FileMode.Create);
            try
            {
                using (var reader = new WaveFileReader(wavPath))
                {
                    var blen = 65536;
                    var buffer = new byte[blen];
                    int rc;
                    var bit16WaveFormat = new WaveFormat(16000, 16, 1);
                    using (var conversionStream = new WaveFormatConversionStream(bit16WaveFormat, reader))
                    {
                        var targetMp3Format = new WaveLib.WaveFormat(16000, 16, 1);
                        using (var mp3Wri = new Mp3Writer(mp3strm, new Mp3WriterConfig(targetMp3Format, new BE_CONFIG(targetMp3Format,64))))
                        {
                            while ((rc = conversionStream.Read(buffer, 0, blen)) > 0) mp3Wri.Write(buffer, 0, rc);
                            mp3strm.Flush();
                            conversionStream.Close();
                        }
                    }
                    reader.Close();
                }
                File.Move(tempMp3Path, TempPath + fileId + ".mp3");
            }
            finally
            {
                mp3strm.Close();
            }
        }
    
    先决条件:

  • .net4编译的yeti库(要获取它,请下载此旧库()并将其转换为.net4.0,然后构建解决方案以获取新版本的DLL)
  • 下载NAudio库(由于Lame仅支持16位wav示例,我必须首先将其从8位转换为16位wav)

  • 我使用了64kpbs的缓冲区大小(我的自定义要求)

    只是想用NAudio.Lame发布我的示例:

    努吉:

    Install-Package NAudio.Lame
    
    代码剪贴:我的显然返回一个字节[]-我有一个单独的磁盘保存方法b/c,我认为它使单元测试更容易

    public static byte[] ConvertWavToMp3(byte[] wavFile)
            {
    
                using(var retMs = new MemoryStream())
                using (var ms = new MemoryStream(wavFile))
                using(var rdr = new WaveFileReader(ms))
                using (var wtr = new LameMP3FileWriter(retMs, rdr.WaveFormat, 128))
                {
                    rdr.CopyTo(wtr);
                    return retMs.ToArray();
                }
    
    
            }
    
    试一试:

    using (WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new     
    Mp3FileReader(inputStream))) 
    using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputStream, waveStream.WaveFormat)) 
    { 
        byte[] bytes = new byte[waveStream.Length]; 
        waveStream.Position = 0;
        waveStream.Read(bytes, 0, waveStream.Length); 
        waveFileWriter.WriteData(bytes, 0, bytes.Length); 
        waveFileWriter.Flush(); 
    } 
    

    你走了多远?你有错误吗?另外,我假设这只是从语音到文本的转换,而不是转换?谢谢你的回复。我是一个初学者,所以如果有一个例子可以帮助我,我很难下一步该怎么做。我无法将引用添加到我的手机项目中。我该怎么办?请涵盖一个教程来做这件事。抱歉@max,但LAME编码器是一个本机Windows DLL,据我所知,它不适用于Windows Phone。在这种情况下,一个蹩脚的包装器也不可能在Windows Phone上工作。你必须为你的MP3编码找到一种不同的机制。我如何为这段代码构建一个web服务来让它工作?请理解,我并没有太多地参与服务器端编码或此类机制@Corey@max如果您正在运行ASP.NET或MVC4网站或类似网站(即Win32/Win64上的IIS),则可以在服务器端使用NAudio.Lame。但是需要添加一些东西-请参阅。这是一个很好的建议。我将尝试为它构建一个web服务。非常感谢:)哇,我不知道为什么这次投票不多。它工作得很好。最简单的解决方案。谢谢Wjdavis5!它对我不起作用,无论我做什么,返回的字节数组都是空的。@AdrianC。添加
    wtr.Flush()
    rdr.CopyTo(wtr)。干杯