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

时间:2013-09-27 19:21:10

标签: 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.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();

    }

感谢。

6 个答案:

答案 0 :(得分:44)

我想用NAudio.Lame发布我的例子:

的NuGet:

Install-Package NAudio.Lame

Code Snip:我的显然返回一个字节[] - 我有一个单独的保存到磁盘的方法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();
            }


        }

答案 1 :(得分:11)

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

实现这一目标的步骤:

  1. 将以下文件从MP3Compressor复制到您的项目中:

    • AudioWriters.cs
    • Lame.cs
    • Lame_enc.dll
    • Mp3Writer.cs
    • Mp3WriterConfig.cs
    • WaveNative.cs
    • WriterConfig.cs


  2. Lame_enc.dll的项目属性中,将Copy to Output属性设置为Copy if newerCopy always

  3. 修改Lame.cs并替换以下所有实例:

    [DllImport("Lame_enc.dll")]
    

    使用:

    [DllImport("Lame_enc.dll", CallingConvention = CallingConvention.Cdecl)]`
    
  4. 将以下代码添加到您的项目中:

    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();
            }
        }
    }
    
  5. System.Windows.Forms的引用添加到您的项目中(如果它已经不存在),或者编辑AudioWriter.csWriterConfig.cs以删除引用。这两个都有using System.Windows.Forms;您可以删除,WriterConfig.cs有一个ConfigControl声明,需要删除/注释掉。

  6. 完成所有这些后,您应该有一个功能性的内存中波形文件到MP3转换器,您可以使用它将您从SpeechSynthesizer获得的WAV文件转换为MP3。

答案 2 :(得分:9)

现在有点老了,但是因为你还没有接受我之前提供的答案......

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

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

答案 3 :(得分:1)

假设您正在尝试将输出转换为MP3,则需要能够处理音频转码的内容。有许多工具可用,但我个人的偏好是FFmpeg。它是一个命令行工具,因此您需要考虑到这一点,否则它非常容易使用。

网上有很多信息,但您可以先查看他们的文档here

答案 4 :(得分:1)

我在.net4.0中有类似的要求转换8bit 8Khz mono 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();
        }
    }

Prerequists:

  1. .net 4编译的yeti库(获取它下载这个较旧的(http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip)并将其转换为.net4.0然后构建解决方案以获取新版本的dll)
  2. 下载NAudio库(由于Lame支持16位wav样本,我必须先将其从8位转换为16位wav)
  3. 我使用的缓冲区大小为64kpbs(我的自定义要求)

答案 5 :(得分:0)

试试看:

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